From f12695b53b6b8e5105c3813f402404e12c38ca08 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 23 Jun 2023 15:58:09 +0000 Subject: [PATCH 1/2] Don't emit same goal as input during wf obligations --- compiler/rustc_trait_selection/src/traits/wf.rs | 11 +++++++++-- tests/ui/traits/new-solver/alias-bound-unsound.rs | 2 ++ .../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 e80d413d97618..e96e89ce73ceb 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>> { + 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 00294c708f1fa..208d4ce966a5e 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 9a43d2a6639ce..3c2ad8f12bd5d 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`. From 2eb7d693095eb1e98b9a041b43a39c9cd228254b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 23 Jun 2023 16:26:22 +0000 Subject: [PATCH 2/2] Resolve vars when reporting WF error --- .../rustc_trait_selection/src/traits/error_reporting/mod.rs | 1 + tests/ui/for/issue-20605.next.stderr | 2 +- tests/ui/for/issue-20605.rs | 2 +- tests/ui/traits/new-solver/alias-bound-unsound.rs | 4 ++-- tests/ui/traits/new-solver/alias-bound-unsound.stderr | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 75a92af714bd5..89634c59df4b4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1049,6 +1049,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => { + let ty = self.resolve_vars_if_possible(ty); match self.tcx.sess.opts.unstable_opts.trait_solver { TraitSolver::Classic => { // WF predicates cannot themselves make diff --git a/tests/ui/for/issue-20605.next.stderr b/tests/ui/for/issue-20605.next.stderr index 5362a68c834a3..a96a53ca93e4a 100644 --- a/tests/ui/for/issue-20605.next.stderr +++ b/tests/ui/for/issue-20605.next.stderr @@ -14,7 +14,7 @@ LL | for item in *things { *item = 0 } = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature -error: the type `<_ as IntoIterator>::IntoIter` is not well-formed +error: the type ` as IntoIterator>::IntoIter` is not well-formed --> $DIR/issue-20605.rs:5:17 | LL | for item in *things { *item = 0 } diff --git a/tests/ui/for/issue-20605.rs b/tests/ui/for/issue-20605.rs index 499271fa92fa9..64156b357051b 100644 --- a/tests/ui/for/issue-20605.rs +++ b/tests/ui/for/issue-20605.rs @@ -4,7 +4,7 @@ fn changer<'a>(mut things: Box>) { for item in *things { *item = 0 } //~^ ERROR the size for values of type - //[next]~^^ ERROR the type `<_ as IntoIterator>::IntoIter` is not well-formed + //[next]~^^ ERROR the type ` as IntoIterator>::IntoIter` is not well-formed //[next]~| ERROR the trait bound `dyn Iterator: IntoIterator` is not satisfied } diff --git a/tests/ui/traits/new-solver/alias-bound-unsound.rs b/tests/ui/traits/new-solver/alias-bound-unsound.rs index 208d4ce966a5e..6b6a77e2c7ee8 100644 --- a/tests/ui/traits/new-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/new-solver/alias-bound-unsound.rs @@ -23,7 +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 + //~| ERROR `<() as Foo>::Item` is not well-formed + //~| ERROR `<() as Foo>::Item` 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 3c2ad8f12bd5d..89abc608213e6 100644 --- a/tests/ui/traits/new-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/new-solver/alias-bound-unsound.stderr @@ -19,13 +19,13 @@ error: the type `<() as Foo>::Item` is not well-formed LL | drop(<() as Foo>::copy_me(&x)); | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: the type `_` is not well-formed +error: the type `<() as Foo>::Item` 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 +error: the type `<() as Foo>::Item` is not well-formed --> $DIR/alias-bound-unsound.rs:23:10 | LL | drop(<() as Foo>::copy_me(&x));