Skip to content

Commit ee49a74

Browse files
authored
Unrolled build for #141030
Rollup merge of #141030 - fmease:lta-no-variance, r=BoxyUwU Expand free alias types during variance computation Instead of computing variances for them since they can never be rigid anyway. Fixes #140230.
2 parents 485ec3f + 05aee18 commit ee49a74

28 files changed

Lines changed: 463 additions & 194 deletions

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
974974
tcx.ensure_ok().generics_of(def_id);
975975
tcx.ensure_ok().type_of(def_id);
976976
tcx.ensure_ok().predicates_of(def_id);
977-
check_type_alias_type_params_are_used(tcx, def_id);
978977
let ty = tcx.type_of(def_id).instantiate_identity();
979978
let span = tcx.def_span(def_id);
980979
if tcx.type_alias_is_lazy(def_id) {
@@ -988,8 +987,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
988987
check_where_clauses(wfcx, def_id);
989988
Ok(())
990989
}));
991-
check_variances_for_type_defn(tcx, def_id);
992990
} else {
991+
check_type_alias_type_params_are_used(tcx, def_id);
993992
res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
994993
// HACK: We sometimes incidentally check that const arguments have the correct
995994
// type as a side effect of the anon const desugaring. To make this "consistent"
@@ -2064,12 +2063,6 @@ fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
20642063
}
20652064

20662065
fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
2067-
if tcx.type_alias_is_lazy(def_id) {
2068-
// Since we compute the variances for lazy type aliases and already reject bivariant
2069-
// parameters as unused, we can and should skip this check for lazy type aliases.
2070-
return;
2071-
}
2072-
20732066
let generics = tcx.generics_of(def_id);
20742067
if generics.own_counts().types == 0 {
20752068
return;

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,12 +2049,6 @@ pub(super) fn check_variances_for_type_defn<'tcx>(tcx: TyCtxt<'tcx>, def_id: Loc
20492049
DefKind::Enum | DefKind::Struct | DefKind::Union => {
20502050
// Ok
20512051
}
2052-
DefKind::TyAlias => {
2053-
assert!(
2054-
tcx.type_alias_is_lazy(def_id),
2055-
"should not be computing variance of non-free type alias"
2056-
);
2057-
}
20582052
kind => span_bug!(tcx.def_span(def_id), "cannot compute the variances of {kind:?}"),
20592053
}
20602054

@@ -2206,7 +2200,6 @@ fn report_bivariance<'tcx>(
22062200
errors::UnusedGenericParameterHelp::AdtNoPhantomData { param_name }
22072201
}
22082202
}
2209-
ItemKind::TyAlias(..) => errors::UnusedGenericParameterHelp::TyAlias { param_name },
22102203
item_kind => bug!("report_bivariance: unexpected item kind: {item_kind:?}"),
22112204
};
22122205

@@ -2288,9 +2281,6 @@ impl<'tcx> IsProbablyCyclical<'tcx> {
22882281
.visit_with(self)
22892282
})
22902283
}
2291-
DefKind::TyAlias if self.tcx.type_alias_is_lazy(def_id) => {
2292-
self.tcx.type_of(def_id).instantiate_identity().skip_norm_wip().visit_with(self)
2293-
}
22942284
_ => ControlFlow::Continue(()),
22952285
}
22962286
}
@@ -2300,17 +2290,12 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsProbablyCyclical<'tcx> {
23002290
type Result = ControlFlow<(), ()>;
23012291

23022292
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<(), ()> {
2303-
let def_id = match ty.kind() {
2304-
ty::Adt(adt_def, _) => Some(adt_def.did()),
2305-
&ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, .. }) => Some(def_id),
2306-
_ => None,
2307-
};
2308-
if let Some(def_id) = def_id {
2309-
if def_id == self.item_def_id {
2293+
if let Some(adt_def) = ty.ty_adt_def() {
2294+
if adt_def.did() == self.item_def_id {
23102295
return ControlFlow::Break(());
23112296
}
2312-
if self.seen.insert(def_id) {
2313-
self.visit_def(def_id)?;
2297+
if self.seen.insert(adt_def.did()) {
2298+
self.visit_def(adt_def.did())?;
23142299
}
23152300
}
23162301
ty.super_visit_with(self)

compiler/rustc_hir_analysis/src/variance/constraints.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ pub(crate) fn add_constraints_from_crate<'a, 'tcx>(
7979
}
8080
}
8181
DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
82-
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
83-
constraint_cx.build_constraints_for_item(def_id)
84-
}
8582
_ => {}
8683
}
8784
}
@@ -107,15 +104,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
107104
let current_item = &CurrentItem { inferred_start };
108105
let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
109106

110-
// The type as returned by `type_of` is the underlying type and generally not a free alias.
111-
// Therefore we need to check the `DefKind` first.
112-
if let DefKind::TyAlias = tcx.def_kind(def_id)
113-
&& tcx.type_alias_is_lazy(def_id)
114-
{
115-
self.add_constraints_from_ty(current_item, ty, self.covariant);
116-
return;
117-
}
118-
119107
match ty.kind() {
120108
ty::Adt(def, _) => {
121109
// Not entirely obvious: constraints on structs/enums do not
@@ -216,14 +204,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
216204
/// Adds constraints appropriate for an instance of `ty` appearing
217205
/// in a context with the generics defined in `generics` and
218206
/// ambient variance `variance`
207+
#[instrument(level = "debug", skip(self, current))]
219208
fn add_constraints_from_ty(
220209
&mut self,
221210
current: &CurrentItem,
222211
ty: Ty<'tcx>,
223212
variance: VarianceTermPtr<'a>,
224213
) {
225-
debug!("add_constraints_from_ty(ty={:?}, variance={:?})", ty, variance);
226-
227214
match *ty.kind() {
228215
ty::Bool
229216
| ty::Char
@@ -281,8 +268,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
281268
self.add_constraints_from_invariant_args(current, args, variance);
282269
}
283270

284-
ty::Alias(ty::AliasTy { kind: ty::Free { def_id }, args, .. }) => {
285-
self.add_constraints_from_args(current, def_id, args, variance);
271+
ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => {
272+
let ty = self.tcx().expand_free_alias_tys(ty);
273+
self.add_constraints_from_ty(current, ty, variance);
286274
}
287275

288276
ty::Dynamic(data, r) => {

compiler/rustc_hir_analysis/src/variance/dump.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,16 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
3838
}
3939

4040
match tcx.def_kind(id) {
41-
DefKind::AssocFn | DefKind::Fn | DefKind::Enum | DefKind::Struct | DefKind::Union => {}
42-
DefKind::TyAlias if tcx.type_alias_is_lazy(id) => {}
41+
DefKind::AssocFn | DefKind::Fn | DefKind::Enum | DefKind::Struct | DefKind::Union => {
42+
tcx.dcx().span_err(tcx.def_span(id), format_variances(tcx, id.def_id));
43+
}
4344
kind => {
4445
let message = format!(
4546
"attr parsing didn't report an error for `#[{}]` on {kind:?}",
4647
rustc_span::sym::rustc_dump_variances,
4748
);
4849
tcx.dcx().span_delayed_bug(tcx.def_span(id), message);
49-
continue;
5050
}
5151
}
52-
53-
tcx.dcx().span_err(tcx.def_span(id), format_variances(tcx, id.def_id));
5452
}
5553
}

compiler/rustc_hir_analysis/src/variance/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@ pub(super) fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Va
5252
let crate_map = tcx.crate_variances(());
5353
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
5454
}
55-
DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
56-
// These are inferred.
57-
let crate_map = tcx.crate_variances(());
58-
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
59-
}
6055
DefKind::AssocTy => match tcx.opt_rpitit_info(item_def_id.to_def_id()) {
6156
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
6257
return variance_of_opaque(

compiler/rustc_hir_analysis/src/variance/terms.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ pub(crate) fn determine_parameters_to_be_inferred<'a, 'tcx>(
9999
}
100100
}
101101
DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
102-
DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
103-
terms_cx.add_inferreds_for_item(def_id)
104-
}
105102
_ => {}
106103
}
107104
}

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,7 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
11531153
| DefKind::Static { .. }
11541154
| DefKind::Const { .. }
11551155
| DefKind::ForeignMod
1156+
| DefKind::TyAlias
11561157
| DefKind::Impl { .. }
11571158
| DefKind::Trait
11581159
| DefKind::TraitAlias
@@ -1166,7 +1167,6 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
11661167
| DefKind::Closure
11671168
| DefKind::ExternCrate
11681169
| DefKind::SyntheticCoroutineBody => false,
1169-
DefKind::TyAlias => tcx.type_alias_is_lazy(def_id),
11701170
}
11711171
}
11721172

compiler/rustc_middle/src/ty/util.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ impl<'tcx> TyCtxt<'tcx> {
905905
return Ty::new_error(self, guar);
906906
}
907907

908-
ty = self.type_of(def_id).instantiate(self, args).skip_norm_wip();
908+
ty = self.type_of(def_id).instantiate(self, args).skip_normalization();
909909
depth += 1;
910910
}
911911

@@ -967,7 +967,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
967967
Some(expanded_ty) => *expanded_ty,
968968
None => {
969969
let generic_ty = self.tcx.type_of(def_id);
970-
let concrete_ty = generic_ty.instantiate(self.tcx, args).skip_norm_wip();
970+
let concrete_ty = generic_ty.instantiate(self.tcx, args).skip_normalization();
971971
let expanded_ty = self.fold_ty(concrete_ty);
972972
self.expanded_cache.insert((def_id, args), expanded_ty);
973973
expanded_ty
@@ -1047,7 +1047,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for FreeAliasTypeExpander<'tcx> {
10471047

10481048
self.depth += 1;
10491049
let ty = ensure_sufficient_stack(|| {
1050-
self.tcx.type_of(def_id).instantiate(self.tcx, args).skip_norm_wip().fold_with(self)
1050+
self.tcx
1051+
.type_of(def_id)
1052+
.instantiate(self.tcx, args)
1053+
.skip_normalization()
1054+
.fold_with(self)
10511055
});
10521056
self.depth -= 1;
10531057
ty
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Test that we check the body at the definition site for well-formedness.
2+
// Compare with `tests/ui/type-alias/lack-of-wfcheck.rs`.
3+
4+
#![feature(lazy_type_alias)]
5+
6+
// unsatisified trait bounds
7+
type _A<T> = <T as std::ops::Mul>::Output; //~ ERROR cannot multiply `T` by `T`
8+
type _B = Vec<str>; //~ ERROR the size for values of type `str` cannot be known at compilation time
9+
10+
// unsatisfied outlives-bounds
11+
type _C<'a> = &'static &'a (); //~ ERROR reference has a longer lifetime than the data it references
12+
13+
// diverging const exprs
14+
type _D = [(); panic!()]; //~ ERROR evaluation panicked
15+
16+
// dyn incompatibility
17+
type _E = dyn Sized; //~ ERROR the trait `Sized` is not dyn compatible
18+
19+
fn main() {}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error[E0277]: cannot multiply `T` by `T`
2+
--> $DIR/def-site-body-wf.rs:7:14
3+
|
4+
LL | type _A<T> = <T as std::ops::Mul>::Output;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `T * T`
6+
|
7+
help: consider restricting type parameter `T` with trait `Mul`
8+
|
9+
LL | type _A<T: std::ops::Mul> = <T as std::ops::Mul>::Output;
10+
| +++++++++++++++
11+
12+
error[E0277]: the size for values of type `str` cannot be known at compilation time
13+
--> $DIR/def-site-body-wf.rs:8:11
14+
|
15+
LL | type _B = Vec<str>;
16+
| ^^^^^^^^ doesn't have a size known at compile-time
17+
|
18+
= help: the trait `Sized` is not implemented for `str`
19+
note: required by an implicit `Sized` bound in `Vec`
20+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
21+
22+
error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
23+
--> $DIR/def-site-body-wf.rs:11:1
24+
|
25+
LL | type _C<'a> = &'static &'a ();
26+
| ^^^^^^^^^^^
27+
|
28+
= note: the pointer is valid for the static lifetime
29+
note: but the referenced data is only valid for the lifetime `'a` as defined here
30+
--> $DIR/def-site-body-wf.rs:11:9
31+
|
32+
LL | type _C<'a> = &'static &'a ();
33+
| ^^
34+
35+
error[E0080]: evaluation panicked: explicit panic
36+
--> $DIR/def-site-body-wf.rs:14:16
37+
|
38+
LL | type _D = [(); panic!()];
39+
| ^^^^^^^^ evaluation of `_D::{constant#0}` failed here
40+
41+
error[E0038]: the trait `Sized` is not dyn compatible
42+
--> $DIR/def-site-body-wf.rs:17:11
43+
|
44+
LL | type _E = dyn Sized;
45+
| ^^^^^^^^^ `Sized` is not dyn compatible
46+
|
47+
= note: the trait is not dyn compatible because it requires `Self: Sized`
48+
= note: for a trait to be dyn compatible it needs to allow building a vtable
49+
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
50+
51+
error: aborting due to 5 previous errors
52+
53+
Some errors have detailed explanations: E0038, E0080, E0277, E0491.
54+
For more information about an error, try `rustc --explain E0038`.

0 commit comments

Comments
 (0)