Skip to content

Commit 6065867

Browse files
committed
Use InferCtxt::probe to properly detect ambiguous candidates
1 parent 3dc38fb commit 6065867

File tree

3 files changed

+62
-21
lines changed

3 files changed

+62
-21
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,35 +2235,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22352235
let mut applicable_candidates: Vec<_> = candidates
22362236
.iter()
22372237
.filter_map(|&(impl_, (assoc_item, def_scope))| {
2238-
let ocx = ObligationCtxt::new(&infcx);
2238+
infcx.probe(|_| {
2239+
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
22392240

2240-
let impl_ty = tcx.type_of(impl_);
2241-
let impl_substs = self.fresh_item_substs(impl_, &infcx);
2242-
let impl_ty = impl_ty.subst(tcx, impl_substs);
2243-
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
2241+
let impl_ty = tcx.type_of(impl_);
2242+
let impl_substs = self.fresh_item_substs(impl_, &infcx);
2243+
let impl_ty = impl_ty.subst(tcx, impl_substs);
2244+
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
22442245

2245-
// Check that the Self-types can be related.
2246-
// FIXME(fmease): Should we use `eq` here?
2247-
ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?;
2246+
// Check that the Self-types can be related.
2247+
// FIXME(fmease): Should we use `eq` here?
2248+
ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).ok()?;
22482249

2249-
// Check whether the impl imposes obligations we have to worry about.
2250-
let impl_bounds = tcx.predicates_of(impl_);
2251-
let impl_bounds = impl_bounds.instantiate(tcx, impl_substs);
2250+
// Check whether the impl imposes obligations we have to worry about.
2251+
let impl_bounds = tcx.predicates_of(impl_);
2252+
let impl_bounds = impl_bounds.instantiate(tcx, impl_substs);
22522253

2253-
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
2254+
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
22542255

2255-
let impl_obligations =
2256-
traits::predicates_for_generics(|_, _| cause.clone(), param_env, impl_bounds);
2256+
let impl_obligations = traits::predicates_for_generics(
2257+
|_, _| cause.clone(),
2258+
param_env,
2259+
impl_bounds,
2260+
);
22572261

2258-
ocx.register_obligations(impl_obligations);
2262+
ocx.register_obligations(impl_obligations);
22592263

2260-
let errors = ocx.select_where_possible();
2261-
if !errors.is_empty() {
2262-
fulfillment_errors = errors;
2263-
return None;
2264-
}
2264+
let errors = ocx.select_where_possible();
2265+
if !errors.is_empty() {
2266+
fulfillment_errors = errors;
2267+
return None;
2268+
}
22652269

2266-
Some((assoc_item, def_scope))
2270+
Some((assoc_item, def_scope))
2271+
})
22672272
})
22682273
.collect();
22692274

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(inherent_associated_types)]
2+
#![allow(incomplete_features)]
3+
4+
struct Wrapper<T>(T);
5+
6+
impl Wrapper<i32> {
7+
type Foo = i32;
8+
}
9+
10+
impl Wrapper<()> {
11+
type Foo = ();
12+
}
13+
14+
fn main() {
15+
let _: Wrapper<_>::Foo = (); //~ ERROR multiple applicable items in scope
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0034]: multiple applicable items in scope
2+
--> $DIR/ambiguity.rs:15:24
3+
|
4+
LL | let _: Wrapper<_>::Foo = ();
5+
| ^^^ multiple `Foo` found
6+
|
7+
note: candidate #1 is defined in an impl for the type `Wrapper<i32>`
8+
--> $DIR/ambiguity.rs:7:5
9+
|
10+
LL | type Foo = i32;
11+
| ^^^^^^^^
12+
note: candidate #2 is defined in an impl for the type `Wrapper<()>`
13+
--> $DIR/ambiguity.rs:11:5
14+
|
15+
LL | type Foo = ();
16+
| ^^^^^^^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0034`.

0 commit comments

Comments
 (0)