Skip to content

Commit b9ec2eb

Browse files
committed
Expand free alias types during variance computation
1 parent 2c35a49 commit b9ec2eb

22 files changed

Lines changed: 324 additions & 172 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

tests/ui/lazy-type-alias/inherent-impls-overflow.current.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ LL | type Poly0<T> = Poly1<(T,)>;
2323
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
2424

2525
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
26-
--> $DIR/inherent-impls-overflow.rs:21:1
26+
--> $DIR/inherent-impls-overflow.rs:20:1
2727
|
2828
LL | type Poly1<T> = Poly0<(T,)>;
2929
| ^^^^^^^^^^^^^
3030
|
3131
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
3232

3333
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
34-
--> $DIR/inherent-impls-overflow.rs:26:1
34+
--> $DIR/inherent-impls-overflow.rs:24:1
3535
|
3636
LL | impl Poly0<()> {}
3737
| ^^^^^^^^^^^^^^^^^

tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,53 +24,31 @@ LL | type Poly0<T> = Poly1<(T,)>;
2424
|
2525
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
2626

27-
error: type parameter `T` is only used recursively
28-
--> $DIR/inherent-impls-overflow.rs:17:24
29-
|
30-
LL | type Poly0<T> = Poly1<(T,)>;
31-
| - ^
32-
| |
33-
| type parameter must be used non-recursively in the definition
34-
|
35-
= help: consider removing `T` or referring to it in the body of the type alias
36-
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
37-
3827
error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
39-
--> $DIR/inherent-impls-overflow.rs:21:1
28+
--> $DIR/inherent-impls-overflow.rs:20:1
4029
|
4130
LL | type Poly1<T> = Poly0<(T,)>;
4231
| ^^^^^^^^^^^^^
4332
|
4433
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
4534

46-
error: type parameter `T` is only used recursively
47-
--> $DIR/inherent-impls-overflow.rs:21:24
48-
|
49-
LL | type Poly1<T> = Poly0<(T,)>;
50-
| - ^
51-
| |
52-
| type parameter must be used non-recursively in the definition
53-
|
54-
= help: consider removing `T` or referring to it in the body of the type alias
55-
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
56-
5735
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
58-
--> $DIR/inherent-impls-overflow.rs:26:1
36+
--> $DIR/inherent-impls-overflow.rs:24:1
5937
|
6038
LL | impl Poly0<()> {}
6139
| ^^^^^^^^^^^^^^^^^
6240
|
6341
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
6442

6543
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
66-
--> $DIR/inherent-impls-overflow.rs:26:6
44+
--> $DIR/inherent-impls-overflow.rs:24:6
6745
|
6846
LL | impl Poly0<()> {}
6947
| ^^^^^^^^^
7048
|
7149
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
7250

73-
error: aborting due to 9 previous errors
51+
error: aborting due to 7 previous errors
7452

7553
Some errors have detailed explanations: E0271, E0275.
7654
For more information about an error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)