Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up and harden various methods around trait substs #104533

Merged
merged 21 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0c47dee
Reduce the amount of passed-around arguments that will get merged int…
oli-obk Nov 17, 2022
250dcf4
Check that type_implements_trait actually is passed the right amount …
oli-obk Nov 17, 2022
48ff6a9
Use ty::List instead of InternalSubsts
oli-obk Nov 17, 2022
d9a02b0
Split out the actual predicate solving code into a separate function
oli-obk Nov 17, 2022
6f77c97
Assert that various types have the right amount of generic args and f…
oli-obk Nov 17, 2022
19a1192
Add a helper for replacing the self type in trait refs
oli-obk Nov 17, 2022
bd40c10
Remove an unnecessary query + subst round
oli-obk Nov 17, 2022
ec8d01f
Allow iterators instead of requiring slices that will get turned into…
oli-obk Nov 17, 2022
9e4c3f4
Use iterators instead of slices at more sites
oli-obk Nov 17, 2022
25c4760
Some cleanup around trait_method lookup
oli-obk Nov 17, 2022
ad57f88
Add helper to create the trait ref for a lang item
oli-obk Nov 17, 2022
a9f3c22
For lcnr
oli-obk Nov 17, 2022
4d9451b
Fix an ICE that I just made worse
oli-obk Nov 17, 2022
48ea298
Remove a redundant assert
oli-obk Nov 17, 2022
472444b
Remove some unnecessary slicing
oli-obk Nov 17, 2022
a4da3f8
Fix clippy's missing substs
oli-obk Nov 18, 2022
7658e0f
Stop passing the self-type as a separate argument.
oli-obk Nov 21, 2022
24cdb72
Use `as_closure` helper method
oli-obk Nov 21, 2022
5316378
Simplify test
oli-obk Nov 21, 2022
a6c5212
Simplify one more `TraitRef::new` site
oli-obk Nov 21, 2022
c2ecd8f
merge self type and substs in `trait_method`
oli-obk Nov 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// but the type has region variables, so erase those.
tcx.infer_ctxt()
.build()
.type_implements_trait(
default_trait,
tcx.erase_regions(ty),
ty::List::empty(),
param_env,
)
.type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env)
.must_apply_modulo_regions()
};

Expand Down Expand Up @@ -1707,7 +1702,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
err.span_label(borrow_span, note);

let tcx = self.infcx.tcx;
let ty_params = ty::List::empty();

let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
let return_ty = tcx.erase_regions(return_ty);
Expand All @@ -1716,7 +1710,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)
&& self
.infcx
.type_implements_trait(iter_trait, return_ty, ty_params, self.param_env)
.type_implements_trait(iter_trait, [return_ty], self.param_env)
.must_apply_modulo_regions()
{
err.span_suggestion_hidden(
Expand Down
36 changes: 10 additions & 26 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,10 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {

if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let tcx = self.tcx();
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
substs: tcx.mk_substs_trait(place_ty.ty, &[]),
};
let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]);

// To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`,
Expand Down Expand Up @@ -1273,10 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

self.check_rvalue(body, rv, location);
if !self.unsized_feature_enabled() {
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(place_ty, &[]),
};
let trait_ref =
tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]);
self.prove_trait_ref(
trait_ref,
location.to_locations(),
Expand Down Expand Up @@ -1840,6 +1835,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
#[instrument(skip(self, body), level = "debug")]
fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
let tcx = self.tcx();
let span = body.source_info(location).span;

match rvalue {
Rvalue::Aggregate(ak, ops) => {
Expand All @@ -1863,12 +1859,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
Operand::Move(place) => {
// Make sure that repeated elements implement `Copy`.
let span = body.source_info(location).span;
let ty = place.ty(body, tcx).ty;
let trait_ref = ty::TraitRef::new(
tcx.require_lang_item(LangItem::Copy, Some(span)),
tcx.mk_substs_trait(ty, &[]),
);
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]);

self.prove_trait_ref(
trait_ref,
Expand All @@ -1881,10 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}

&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(ty, &[]),
};
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]);

self.prove_trait_ref(
trait_ref,
Expand All @@ -1896,10 +1885,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Rvalue::ShallowInitBox(operand, ty) => {
self.check_operand(operand, location);

let trait_ref = ty::TraitRef {
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
substs: tcx.mk_substs_trait(*ty, &[]),
};
let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]);

self.prove_trait_ref(
trait_ref,
Expand Down Expand Up @@ -1996,11 +1982,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

CastKind::Pointer(PointerCast::Unsize) => {
let &ty = ty;
let trait_ref = ty::TraitRef {
def_id: tcx
.require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)),
substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
};
let trait_ref = tcx
.at(span)
.mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]);

self.prove_trait_ref(
trait_ref,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,12 @@ impl Qualif for NeedsNonConstDrop {
return false;
}

let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None);

let obligation = Obligation::new(
cx.tcx,
ObligationCause::dummy(),
ObligationCause::dummy_with_span(cx.body.span),
cx.param_env,
ty::Binder::dummy(ty::TraitPredicate {
trait_ref: ty::TraitRef {
def_id: destruct,
substs: cx.tcx.mk_substs_trait(ty, &[]),
},
trait_ref: cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, [ty]),
constness: ty::BoundConstness::ConstIfConst,
polarity: ty::ImplPolarity::Positive,
}),
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,10 @@ impl<'tcx> Bounds<'tcx> {
{
// If it could be sized, and is, add the `Sized` predicate.
let sized_predicate = self.implicitly_sized.and_then(|span| {
tcx.lang_items().sized_trait().map(move |sized| {
let trait_ref = ty::Binder::dummy(ty::TraitRef {
def_id: sized,
substs: tcx.mk_substs_trait(param_ty, &[]),
});
(trait_ref.without_const().to_predicate(tcx), span)
})
// FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write.
let sized = tcx.lang_items().sized_trait()?;
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, [param_ty]));
Some((trait_ref.without_const().to_predicate(tcx), span))
});

let region_preds = self.region_bounds.iter().map(move |&(region_bound, span)| {
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1722,7 +1722,7 @@ fn receiver_is_valid<'tcx>(
// The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
autoderef.next();

let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, None);
let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span));

// Keep dereferencing `receiver_ty` until we get to `self_ty`.
loop {
Expand Down Expand Up @@ -1782,10 +1782,7 @@ fn receiver_is_implemented<'tcx>(
receiver_ty: Ty<'tcx>,
) -> bool {
let tcx = wfcx.tcx();
let trait_ref = ty::Binder::dummy(ty::TraitRef {
def_id: receiver_trait_def_id,
substs: tcx.mk_substs_trait(receiver_ty, &[]),
});
let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(receiver_trait_def_id, [receiver_ty]));

let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref.without_const());

Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/coherence/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
cause.clone(),
dispatch_from_dyn_trait,
0,
field.ty(tcx, substs_a),
&[field.ty(tcx, substs_b).into()],
[field.ty(tcx, substs_a), field.ty(tcx, substs_b)],
)
}),
);
Expand Down Expand Up @@ -558,7 +557,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
// Register an obligation for `A: Trait<B>`.
let cause = traits::ObligationCause::misc(span, impl_hir_id);
let predicate =
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]);
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]);
let errors = traits::fully_solve_obligation(&infcx, predicate);
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,17 +539,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.subst_iter_copied(self.tcx, substs)
{
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
ty::PredicateKind::Trait(mut trait_pred) => {
ty::PredicateKind::Trait(trait_pred) => {
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
trait_pred.trait_ref.substs =
self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]);
ty::PredicateKind::Trait(trait_pred)
ty::PredicateKind::Trait(trait_pred.with_self_type(self.tcx, ty))
}
ty::PredicateKind::Projection(mut proj_pred) => {
assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
proj_pred.projection_ty.substs = self
.tcx
.mk_substs_trait(ty, &proj_pred.projection_ty.substs[1..]);
proj_pred.projection_ty.substs = self.tcx.mk_substs_trait(
ty,
proj_pred.projection_ty.substs.iter().skip(1),
);
ty::PredicateKind::Projection(proj_pred)
}
_ => continue,
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,10 +498,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
let ty = fcx.tcx.erase_regions(ty);
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
let expr_ty = fcx.tcx.erase_regions(expr_ty);
let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
if fcx
.infcx
.type_implements_trait(from_trait, ty, ty_params, fcx.param_env)
.type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env)
.must_apply_modulo_regions()
{
label = false;
Expand Down
13 changes: 5 additions & 8 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
cause,
coerce_unsized_did,
0,
coerce_source,
&[coerce_target.into()]
[coerce_source, coerce_target]
)];

let mut has_unsized_tuple_coercion = false;
Expand Down Expand Up @@ -805,10 +804,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
self.tcx,
self.cause.clone(),
self.param_env,
ty::Binder::dummy(ty::TraitRef::new(
self.tcx.require_lang_item(hir::LangItem::PointerSized, Some(self.cause.span)),
self.tcx.mk_substs_trait(a, &[]),
))
ty::Binder::dummy(
self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]),
)
.to_poly_trait_predicate(),
));
}
Expand Down Expand Up @@ -1086,8 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.infcx
.type_implements_trait(
self.tcx.lang_items().deref_mut_trait()?,
expr_ty,
ty::List::empty(),
[expr_ty],
self.param_env,
)
.may_apply()
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,8 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.infcx
.type_implements_trait(
self.tcx.lang_items().sized_trait().unwrap(),
lhs_deref_ty,
ty::List::empty(),
[lhs_deref_ty],
self.param_env,
)
.may_apply();
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,10 +1093,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx,
self.misc(expr.span),
self.param_env,
ty::Binder::dummy(ty::TraitRef {
def_id: into_def_id,
substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]),
})
ty::Binder::dummy(self.tcx.mk_trait_ref(
into_def_id,
[expr_ty, expected_ty]
))
.to_poly_trait_predicate(),
))
{
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_hir_typeck/src/method/prelude2021.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use hir::ItemKind;
use rustc_ast::Mutability;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty::{Adt, Array, Ref, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::{Empty, Underscore};
Expand Down Expand Up @@ -227,14 +227,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If we know it does not, we don't need to warn.
if method_name.name == sym::from_iter {
if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) {
let any_type = self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
});
if !self
.infcx
.type_implements_trait(
trait_def_id,
self_ty,
InternalSubsts::empty(),
self.param_env,
)
.type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env)
.may_apply()
{
return;
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.autoderef(span, ty).any(|(ty, _)| {
info!("check deref {:?} impl FnOnce", ty);
self.probe(|_| {
let fn_once_substs = tcx.mk_substs_trait(
ty,
&[self
.next_ty_var(TypeVariableOrigin {
let trait_ref = tcx.mk_trait_ref(
fn_once,
[
ty,
self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
})
.into()],
}),
],
);
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
let poly_trait_ref = ty::Binder::dummy(trait_ref);
let obligation = Obligation::misc(
tcx,
Expand Down
22 changes: 3 additions & 19 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -970,12 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
check_trait
.map(|check_trait| {
self.infcx
.type_implements_trait(
check_trait,
ty,
self.tcx.mk_substs_trait(ty, &[]),
self.param_env,
)
.type_implements_trait(check_trait, [ty], self.param_env)
.must_apply_modulo_regions()
})
.unwrap_or(false),
Expand All @@ -999,12 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
check_trait
.map(|check_trait| {
self.infcx
.type_implements_trait(
check_trait,
ty,
self.tcx.mk_substs_trait(ty, &[]),
self.param_env,
)
.type_implements_trait(check_trait, [ty], self.param_env)
.must_apply_modulo_regions()
})
.unwrap_or(false),
Expand Down Expand Up @@ -1347,14 +1337,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let is_drop_defined_for_ty = |ty: Ty<'tcx>| {
let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span));
let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]);
self.infcx
.type_implements_trait(
drop_trait,
ty,
ty_params,
self.tcx.param_env(closure_def_id),
)
.type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id))
.must_apply_modulo_regions()
};

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
def_id: DefId,
cause: ObligationCause<'tcx>,
) {
let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
let trait_ref = infcx.tcx.mk_trait_ref(def_id, [ty]);
self.register_predicate_obligation(
infcx,
Obligation {
Expand Down
Loading