Skip to content

Commit

Permalink
Auto merge of #116045 - notriddle:notriddle/issue-83556, r=cjgillot
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Sep 23, 2023
2 parents 136d74f + 58ef3a0 commit 0237aa3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
22 changes: 19 additions & 3 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1755,20 +1755,36 @@ fn check_variances_for_type_defn<'tcx>(
.collect::<FxHashSet<_>>()
});

let ty_generics = tcx.generics_of(item.owner_id);

for (index, _) in variances.iter().enumerate() {
let parameter = Parameter(index as u32);

if constrained_parameters.contains(&parameter) {
continue;
}

let param = &hir_generics.params[index];
let ty_param = &ty_generics.params[index];
let hir_param = &hir_generics.params[index];

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 param.name {
match hir_param.name {
hir::ParamName::Error => {}
_ => {
let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
report_bivariance(tcx, param, has_explicit_bounds);
report_bivariance(tcx, hir_param, has_explicit_bounds);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/generics/issue-83556.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct Foo<T, 'a>(&'a ());
//~^ ERROR lifetime parameters must be declared prior to

fn main() {}
8 changes: 8 additions & 0 deletions tests/ui/generics/issue-83556.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 0237aa3

Please sign in to comment.