Auto merge of #116045 - notriddle:notriddle/issue-83556, r=cjgillot
diagnostics: avoid mismatch between variance index and hir generic
This happens because variances are constructed from ty generics, and ty generics are always constructed with lifetimes first.
b3aa8e7168/compiler/rustc_hir_analysis/src/collect/generics_of.rs (L248-L269)
Fixes #83556
This commit is contained in:
commit
0237aa3d77
3 changed files with 31 additions and 3 deletions
|
@ -1755,6 +1755,8 @@ fn check_variances_for_type_defn<'tcx>(
|
||||||
.collect::<FxHashSet<_>>()
|
.collect::<FxHashSet<_>>()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let ty_generics = tcx.generics_of(item.owner_id);
|
||||||
|
|
||||||
for (index, _) in variances.iter().enumerate() {
|
for (index, _) in variances.iter().enumerate() {
|
||||||
let parameter = Parameter(index as u32);
|
let parameter = Parameter(index as u32);
|
||||||
|
|
||||||
|
@ -1762,13 +1764,27 @@ fn check_variances_for_type_defn<'tcx>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let param = &hir_generics.params[index];
|
let ty_param = &ty_generics.params[index];
|
||||||
|
let hir_param = &hir_generics.params[index];
|
||||||
|
|
||||||
match param.name {
|
if ty_param.def_id != hir_param.def_id.into() {
|
||||||
|
// valid programs always have lifetimes before types in the generic parameter list
|
||||||
|
// ty_generics are normalized to be in this required order, and variances are built
|
||||||
|
// from ty generics, not from hir generics. but we need hir generics to get
|
||||||
|
// a span out
|
||||||
|
//
|
||||||
|
// if they aren't in the same order, then the user has written invalid code, and already
|
||||||
|
// got an error about it (or I'm wrong about this)
|
||||||
|
tcx.sess
|
||||||
|
.delay_span_bug(hir_param.span, "hir generics and ty generics in different order");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
match hir_param.name {
|
||||||
hir::ParamName::Error => {}
|
hir::ParamName::Error => {}
|
||||||
_ => {
|
_ => {
|
||||||
let has_explicit_bounds = explicitly_bounded_params.contains(¶meter);
|
let has_explicit_bounds = explicitly_bounded_params.contains(¶meter);
|
||||||
report_bivariance(tcx, param, has_explicit_bounds);
|
report_bivariance(tcx, hir_param, has_explicit_bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
tests/ui/generics/issue-83556.rs
Normal file
4
tests/ui/generics/issue-83556.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
struct Foo<T, 'a>(&'a ());
|
||||||
|
//~^ ERROR lifetime parameters must be declared prior to
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/generics/issue-83556.stderr
Normal file
8
tests/ui/generics/issue-83556.stderr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
error: lifetime parameters must be declared prior to type and const parameters
|
||||||
|
--> $DIR/issue-83556.rs:1:15
|
||||||
|
|
|
||||||
|
LL | struct Foo<T, 'a>(&'a ());
|
||||||
|
| ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue