Skip to content

Commit 0237aa3

Browse files
committed
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. https://github.com/rust-lang/rust/blob/b3aa8e7168a3d940122db3561289ffbf3f587262/compiler/rustc_hir_analysis/src/collect/generics_of.rs#L248-L269 Fixes #83556
2 parents 136d74f + 58ef3a0 commit 0237aa3

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

Diff for: compiler/rustc_hir_analysis/src/check/wfcheck.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -1755,20 +1755,36 @@ fn check_variances_for_type_defn<'tcx>(
17551755
.collect::<FxHashSet<_>>()
17561756
});
17571757

1758+
let ty_generics = tcx.generics_of(item.owner_id);
1759+
17581760
for (index, _) in variances.iter().enumerate() {
17591761
let parameter = Parameter(index as u32);
17601762

17611763
if constrained_parameters.contains(&parameter) {
17621764
continue;
17631765
}
17641766

1765-
let param = &hir_generics.params[index];
1767+
let ty_param = &ty_generics.params[index];
1768+
let hir_param = &hir_generics.params[index];
1769+
1770+
if ty_param.def_id != hir_param.def_id.into() {
1771+
// valid programs always have lifetimes before types in the generic parameter list
1772+
// ty_generics are normalized to be in this required order, and variances are built
1773+
// from ty generics, not from hir generics. but we need hir generics to get
1774+
// a span out
1775+
//
1776+
// if they aren't in the same order, then the user has written invalid code, and already
1777+
// got an error about it (or I'm wrong about this)
1778+
tcx.sess
1779+
.delay_span_bug(hir_param.span, "hir generics and ty generics in different order");
1780+
continue;
1781+
}
17661782

1767-
match param.name {
1783+
match hir_param.name {
17681784
hir::ParamName::Error => {}
17691785
_ => {
17701786
let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
1771-
report_bivariance(tcx, param, has_explicit_bounds);
1787+
report_bivariance(tcx, hir_param, has_explicit_bounds);
17721788
}
17731789
}
17741790
}

Diff for: tests/ui/generics/issue-83556.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
struct Foo<T, 'a>(&'a ());
2+
//~^ ERROR lifetime parameters must be declared prior to
3+
4+
fn main() {}

Diff for: tests/ui/generics/issue-83556.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: lifetime parameters must be declared prior to type and const parameters
2+
--> $DIR/issue-83556.rs:1:15
3+
|
4+
LL | struct Foo<T, 'a>(&'a ());
5+
| ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)