Skip to content

Commit c383c9d

Browse files
Fix missing type alias cycle detection
1 parent 9e7f02b commit c383c9d

File tree

9 files changed

+74
-42
lines changed

9 files changed

+74
-42
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+47-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use rustc_middle::mir::ConstraintCategory;
1414
use rustc_middle::ty::query::Providers;
1515
use rustc_middle::ty::trait_def::TraitSpecializationKind;
1616
use rustc_middle::ty::{
17-
self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
18-
TypeSuperVisitable, TypeVisitable, TypeVisitor,
17+
self, AdtKind, DefIdTree, GenericParamDefKind, SubstsRef, ToPredicate, Ty, TyCtxt,
18+
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
1919
};
2020
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
2121
use rustc_session::parse::feature_err;
@@ -239,6 +239,51 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
239239
hir::ItemKind::TraitAlias(..) => {
240240
check_trait(tcx, item);
241241
}
242+
hir::ItemKind::TyAlias { .. } => {
243+
struct TyAliasPeeler<'t> {
244+
tcx: TyCtxt<'t>,
245+
visited: FxHashSet<(DefId, SubstsRef<'t>)>,
246+
}
247+
248+
impl<'t> ty::TypeFolder<'t> for TyAliasPeeler<'t> {
249+
fn tcx<'a>(&'a self) -> TyCtxt<'t> {
250+
self.tcx
251+
}
252+
253+
fn fold_ty(&mut self, t: Ty<'t>) -> Ty<'t> {
254+
use crate::ty::fold::{TypeFoldable, TypeSuperFoldable};
255+
use crate::ty::visit::TypeVisitable;
256+
257+
match *t.kind() {
258+
ty::TyAlias(def_id, substs) => {
259+
if !self.visited.insert((def_id, substs)) {
260+
let def_span = self.tcx.def_span(def_id);
261+
self.tcx
262+
.sess
263+
.struct_span_err(
264+
def_span,
265+
"cycle detected when expanding type alias",
266+
)
267+
.emit();
268+
return t;
269+
}
270+
let binder_ty = self.tcx.bound_type_of(def_id);
271+
let ty = binder_ty.subst(self.tcx, substs);
272+
ty.fold_with(self)
273+
}
274+
_ if !t.has_ty_alias() => t,
275+
_ => t.super_fold_with(self),
276+
}
277+
}
278+
}
279+
280+
let ty = tcx.bound_type_of(item.def_id.to_def_id()).0;
281+
if let ty::TyAlias(def_id, substs) = *ty.kind() {
282+
let binder_ty = tcx.bound_type_of(def_id);
283+
let ty = binder_ty.subst(tcx, substs);
284+
ty.fold_with(&mut TyAliasPeeler { tcx, visited: FxHashSet::default() });
285+
}
286+
}
242287
// `ForeignItem`s are handled separately.
243288
hir::ItemKind::ForeignMod { .. } => {}
244289
_ => {}

compiler/rustc_hir_analysis/src/variance/constraints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use hir::def_id::{DefId, LocalDefId};
77
use rustc_hir as hir;
88
use rustc_hir::def::DefKind;
99
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
10-
use rustc_middle::ty::{self, Subst, Ty, TyCtxt};
10+
use rustc_middle::ty::{self, Ty, TyCtxt};
1111

1212
use super::terms::VarianceTerm::*;
1313
use super::terms::*;

compiler/rustc_lint/src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_macros::LintDiagnostic;
99
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
1010
use rustc_middle::ty::subst::SubstsRef;
1111
use rustc_middle::ty::{
12-
self, AdtKind, DefIdTree, Subst, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
12+
self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
1313
};
1414
use rustc_span::source_map;
1515
use rustc_span::symbol::sym;

compiler/rustc_privacy/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_middle::span_bug;
2828
use rustc_middle::ty::abstract_const::{walk_abstract_const, AbstractConst, Node as ACNode};
2929
use rustc_middle::ty::query::Providers;
3030
use rustc_middle::ty::subst::InternalSubsts;
31-
use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind, Subst};
31+
use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
3232
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
3333
use rustc_session::lint;
3434
use rustc_span::hygiene::Transparency;

compiler/rustc_trait_selection/src/traits/project.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use rustc_hir::lang_items::LangItem;
3030
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
3131
use rustc_middle::traits::select::OverflowError;
3232
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
33-
use rustc_middle::ty::subst::{Subst, SubstsRef};
33+
use rustc_middle::ty::subst::SubstsRef;
3434
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
3535
use rustc_middle::ty::DefIdTree;
3636
use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};

compiler/rustc_trait_selection/src/traits/query/normalize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
1313
use rustc_hir::def_id::DefId;
1414
use rustc_infer::traits::Normalized;
1515
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
16-
use rustc_middle::ty::subst::{Subst, SubstsRef};
16+
use rustc_middle::ty::subst::SubstsRef;
1717
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable};
1818
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
1919
use rustc_span::DUMMY_SP;

compiler/rustc_trait_selection/src/traits/wf.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
55
use rustc_hir::lang_items::LangItem;
66
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
77
use rustc_middle::ty::walk::TypeWalker;
8-
use rustc_middle::ty::{self, ParamEnv, Subst, ToPredicate, Ty, TyCtxt, TypeVisitable};
8+
use rustc_middle::ty::{self, ParamEnv, ToPredicate, Ty, TyCtxt, TypeVisitable};
99
use rustc_span::Span;
1010

1111
use std::iter;
@@ -506,9 +506,9 @@ impl<'tcx> WfPredicates<'tcx> {
506506
cause,
507507
depth,
508508
param_env,
509-
ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
510-
ty::OutlivesPredicate(rty, r),
511-
))
509+
ty::Binder::dummy(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
510+
rty, r,
511+
)))
512512
.to_predicate(self.tcx()),
513513
));
514514
}
@@ -606,8 +606,7 @@ impl<'tcx> WfPredicates<'tcx> {
606606
cause.clone(),
607607
depth,
608608
param_env,
609-
ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did))
610-
.to_predicate(tcx),
609+
ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did)).to_predicate(tcx),
611610
)
612611
}));
613612
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
type X1 = X2;
2-
//~^ ERROR cycle detected when expanding type alias `X1`
2+
//~^ ERROR cycle detected when expanding type alias
33
type X2 = X3;
4+
//~^ ERROR cycle detected when expanding type alias
45
type X3 = X1;
6+
//~^ ERROR cycle detected when expanding type alias
57

68
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
1-
error[E0391]: cycle detected when expanding type alias `X1`
2-
--> $DIR/infinite-type-alias-mutual-recursion.rs:1:11
3-
|
4-
LL | type X1 = X2;
5-
| ^^
6-
|
7-
note: ...which requires expanding type alias `X2`...
8-
--> $DIR/infinite-type-alias-mutual-recursion.rs:3:11
9-
|
10-
LL | type X2 = X3;
11-
| ^^
12-
note: ...which requires expanding type alias `X3`...
13-
--> $DIR/infinite-type-alias-mutual-recursion.rs:4:11
1+
error: cycle detected when expanding type alias
2+
--> $DIR/infinite-type-alias-mutual-recursion.rs:5:1
143
|
154
LL | type X3 = X1;
16-
| ^^
17-
= note: ...which again requires expanding type alias `X1`, completing the cycle
18-
= note: type aliases cannot be recursive
19-
= help: consider using a struct, enum, or union instead to break the cycle
20-
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
21-
note: cycle used when collecting item types in top-level module
5+
| ^^^^^^^
6+
7+
error: cycle detected when expanding type alias
228
--> $DIR/infinite-type-alias-mutual-recursion.rs:1:1
239
|
24-
LL | / type X1 = X2;
25-
LL | |
26-
LL | | type X2 = X3;
27-
LL | | type X3 = X1;
28-
LL | |
29-
LL | | fn main() {}
30-
| |____________^
10+
LL | type X1 = X2;
11+
| ^^^^^^^
12+
13+
error: cycle detected when expanding type alias
14+
--> $DIR/infinite-type-alias-mutual-recursion.rs:3:1
15+
|
16+
LL | type X2 = X3;
17+
| ^^^^^^^
3118

32-
error: aborting due to previous error
19+
error: aborting due to 3 previous errors
3320

34-
For more information about this error, try `rustc --explain E0391`.

0 commit comments

Comments
 (0)