diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index f3a03805a44..b039e654fd0 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -225,7 +225,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { pub(crate) fn complain_about_ambiguous_inherent_assoc_type( &self, name: Ident, - candidates: Vec<(DefId, DefId)>, + candidates: Vec, span: Span, ) -> ErrorGuaranteed { let mut err = struct_span_err!( @@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn note_ambiguous_inherent_assoc_type( &self, err: &mut Diagnostic, - candidates: Vec<(DefId, DefId)>, + candidates: Vec, span: Span, ) { let tcx = self.tcx(); @@ -251,11 +251,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Dynamic limit to avoid hiding just one candidate, which is silly. let limit = if candidates.len() == 5 { 5 } else { 4 }; - for (index, &(assoc_item, _)) in candidates.iter().take(limit).enumerate() { - let impl_ = tcx.impl_of_method(assoc_item).unwrap(); + for (index, &item) in candidates.iter().take(limit).enumerate() { + let impl_ = tcx.impl_of_method(item).unwrap(); - let note_span = if assoc_item.is_local() { - Some(tcx.def_span(assoc_item)) + let note_span = if item.is_local() { + Some(tcx.def_span(item)) } else if impl_.is_local() { Some(tcx.def_span(impl_)) } else { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index c22ebc1c659..f43b92254eb 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2267,7 +2267,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return None; } - Some((assoc_item, def_scope)) + // FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot. + Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs))) }) }) .collect(); @@ -2275,23 +2276,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if applicable_candidates.len() > 1 { return Err(self.complain_about_ambiguous_inherent_assoc_type( name, - applicable_candidates, + applicable_candidates.into_iter().map(|(candidate, ..)| candidate).collect(), span, )); } - if let Some((assoc_item, def_scope)) = applicable_candidates.pop() { + if let Some((assoc_item, def_scope, impl_substs)) = applicable_candidates.pop() { self.check_assoc_ty(assoc_item, name, def_scope, block, span); - let ty::Adt(_, adt_substs) = self_ty.kind() else { - bug!("unreachable: `lookup_inherent_assoc_ty` is only called on ADTs"); - }; + // FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate, + // we still need to register region obligations for regionck to prove/disprove. - let item_substs = self.create_substs_for_associated_item( - span, assoc_item, segment, - // FIXME(fmease, #107468, #105305): Don't use `adt_substs` here but `impl_substs`. - adt_substs, - ); + let item_substs = + self.create_substs_for_associated_item(span, assoc_item, segment, impl_substs); // FIXME(fmease, #106722): Check if the bounds on the parameters of the // associated type hold, if any. diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs index f10386bd9f9..f846bfa4168 100644 --- a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs @@ -31,7 +31,7 @@ fn main() { let _: Select::Projection = (); let _: Choose::Result = (); - let _: Choose<&str>::Result = vec!["..."]; + let _: Choose::Result = vec![true]; } // Test if we use the correct `ParamEnv` when proving obligations. diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr index 1c77688b45a..c9a48872af4 100644 --- a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr +++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr @@ -10,7 +10,7 @@ error[E0308]: mismatched types --> $DIR/dispatch-on-self-type-2.rs:16:47 | LL | let _: Parameterized::Result = (); - | -------------------------------- ^^ expected `bool`, found `()` + | -------------------------------- ^^ expected `u32`, found `()` | | | expected due to this diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.rs b/tests/ui/associated-inherent-types/substitute-params-bad.rs new file mode 100644 index 00000000000..00eb1a14da4 --- /dev/null +++ b/tests/ui/associated-inherent-types/substitute-params-bad.rs @@ -0,0 +1,23 @@ +// Regression test for issue #105305 and for +// https://github.com/rust-lang/rust/issues/107468#issuecomment-1409096700 + +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +struct S(T); + +impl S { //~ ERROR lifetime parameters must be declared prior to type and const parameters + type P = T; +} + +struct Subj(T); + +impl Subj<(T, S)> { + type Un = (T, S); +} + +fn main() { + type A = S<()>::P; + + let _: Subj<(i32, i32)>::Un = 0i32; //~ ERROR mismatched types +} diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.stderr b/tests/ui/associated-inherent-types/substitute-params-bad.stderr new file mode 100644 index 00000000000..7a7808ba67b --- /dev/null +++ b/tests/ui/associated-inherent-types/substitute-params-bad.stderr @@ -0,0 +1,20 @@ +error: lifetime parameters must be declared prior to type and const parameters + --> $DIR/substitute-params-bad.rs:9:9 + | +LL | impl S { + | ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>` + +error[E0308]: mismatched types + --> $DIR/substitute-params-bad.rs:22:35 + | +LL | let _: Subj<(i32, i32)>::Un = 0i32; + | -------------------- ^^^^ expected `(i32, i32)`, found `i32` + | | + | expected due to this + | + = note: expected tuple `(i32, i32)` + found type `i32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-inherent-types/struct-generics.rs b/tests/ui/associated-inherent-types/substitute-params.rs similarity index 55% rename from tests/ui/associated-inherent-types/struct-generics.rs rename to tests/ui/associated-inherent-types/substitute-params.rs index 8952b379173..e94d6833159 100644 --- a/tests/ui/associated-inherent-types/struct-generics.rs +++ b/tests/ui/associated-inherent-types/substitute-params.rs @@ -9,7 +9,15 @@ impl S { type P = T; } +impl S<(T,)> { + type Un = T; +} + fn main() { + // Regression test for issue #104240. type A = S<()>::P; let _: A = (); + + // Regression test for issue #107468. + let _: S<(i32,)>::Un = 0i32; }