From ce04c6acbdae34e027656a4fbe72420dcc3d523f Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 18 May 2023 19:03:34 +0100 Subject: [PATCH] Propagate recursion depth in collect_predicates_for_types --- .../src/traits/select/mod.rs | 3 +- tests/ui/traits/cycle-cache-err-60010.stderr | 18 ++++- tests/ui/traits/cycle-recursion-limit.rs | 74 +++++++++++++++++++ tests/ui/traits/cycle-recursion-limit.stderr | 25 +++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/cycle-recursion-limit.rs create mode 100644 tests/ui/traits/cycle-recursion-limit.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b72ff5b78e418..4bbb5ba55b77f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2409,9 +2409,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ) }); - let obligation = Obligation::new( + let obligation = Obligation::with_depth( self.tcx(), cause.clone(), + recursion_depth, param_env, ty::TraitRef::new(self.tcx(), trait_def_id, [normalized_ty]), ); diff --git a/tests/ui/traits/cycle-cache-err-60010.stderr b/tests/ui/traits/cycle-cache-err-60010.stderr index 2ff16b4af38d4..aee41c43aefeb 100644 --- a/tests/ui/traits/cycle-cache-err-60010.stderr +++ b/tests/ui/traits/cycle-cache-err-60010.stderr @@ -1,9 +1,25 @@ -error[E0275]: overflow evaluating the requirement `RootDatabase: RefUnwindSafe` +error[E0275]: overflow evaluating the requirement `SalsaStorage: RefUnwindSafe` --> $DIR/cycle-cache-err-60010.rs:27:13 | LL | _parse: >::Data, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | +note: required because it appears within the type `PhantomData` + --> $SRC_DIR/core/src/marker.rs:LL:COL +note: required because it appears within the type `Unique` + --> $SRC_DIR/core/src/ptr/unique.rs:LL:COL +note: required because it appears within the type `Box` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +note: required because it appears within the type `Runtime` + --> $DIR/cycle-cache-err-60010.rs:23:8 + | +LL | struct Runtime { + | ^^^^^^^ +note: required because it appears within the type `RootDatabase` + --> $DIR/cycle-cache-err-60010.rs:20:8 + | +LL | struct RootDatabase { + | ^^^^^^^^^^^^ note: required for `RootDatabase` to implement `SourceDatabase` --> $DIR/cycle-cache-err-60010.rs:44:9 | diff --git a/tests/ui/traits/cycle-recursion-limit.rs b/tests/ui/traits/cycle-recursion-limit.rs new file mode 100644 index 0000000000000..1890251ba7197 --- /dev/null +++ b/tests/ui/traits/cycle-recursion-limit.rs @@ -0,0 +1,74 @@ +//~ ERROR overflow +// Test that we properly detect the cycle amongst the traits +// here and report an error. + +use std::panic::RefUnwindSafe; + +trait Database { + type Storage; +} +trait HasQueryGroup {} +trait Query { + type Data; +} +trait SourceDatabase { + fn parse(&self) { + loop {} + } +} + +struct ParseQuery; +struct RootDatabase { + _runtime: Runtime, +} +struct Runtime { + _storage: Box, +} +struct SalsaStorage { + _parse: >::Data, +} + +impl Database for RootDatabase { + // This would also be an error if we didn't abort compilation on the error + // above. + type Storage = SalsaStorage; +} +impl HasQueryGroup for RootDatabase {} +impl Query for ParseQuery +where + DB: SourceDatabase, + DB: Database, +{ + type Data = RootDatabase; +} +impl Database for T +where + T: RefUnwindSafe, + T: HasQueryGroup, +{ +} + +pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 { + // This is not satisfied: + // + // - `RootDatabase: SourceDatabase` + // - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup` + // - `RootDatabase: RefUnwindSafe` + // - requires `Runtime: RefUnwindSafe` + // - `Runtime: RefUnwindSafe` + // - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`) + // - `SalsaStorage: RefUnwindSafe` + // - requires `>::Data: RefUnwindSafe`, + // which means `ParseQuery: Query` + // - `ParseQuery: Query` + // - requires `RootDatabase: SourceDatabase`, + // - `RootDatabase: SourceDatabase` is already on the stack, so we have a + // cycle with non-coinductive participants + // + // we used to fail to report an error here because we got the + // caching wrong. + SourceDatabase::parse(db); + 22 +} + +fn main() {} diff --git a/tests/ui/traits/cycle-recursion-limit.stderr b/tests/ui/traits/cycle-recursion-limit.stderr new file mode 100644 index 0000000000000..ca1bad428be70 --- /dev/null +++ b/tests/ui/traits/cycle-recursion-limit.stderr @@ -0,0 +1,25 @@ +error[E0275]: overflow evaluating the requirement `Runtime: RefUnwindSafe` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_recursion_limit`) +note: required because it appears within the type `RootDatabase` + --> $DIR/cycle-recursion-limit.rs:21:8 + | +LL | struct RootDatabase { + | ^^^^^^^^^^^^ +note: required for `RootDatabase` to implement `Database` + --> $DIR/cycle-recursion-limit.rs:44:9 + | +LL | impl Database for T + | ^^^^^^^^ ^ +LL | where +LL | T: RefUnwindSafe, + | ------------- unsatisfied trait bound introduced here +note: required because it appears within the type `Runtime` + --> $DIR/cycle-recursion-limit.rs:24:8 + | +LL | struct Runtime { + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`.