Fix substitution bug
This commit is contained in:
parent
6065867a7e
commit
77ea90ec71
7 changed files with 67 additions and 19 deletions
|
@ -225,7 +225,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
|
pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
|
||||||
&self,
|
&self,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
candidates: Vec<(DefId, DefId)>,
|
candidates: Vec<DefId>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
|
@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
fn note_ambiguous_inherent_assoc_type(
|
fn note_ambiguous_inherent_assoc_type(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
candidates: Vec<(DefId, DefId)>,
|
candidates: Vec<DefId>,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
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.
|
// Dynamic limit to avoid hiding just one candidate, which is silly.
|
||||||
let limit = if candidates.len() == 5 { 5 } else { 4 };
|
let limit = if candidates.len() == 5 { 5 } else { 4 };
|
||||||
|
|
||||||
for (index, &(assoc_item, _)) in candidates.iter().take(limit).enumerate() {
|
for (index, &item) in candidates.iter().take(limit).enumerate() {
|
||||||
let impl_ = tcx.impl_of_method(assoc_item).unwrap();
|
let impl_ = tcx.impl_of_method(item).unwrap();
|
||||||
|
|
||||||
let note_span = if assoc_item.is_local() {
|
let note_span = if item.is_local() {
|
||||||
Some(tcx.def_span(assoc_item))
|
Some(tcx.def_span(item))
|
||||||
} else if impl_.is_local() {
|
} else if impl_.is_local() {
|
||||||
Some(tcx.def_span(impl_))
|
Some(tcx.def_span(impl_))
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2267,7 +2267,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
return None;
|
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();
|
.collect();
|
||||||
|
@ -2275,23 +2276,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
if applicable_candidates.len() > 1 {
|
if applicable_candidates.len() > 1 {
|
||||||
return Err(self.complain_about_ambiguous_inherent_assoc_type(
|
return Err(self.complain_about_ambiguous_inherent_assoc_type(
|
||||||
name,
|
name,
|
||||||
applicable_candidates,
|
applicable_candidates.into_iter().map(|(candidate, ..)| candidate).collect(),
|
||||||
span,
|
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);
|
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
|
||||||
|
|
||||||
let ty::Adt(_, adt_substs) = self_ty.kind() else {
|
// FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate,
|
||||||
bug!("unreachable: `lookup_inherent_assoc_ty` is only called on ADTs");
|
// we still need to register region obligations for regionck to prove/disprove.
|
||||||
};
|
|
||||||
|
|
||||||
let item_substs = self.create_substs_for_associated_item(
|
let item_substs =
|
||||||
span, assoc_item, segment,
|
self.create_substs_for_associated_item(span, assoc_item, segment, impl_substs);
|
||||||
// FIXME(fmease, #107468, #105305): Don't use `adt_substs` here but `impl_substs`.
|
|
||||||
adt_substs,
|
|
||||||
);
|
|
||||||
|
|
||||||
// FIXME(fmease, #106722): Check if the bounds on the parameters of the
|
// FIXME(fmease, #106722): Check if the bounds on the parameters of the
|
||||||
// associated type hold, if any.
|
// associated type hold, if any.
|
||||||
|
|
|
@ -31,7 +31,7 @@ fn main() {
|
||||||
let _: Select<u8>::Projection = ();
|
let _: Select<u8>::Projection = ();
|
||||||
|
|
||||||
let _: Choose<NonCopy>::Result = ();
|
let _: Choose<NonCopy>::Result = ();
|
||||||
let _: Choose<&str>::Result = vec!["..."];
|
let _: Choose<bool>::Result = vec![true];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if we use the correct `ParamEnv` when proving obligations.
|
// Test if we use the correct `ParamEnv` when proving obligations.
|
||||||
|
|
|
@ -10,7 +10,7 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/dispatch-on-self-type-2.rs:16:47
|
--> $DIR/dispatch-on-self-type-2.rs:16:47
|
||||||
|
|
|
|
||||||
LL | let _: Parameterized<bool, u32>::Result = ();
|
LL | let _: Parameterized<bool, u32>::Result = ();
|
||||||
| -------------------------------- ^^ expected `bool`, found `()`
|
| -------------------------------- ^^ expected `u32`, found `()`
|
||||||
| |
|
| |
|
||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
||||||
|
|
23
tests/ui/associated-inherent-types/substitute-params-bad.rs
Normal file
23
tests/ui/associated-inherent-types/substitute-params-bad.rs
Normal file
|
@ -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>(T);
|
||||||
|
|
||||||
|
impl<T, 'a> S<T> { //~ ERROR lifetime parameters must be declared prior to type and const parameters
|
||||||
|
type P = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Subj<T>(T);
|
||||||
|
|
||||||
|
impl<T, S> Subj<(T, S)> {
|
||||||
|
type Un = (T, S);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
type A = S<()>::P;
|
||||||
|
|
||||||
|
let _: Subj<(i32, i32)>::Un = 0i32; //~ ERROR mismatched types
|
||||||
|
}
|
|
@ -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<T, 'a> S<T> {
|
||||||
|
| ----^^- 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`.
|
|
@ -9,7 +9,15 @@ impl<T> S<T> {
|
||||||
type P = T;
|
type P = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> S<(T,)> {
|
||||||
|
type Un = T;
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// Regression test for issue #104240.
|
||||||
type A = S<()>::P;
|
type A = S<()>::P;
|
||||||
let _: A = ();
|
let _: A = ();
|
||||||
|
|
||||||
|
// Regression test for issue #107468.
|
||||||
|
let _: S<(i32,)>::Un = 0i32;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue