Skip to content

Commit 77ea90e

Browse files
committed
Fix substitution bug
1 parent 6065867 commit 77ea90e

File tree

7 files changed

+67
-19
lines changed

7 files changed

+67
-19
lines changed

compiler/rustc_hir_analysis/src/astconv/errors.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
225225
pub(crate) fn complain_about_ambiguous_inherent_assoc_type(
226226
&self,
227227
name: Ident,
228-
candidates: Vec<(DefId, DefId)>,
228+
candidates: Vec<DefId>,
229229
span: Span,
230230
) -> ErrorGuaranteed {
231231
let mut err = struct_span_err!(
@@ -243,19 +243,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
243243
fn note_ambiguous_inherent_assoc_type(
244244
&self,
245245
err: &mut Diagnostic,
246-
candidates: Vec<(DefId, DefId)>,
246+
candidates: Vec<DefId>,
247247
span: Span,
248248
) {
249249
let tcx = self.tcx();
250250

251251
// Dynamic limit to avoid hiding just one candidate, which is silly.
252252
let limit = if candidates.len() == 5 { 5 } else { 4 };
253253

254-
for (index, &(assoc_item, _)) in candidates.iter().take(limit).enumerate() {
255-
let impl_ = tcx.impl_of_method(assoc_item).unwrap();
254+
for (index, &item) in candidates.iter().take(limit).enumerate() {
255+
let impl_ = tcx.impl_of_method(item).unwrap();
256256

257-
let note_span = if assoc_item.is_local() {
258-
Some(tcx.def_span(assoc_item))
257+
let note_span = if item.is_local() {
258+
Some(tcx.def_span(item))
259259
} else if impl_.is_local() {
260260
Some(tcx.def_span(impl_))
261261
} else {

compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,31 +2267,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22672267
return None;
22682268
}
22692269

2270-
Some((assoc_item, def_scope))
2270+
// FIXME(fmease): Unsolved vars can escape this InferCtxt snapshot.
2271+
Some((assoc_item, def_scope, infcx.resolve_vars_if_possible(impl_substs)))
22712272
})
22722273
})
22732274
.collect();
22742275

22752276
if applicable_candidates.len() > 1 {
22762277
return Err(self.complain_about_ambiguous_inherent_assoc_type(
22772278
name,
2278-
applicable_candidates,
2279+
applicable_candidates.into_iter().map(|(candidate, ..)| candidate).collect(),
22792280
span,
22802281
));
22812282
}
22822283

2283-
if let Some((assoc_item, def_scope)) = applicable_candidates.pop() {
2284+
if let Some((assoc_item, def_scope, impl_substs)) = applicable_candidates.pop() {
22842285
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
22852286

2286-
let ty::Adt(_, adt_substs) = self_ty.kind() else {
2287-
bug!("unreachable: `lookup_inherent_assoc_ty` is only called on ADTs");
2288-
};
2287+
// FIXME(inherent_associated_types): To fully *confirm* the *probed* candidate,
2288+
// we still need to register region obligations for regionck to prove/disprove.
22892289

2290-
let item_substs = self.create_substs_for_associated_item(
2291-
span, assoc_item, segment,
2292-
// FIXME(fmease, #107468, #105305): Don't use `adt_substs` here but `impl_substs`.
2293-
adt_substs,
2294-
);
2290+
let item_substs =
2291+
self.create_substs_for_associated_item(span, assoc_item, segment, impl_substs);
22952292

22962293
// FIXME(fmease, #106722): Check if the bounds on the parameters of the
22972294
// associated type hold, if any.

tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn main() {
3131
let _: Select<u8>::Projection = ();
3232

3333
let _: Choose<NonCopy>::Result = ();
34-
let _: Choose<&str>::Result = vec!["..."];
34+
let _: Choose<bool>::Result = vec![true];
3535
}
3636

3737
// Test if we use the correct `ParamEnv` when proving obligations.

tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ error[E0308]: mismatched types
1010
--> $DIR/dispatch-on-self-type-2.rs:16:47
1111
|
1212
LL | let _: Parameterized<bool, u32>::Result = ();
13-
| -------------------------------- ^^ expected `bool`, found `()`
13+
| -------------------------------- ^^ expected `u32`, found `()`
1414
| |
1515
| expected due to this
1616

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Regression test for issue #105305 and for
2+
// https://github.com/rust-lang/rust/issues/107468#issuecomment-1409096700
3+
4+
#![feature(inherent_associated_types)]
5+
#![allow(incomplete_features)]
6+
7+
struct S<T>(T);
8+
9+
impl<T, 'a> S<T> { //~ ERROR lifetime parameters must be declared prior to type and const parameters
10+
type P = T;
11+
}
12+
13+
struct Subj<T>(T);
14+
15+
impl<T, S> Subj<(T, S)> {
16+
type Un = (T, S);
17+
}
18+
19+
fn main() {
20+
type A = S<()>::P;
21+
22+
let _: Subj<(i32, i32)>::Un = 0i32; //~ ERROR mismatched types
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: lifetime parameters must be declared prior to type and const parameters
2+
--> $DIR/substitute-params-bad.rs:9:9
3+
|
4+
LL | impl<T, 'a> S<T> {
5+
| ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
6+
7+
error[E0308]: mismatched types
8+
--> $DIR/substitute-params-bad.rs:22:35
9+
|
10+
LL | let _: Subj<(i32, i32)>::Un = 0i32;
11+
| -------------------- ^^^^ expected `(i32, i32)`, found `i32`
12+
| |
13+
| expected due to this
14+
|
15+
= note: expected tuple `(i32, i32)`
16+
found type `i32`
17+
18+
error: aborting due to 2 previous errors
19+
20+
For more information about this error, try `rustc --explain E0308`.

tests/ui/associated-inherent-types/struct-generics.rs renamed to tests/ui/associated-inherent-types/substitute-params.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ impl<T> S<T> {
99
type P = T;
1010
}
1111

12+
impl<T> S<(T,)> {
13+
type Un = T;
14+
}
15+
1216
fn main() {
17+
// Regression test for issue #104240.
1318
type A = S<()>::P;
1419
let _: A = ();
20+
21+
// Regression test for issue #107468.
22+
let _: S<(i32,)>::Un = 0i32;
1523
}

0 commit comments

Comments
 (0)