Skip to content

Commit 73000c7

Browse files
committed
eagerly prove WF when resolving fully qualified paths
1 parent 021fb9c commit 73000c7

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -798,13 +798,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
798798
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
799799
}
800800
};
801+
802+
self.register_wf_obligation(
803+
ty.raw.into(),
804+
qself.span,
805+
ObligationCauseCode::WellFormed(None),
806+
);
807+
self.select_obligations_where_possible(|_| {});
808+
801809
if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
802810
{
803-
self.register_wf_obligation(
804-
ty.raw.into(),
805-
qself.span,
806-
ObligationCauseCode::WellFormed(None),
807-
);
808811
// Return directly on cache hit. This is useful to avoid doubly reporting
809812
// errors with default match binding modes. See #44614.
810813
let def = cached_result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id));
@@ -849,14 +852,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
849852
result
850853
});
851854

852-
if result.is_ok() {
853-
self.register_wf_obligation(
854-
ty.raw.into(),
855-
qself.span,
856-
ObligationCauseCode::WellFormed(None),
857-
);
858-
}
859-
860855
// Write back the new resolution.
861856
self.write_resolution(hir_id, result);
862857
(
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
// A regression test for trait-system-refactor-initiative#161
5+
6+
trait Constrain<T> {
7+
type Assoc;
8+
}
9+
impl<T> Constrain<T> for () {
10+
type Assoc = ();
11+
}
12+
struct Foo<T, U = <() as Constrain<T>>::Assoc>(T, U);
13+
14+
impl<T: Copy> Foo<T> {
15+
fn foo() {}
16+
}
17+
struct B;
18+
impl Foo<B> {
19+
fn foo() {}
20+
}
21+
22+
type Alias<T> = Foo<T>;
23+
fn via_guidance<T: Copy>()
24+
where
25+
(): Constrain<T>,
26+
{
27+
// Method selection on `Foo<?t, <() as Constrain<?t>>::Assoc>` is ambiguous.
28+
// only by unnecessarily constraining `?t` to `T` when proving `(): Constrain<?t>`
29+
// are we able to select the first impl.
30+
//
31+
// This happens in the old solver when normalizing `Alias<?t>`. The new solver doesn't try
32+
// to eagerly normalize `<() as Constrain<?t>>::Assoc` so we instead always prove that the
33+
// self type is well-formed before method lookup.
34+
Alias::foo();
35+
}
36+
37+
fn main() {
38+
via_guidance::<()>();
39+
}

0 commit comments

Comments
 (0)