Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use trait definition cycle detection for trait alias definitions, too #134504

Merged
merged 2 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
}
}
}
PredicateFilter::SelfAndAssociatedTypeBounds => {
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
for &(pred, span) in implied_bounds {
debug!("superbound: {:?}", pred);
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
Expand Down
39 changes: 37 additions & 2 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ impl<'tcx> Ty<'tcx> {
/// The more specific methods will often optimize their creation.
#[allow(rustc::usage_of_ty_tykind)]
#[inline]
pub fn new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx> {
fn new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx> {
tcx.mk_ty_from_kind(st)
}

Expand Down Expand Up @@ -613,6 +613,41 @@ impl<'tcx> Ty<'tcx> {
#[inline]
pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
tcx.debug_assert_args_compatible(def.did(), args);
if cfg!(debug_assertions) {
match tcx.def_kind(def.did()) {
DefKind::Struct | DefKind::Union | DefKind::Enum => {}
DefKind::Mod
| DefKind::Variant
| DefKind::Trait
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::Fn
| DefKind::Const
| DefKind::ConstParam
| DefKind::Static { .. }
| DefKind::Ctor(..)
| DefKind::AssocFn
| DefKind::AssocConst
| DefKind::Macro(..)
| DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
| DefKind::AnonConst
| DefKind::InlineConst
| DefKind::OpaqueTy
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm
| DefKind::Impl { .. }
| DefKind::Closure
| DefKind::SyntheticCoroutineBody => {
bug!("not an adt: {def:?} ({:?})", tcx.def_kind(def.did()))
}
}
}
Ty::new(tcx, Adt(def, args))
}

Expand Down Expand Up @@ -772,7 +807,7 @@ impl<'tcx> Ty<'tcx> {
}
}
});
Ty::new(tcx, Adt(adt_def, args))
Ty::new_adt(tcx, adt_def, args)
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/infinite/infinite-trait-alias-recursion.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(trait_alias)]

trait T1 = T2;
//~^ ERROR cycle detected when computing the super predicates of `T1`
//~^ ERROR cycle detected when computing the implied predicates of `T1`

trait T2 = T3;

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/infinite/infinite-trait-alias-recursion.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
error[E0391]: cycle detected when computing the super predicates of `T1`
error[E0391]: cycle detected when computing the implied predicates of `T1`
--> $DIR/infinite-trait-alias-recursion.rs:3:12
|
LL | trait T1 = T2;
| ^^
|
note: ...which requires computing the super predicates of `T2`...
note: ...which requires computing the implied predicates of `T2`...
--> $DIR/infinite-trait-alias-recursion.rs:6:12
|
LL | trait T2 = T3;
| ^^
note: ...which requires computing the super predicates of `T3`...
note: ...which requires computing the implied predicates of `T3`...
--> $DIR/infinite-trait-alias-recursion.rs:8:12
|
LL | trait T3 = T1 + T3;
| ^^
= note: ...which again requires computing the super predicates of `T1`, completing the cycle
= note: ...which again requires computing the implied predicates of `T1`, completing the cycle
= note: trait aliases cannot be recursive
note: cycle used when checking that `T1` is well-formed
--> $DIR/infinite-trait-alias-recursion.rs:3:1
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/traits/alias/infinite_normalization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! This test used to get stuck in an infinite
//! recursion during normalization.
//!
//! issue: https://github.com/rust-lang/rust/issues/133901

#![feature(trait_alias)]
fn foo<T: Baz<i32>>() {}
trait Baz<A> = Baz<Option<A>>;
//~^ ERROR: cycle detected when computing the implied predicates of `Baz`

fn main() {}
18 changes: 18 additions & 0 deletions tests/ui/traits/alias/infinite_normalization.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0391]: cycle detected when computing the implied predicates of `Baz`
--> $DIR/infinite_normalization.rs:8:16
|
LL | trait Baz<A> = Baz<Option<A>>;
| ^^^^^^^^^^^^^^
|
= note: ...which immediately requires computing the implied predicates of `Baz` again
= note: trait aliases cannot be recursive
note: cycle used when computing normalized predicates of `foo`
--> $DIR/infinite_normalization.rs:7:1
|
LL | fn foo<T: Baz<i32>>() {}
| ^^^^^^^^^^^^^^^^^^^^^
= 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

error: aborting due to 1 previous error

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