Auto merge of #134504 - oli-obk:push-rltsvnyttwll, r=compiler-errors
Use trait definition cycle detection for trait alias definitions, too fixes #133901 In general doing this for `All` is not right, but this code path is specifically for traits and trait aliases, and there we only ever use `All` for trait aliases.
This commit is contained in:
commit
99db2737c9
6 changed files with 72 additions and 8 deletions
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -772,7 +807,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
});
|
||||
Ty::new(tcx, Adt(adt_def, args))
|
||||
Ty::new_adt(tcx, adt_def, args)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
11
tests/ui/traits/alias/infinite_normalization.rs
Normal file
11
tests/ui/traits/alias/infinite_normalization.rs
Normal file
|
@ -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
tests/ui/traits/alias/infinite_normalization.stderr
Normal file
18
tests/ui/traits/alias/infinite_normalization.stderr
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue