Skip to content

Commit b745423

Browse files
committed
Check variances for validity in variances_of query
1 parent dead438 commit b745423

File tree

6 files changed

+51
-49
lines changed

6 files changed

+51
-49
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -308,22 +308,21 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
308308
hir::ItemKind::Const(ty, ..) => {
309309
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
310310
}
311-
hir::ItemKind::Struct(_, hir_generics) => check_type_defn(tcx, item, false)
312-
.and(check_variances_for_type_defn(tcx, item.owner_id.def_id, hir_generics)),
313-
hir::ItemKind::Union(_, hir_generics) => check_type_defn(tcx, item, true)
314-
.and(check_variances_for_type_defn(tcx, item.owner_id.def_id, hir_generics)),
315-
hir::ItemKind::Enum(_, hir_generics) => check_type_defn(tcx, item, true)
316-
.and(check_variances_for_type_defn(tcx, item.owner_id.def_id, hir_generics)),
311+
hir::ItemKind::Struct(..) => check_type_defn(tcx, item, false),
312+
hir::ItemKind::Union(..) => check_type_defn(tcx, item, true),
313+
hir::ItemKind::Enum(..) => check_type_defn(tcx, item, true),
314+
317315
hir::ItemKind::Trait(..) => check_trait(tcx, item),
318316
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
319317
// `ForeignItem`s are handled separately.
320318
hir::ItemKind::ForeignMod { .. } => Ok(()),
321-
hir::ItemKind::TyAlias(hir_ty, hir_generics) => {
319+
hir::ItemKind::TyAlias(hir_ty, ..) => {
322320
if tcx.type_alias_is_lazy(item.owner_id) {
323321
// Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
324322
// E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
325-
check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow)
326-
.and(check_variances_for_type_defn(tcx, item.owner_id.def_id, hir_generics))
323+
let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
324+
let _ = tcx.variances_of(def_id);
325+
res
327326
} else {
328327
Ok(())
329328
}
@@ -1062,6 +1061,7 @@ fn check_type_defn<'tcx>(
10621061
all_sized: bool,
10631062
) -> Result<(), ErrorGuaranteed> {
10641063
let _ = tcx.representability(item.owner_id.def_id);
1064+
let _ = tcx.variances_of(item.owner_id.def_id);
10651065
let adt_def = tcx.adt_def(item.owner_id);
10661066

10671067
enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
@@ -1799,10 +1799,10 @@ fn receiver_is_implemented<'tcx>(
17991799
}
18001800
}
18011801

1802-
fn check_variances_for_type_defn<'tcx>(
1802+
pub fn check_variances_for_type_defn<'tcx>(
18031803
tcx: TyCtxt<'tcx>,
18041804
item: LocalDefId,
1805-
hir_generics: &hir::Generics<'tcx>,
1805+
variances: &[ty::Variance],
18061806
) -> Result<(), ErrorGuaranteed> {
18071807
let identity_args = ty::GenericArgs::identity_for_item(tcx, item);
18081808

@@ -1819,12 +1819,11 @@ fn check_variances_for_type_defn<'tcx>(
18191819
);
18201820
tcx.type_of(item).skip_binder().error_reported()?;
18211821
}
1822-
kind => span_bug!(tcx.def_span(item), "cannot compute the variances of {kind:?}"),
1822+
_ => return Ok(()),
18231823
}
18241824

18251825
let ty_predicates = tcx.predicates_of(item);
18261826
assert_eq!(ty_predicates.parent, None);
1827-
let variances = tcx.variances_of(item);
18281827

18291828
let mut constrained_parameters: FxHashSet<_> = variances
18301829
.iter()
@@ -1835,6 +1834,8 @@ fn check_variances_for_type_defn<'tcx>(
18351834

18361835
identify_constrained_generic_params(tcx, ty_predicates, None, &mut constrained_parameters);
18371836

1837+
let hir_generics = tcx.hir_node_by_def_id(item).generics().unwrap();
1838+
18381839
// Lazily calculated because it is only needed in case of an error.
18391840
let explicitly_bounded_params = LazyCell::new(|| {
18401841
let icx = crate::collect::ItemCtxt::new(tcx, item);

compiler/rustc_hir_analysis/src/variance/mod.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
4545
return &[];
4646
}
4747

48-
match tcx.def_kind(item_def_id) {
48+
let variances = match tcx.def_kind(item_def_id) {
4949
DefKind::Fn
5050
| DefKind::AssocFn
5151
| DefKind::Enum
@@ -55,21 +55,25 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
5555
| DefKind::Ctor(..) => {
5656
// These are inferred.
5757
let crate_map = tcx.crate_variances(());
58-
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
58+
crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
5959
}
6060
DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
6161
// These are inferred.
6262
let crate_map = tcx.crate_variances(());
63-
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
63+
crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
6464
}
65-
DefKind::OpaqueTy => {
66-
return variance_of_opaque(tcx, item_def_id);
65+
DefKind::OpaqueTy => variance_of_opaque(tcx, item_def_id),
66+
_ => {
67+
// Variance not relevant.
68+
span_bug!(
69+
tcx.def_span(item_def_id),
70+
"asked to compute variance for wrong kind of item"
71+
);
6772
}
68-
_ => {}
69-
}
73+
};
7074

71-
// Variance not relevant.
72-
span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item");
75+
let _ = crate::check::wfcheck::check_variances_for_type_defn(tcx, item_def_id, variances);
76+
variances
7377
}
7478

7579
#[instrument(level = "trace", skip(tcx), ret)]

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -730,16 +730,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
730730

731731
/// Resolves an associated value path into a base type and associated constant, or method
732732
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
733+
#[instrument(level = "trace", skip(self), ret)]
733734
pub fn resolve_ty_and_res_fully_qualified_call(
734735
&self,
735736
qpath: &'tcx QPath<'tcx>,
736737
hir_id: HirId,
737738
span: Span,
738739
) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
739-
debug!(
740-
"resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
741-
qpath, hir_id, span
742-
);
743740
let (ty, qself, item_segment) = match *qpath {
744741
QPath::Resolved(ref opt_qself, path) => {
745742
return (

tests/ui/issues/issue-34373.stderr

+9-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
1919

20+
error[E0392]: type parameter `T` is never used
21+
--> $DIR/issue-34373.rs:7:16
22+
|
23+
LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused type parameter
25+
|
26+
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
27+
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
28+
2029
error[E0038]: the trait `Trait` cannot be made into an object
2130
--> $DIR/issue-34373.rs:7:24
2231
|
@@ -39,15 +48,6 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
3948
LL | fn foo(_: T) where Self: Sized {}
4049
| +++++++++++++++++
4150

42-
error[E0392]: type parameter `T` is never used
43-
--> $DIR/issue-34373.rs:7:16
44-
|
45-
LL | pub struct Foo<T = Box<Trait<DefaultFoo>>>;
46-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unused type parameter
47-
|
48-
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
49-
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
50-
5151
error: aborting due to 3 previous errors
5252

5353
Some errors have detailed explanations: E0038, E0391, E0392.

tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ LL | beta: [(); foo::<&'a ()>()],
77
= note: lifetime parameters may not be used in const expressions
88
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
99

10-
error: generic `Self` types are currently not permitted in anonymous constants
11-
--> $DIR/issue-64173-unused-lifetimes.rs:4:28
12-
|
13-
LL | array: [(); size_of::<&Self>()],
14-
| ^^^^
15-
1610
error[E0392]: lifetime parameter `'s` is never used
1711
--> $DIR/issue-64173-unused-lifetimes.rs:3:12
1812
|
@@ -21,6 +15,12 @@ LL | struct Foo<'s> {
2115
|
2216
= help: consider removing `'s`, referring to it in a field, or using a marker such as `PhantomData`
2317

18+
error: generic `Self` types are currently not permitted in anonymous constants
19+
--> $DIR/issue-64173-unused-lifetimes.rs:4:28
20+
|
21+
LL | array: [(); size_of::<&Self>()],
22+
| ^^^^
23+
2424
error[E0392]: lifetime parameter `'a` is never used
2525
--> $DIR/issue-64173-unused-lifetimes.rs:15:12
2626
|

tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ error[E0226]: only a single explicit lifetime bound is permitted
44
LL | z: Box<dyn Is<'a>+'b+'c>,
55
| ^^
66

7+
error[E0392]: lifetime parameter `'c` is never used
8+
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:18
9+
|
10+
LL | struct Foo<'a,'b,'c> {
11+
| ^^ unused lifetime parameter
12+
|
13+
= help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
14+
715
error[E0478]: lifetime bound not satisfied
816
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:21:8
917
|
@@ -21,14 +29,6 @@ note: but lifetime parameter must outlive the lifetime `'a` as defined here
2129
LL | struct Foo<'a,'b,'c> {
2230
| ^^
2331

24-
error[E0392]: lifetime parameter `'c` is never used
25-
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:18
26-
|
27-
LL | struct Foo<'a,'b,'c> {
28-
| ^^ unused lifetime parameter
29-
|
30-
= help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
31-
3232
error: aborting due to 3 previous errors
3333

3434
Some errors have detailed explanations: E0226, E0392, E0478.

0 commit comments

Comments
 (0)