Skip to content

Commit 2f4fbf8

Browse files
committed
Do not look in ParamEnv for opaque type bounds that could be satisfied
1 parent dc028f3 commit 2f4fbf8

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,42 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
4040
predicate: self.infcx.resolve_vars_if_possible(obligation.predicate),
4141
};
4242

43-
if obligation.predicate.skip_binder().self_ty().is_ty_var() {
44-
debug!(ty = ?obligation.predicate.skip_binder().self_ty(), "ambiguous inference var or opaque type");
45-
// Self is a type variable (e.g., `_: AsRef<str>`).
46-
//
47-
// This is somewhat problematic, as the current scheme can't really
48-
// handle it turning to be a projection. This does end up as truly
49-
// ambiguous in most cases anyway.
50-
//
51-
// Take the fast path out - this also improves
52-
// performance by preventing assemble_candidates_from_impls from
53-
// matching every impl for this trait.
54-
return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true });
55-
}
56-
5743
let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
44+
let def_id = obligation.predicate.def_id();
45+
let tcx = self.tcx();
46+
47+
match obligation.predicate.skip_binder().self_ty().kind() {
48+
// Opaque types in their defining scope are just like inference vars...
49+
ty::Alias(ty::Opaque, alias) if self.infcx.can_define_opaque_ty(alias.def_id) => {
50+
if tcx.is_lang_item(def_id, LangItem::Unsize) {
51+
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
52+
}
53+
self.assemble_candidates_from_impls(obligation, &mut candidates);
54+
// .. unless we are looking for candidates just on the opaque signature, ...
55+
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
56+
// .. or for auto traits, which look at the hidden type.
57+
// Auto traits must be collected after projected tys, because opaque types
58+
// do not emit auto trait candidates if a projection for the same auto trait
59+
// already exists (e.g. due to the bounds on the opaque).
60+
self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
61+
return Ok(candidates);
62+
}
63+
ty::Infer(ty::TyVar(vid)) => {
64+
debug!(?vid, "ambiguous inference var");
65+
// Self is a type variable (e.g., `_: AsRef<str>`).
66+
//
67+
// This is somewhat problematic, as the current scheme can't really
68+
// handle it turning to be a projection. This does end up as truly
69+
// ambiguous in most cases anyway.
70+
//
71+
// Take the fast path out - this also improves
72+
// performance by preventing assemble_candidates_from_impls from
73+
// matching every impl for this trait.
74+
candidates.ambiguous = true;
75+
return Ok(candidates);
76+
}
77+
_ => {}
78+
}
5879

5980
// Negative trait predicates have different rules than positive trait predicates.
6081
if obligation.polarity() == ty::PredicatePolarity::Negative {
@@ -66,8 +87,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6687

6788
// Other bounds. Consider both in-scope bounds from fn decl
6889
// and applicable impls. There is a certain set of precedence rules here.
69-
let def_id = obligation.predicate.def_id();
70-
let tcx = self.tcx();
7190

7291
if tcx.is_lang_item(def_id, LangItem::Copy) {
7392
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());

0 commit comments

Comments
 (0)