diff options
| author | Michael Goulet <michael@errs.io> | 2023-06-23 15:58:09 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-06-23 16:23:27 +0000 |
| commit | f12695b53b6b8e5105c3813f402404e12c38ca08 (patch) | |
| tree | f19ff343ba5a8392ef2bdd22bdc9b3585e32c977 | |
| parent | 04075b32021932e3e8f6ab55d519b3b3494b6ef9 (diff) | |
| download | rust-f12695b53b6b8e5105c3813f402404e12c38ca08.tar.gz rust-f12695b53b6b8e5105c3813f402404e12c38ca08.zip | |
Don't emit same goal as input during wf obligations
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 11 | ||||
| -rw-r--r-- | tests/ui/traits/new-solver/alias-bound-unsound.rs | 2 | ||||
| -rw-r--r-- | tests/ui/traits/new-solver/alias-bound-unsound.stderr | 14 |
3 files changed, 24 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index e80d413d976..e96e89ce73c 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -77,12 +77,19 @@ pub fn unnormalized_obligations<'tcx>( param_env: ty::ParamEnv<'tcx>, arg: GenericArg<'tcx>, ) -> Option<Vec<traits::PredicateObligation<'tcx>>> { + debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg)); + + // However, if `arg` IS an unresolved inference variable, returns `None`, + // because we are not able to make any progress at all. This is to prevent + // "livelock" where we say "$0 is WF if $0 is WF". + if arg.is_non_region_infer() { + return None; + } + if let ty::GenericArgKind::Lifetime(..) = arg.unpack() { return Some(vec![]); } - debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg)); - let mut wf = WfPredicates { infcx, param_env, diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/new-solver/alias-bound-unsound.rs index 00294c708f1..208d4ce966a 100644 --- a/tests/ui/traits/new-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/new-solver/alias-bound-unsound.rs @@ -23,5 +23,7 @@ fn main() { drop(<() as Foo>::copy_me(&x)); //~^ ERROR `<() as Foo>::Item: Copy` is not satisfied //~| ERROR `<() as Foo>::Item` is not well-formed + //~| ERROR `_` is not well-formed + //~| ERROR `_` is not well-formed println!("{x}"); } diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.stderr b/tests/ui/traits/new-solver/alias-bound-unsound.stderr index 9a43d2a6639..3c2ad8f12bd 100644 --- a/tests/ui/traits/new-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/new-solver/alias-bound-unsound.stderr @@ -19,6 +19,18 @@ error: the type `<() as Foo>::Item` is not well-formed LL | drop(<() as Foo>::copy_me(&x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: the type `_` is not well-formed + --> $DIR/alias-bound-unsound.rs:23:5 + | +LL | drop(<() as Foo>::copy_me(&x)); + | ^^^^ + +error: the type `_` is not well-formed + --> $DIR/alias-bound-unsound.rs:23:10 + | +LL | drop(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. |
