about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_transform/src/impossible_predicates.rs33
-rw-r--r--tests/crashes/122904-2.rs17
-rw-r--r--tests/crashes/139556.rs13
-rw-r--r--tests/ui/consts/promoted_const_call2.rs1
-rw-r--r--tests/ui/consts/promoted_const_call2.stderr17
-rw-r--r--tests/ui/coroutine/moved-twice.rs (renamed from tests/crashes/122630.rs)11
-rw-r--r--tests/ui/coroutine/moved-twice.stderr24
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr30
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs24
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr58
-rw-r--r--tests/ui/type-alias-impl-trait/type-error-drop-elaboration.rs (renamed from tests/crashes/125185.rs)3
-rw-r--r--tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr12
13 files changed, 201 insertions, 61 deletions
diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs
index b03518de00a..883ee32bdec 100644
--- a/compiler/rustc_mir_transform/src/impossible_predicates.rs
+++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs
@@ -28,6 +28,7 @@
 
 use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind};
 use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt};
+use rustc_span::def_id::DefId;
 use rustc_trait_selection::traits;
 use tracing::trace;
 
@@ -35,23 +36,29 @@ use crate::pass_manager::MirPass;
 
 pub(crate) struct ImpossiblePredicates;
 
+fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
+    let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx);
+    tracing::trace!(?predicates);
+    let predicates = predicates.predicates.into_iter().filter(|p| {
+        !p.has_type_flags(
+            // Only consider global clauses to simplify.
+            TypeFlags::HAS_FREE_LOCAL_NAMES
+                // Clauses that refer to unevaluated constants as they cause cycles.
+                | TypeFlags::HAS_CT_PROJECTION,
+        )
+    });
+    let predicates: Vec<_> = traits::elaborate(tcx, predicates).collect();
+    tracing::trace!(?predicates);
+    predicates.references_error() || traits::impossible_predicates(tcx, predicates)
+}
+
 impl<'tcx> MirPass<'tcx> for ImpossiblePredicates {
     #[tracing::instrument(level = "trace", skip(self, tcx, body))]
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         tracing::trace!(def_id = ?body.source.def_id());
-        let predicates = tcx.predicates_of(body.source.def_id()).instantiate_identity(tcx);
-        tracing::trace!(?predicates);
-        let predicates = predicates.predicates.into_iter().filter(|p| {
-            !p.has_type_flags(
-                // Only consider global clauses to simplify.
-                TypeFlags::HAS_FREE_LOCAL_NAMES
-                // Clauses that refer to unevaluated constants as they cause cycles.
-                | TypeFlags::HAS_CT_PROJECTION,
-            )
-        });
-        let predicates: Vec<_> = traits::elaborate(tcx, predicates).collect();
-        tracing::trace!(?predicates);
-        if predicates.references_error() || traits::impossible_predicates(tcx, predicates) {
+        let impossible = body.tainted_by_errors.is_some()
+            || has_impossible_predicates(tcx, body.source.def_id());
+        if impossible {
             trace!("found unsatisfiable predicates");
             // Clear the body to only contain a single `unreachable` statement.
             let bbs = body.basic_blocks.as_mut();
diff --git a/tests/crashes/122904-2.rs b/tests/crashes/122904-2.rs
deleted file mode 100644
index db66b8625db..00000000000
--- a/tests/crashes/122904-2.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #122904
-trait T {}
-
-type Alias<'a> = impl T;
-
-struct S;
-impl<'a> T for &'a S {}
-
-#[define_opaque(Alias)]
-fn with_positive(fun: impl Fn(Alias<'_>)) {
-    with_positive(|&n| ());
-}
-
-#[define_opaque(Alias)]
-fn main(Alias<'_>) {
-    with_positive(|&a| ());
-}
diff --git a/tests/crashes/139556.rs b/tests/crashes/139556.rs
deleted file mode 100644
index 60dc8d7c3af..00000000000
--- a/tests/crashes/139556.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ known-bug: #139556
-
-trait T {}
-
-type Alias<'a> = impl T;
-
-struct S;
-impl<'a> T for &'a S {}
-
-#[define_opaque(Alias)]
-fn with_positive(fun: impl Fn(Alias<'_>)) {
-    with_positive(|&n| ());
-}
diff --git a/tests/ui/consts/promoted_const_call2.rs b/tests/ui/consts/promoted_const_call2.rs
index f332cd18cea..62391f098e5 100644
--- a/tests/ui/consts/promoted_const_call2.rs
+++ b/tests/ui/consts/promoted_const_call2.rs
@@ -4,7 +4,6 @@ pub const C: () = {
     let _: &'static _ = &id(&String::new());
     //~^ ERROR: temporary value dropped while borrowed
     //~| ERROR: temporary value dropped while borrowed
-    //~| ERROR: destructor of `String` cannot be evaluated at compile-time
 };
 
 fn main() {
diff --git a/tests/ui/consts/promoted_const_call2.stderr b/tests/ui/consts/promoted_const_call2.stderr
index bdb43385d20..e62458d1a6a 100644
--- a/tests/ui/consts/promoted_const_call2.stderr
+++ b/tests/ui/consts/promoted_const_call2.stderr
@@ -18,16 +18,8 @@ LL |     let _: &'static _ = &id(&String::new());
    |            |                 creates a temporary value which is freed while still in use
    |            type annotation requires that borrow lasts for `'static`
 
-error[E0493]: destructor of `String` cannot be evaluated at compile-time
-  --> $DIR/promoted_const_call2.rs:4:30
-   |
-LL |     let _: &'static _ = &id(&String::new());
-   |                              ^^^^^^^^^^^^^ - value is dropped here
-   |                              |
-   |                              the destructor for this type cannot be evaluated in constants
-
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call2.rs:11:26
+  --> $DIR/promoted_const_call2.rs:10:26
    |
 LL |     let _: &'static _ = &id(&String::new());
    |            ----------    ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -38,7 +30,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call2.rs:11:30
+  --> $DIR/promoted_const_call2.rs:10:30
    |
 LL |     let _: &'static _ = &id(&String::new());
    |            ----------        ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -46,7 +38,6 @@ LL |     let _: &'static _ = &id(&String::new());
    |            |                 creates a temporary value which is freed while still in use
    |            type annotation requires that borrow lasts for `'static`
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0493, E0716.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/crashes/122630.rs b/tests/ui/coroutine/moved-twice.rs
index e66624431c5..72b83e274c9 100644
--- a/tests/crashes/122630.rs
+++ b/tests/ui/coroutine/moved-twice.rs
@@ -1,22 +1,27 @@
-//@ known-bug: #122630
+//! Regression test for #122630
 //@ compile-flags: -Zvalidate-mir
 
+#![feature(coroutines, coroutine_trait, yield_expr)]
+
 use std::ops::Coroutine;
 
 const FOO_SIZE: usize = 1024;
 struct Foo([u8; FOO_SIZE]);
 
 impl Drop for Foo {
-    fn move_before_yield_with_noop() -> impl Coroutine<Yield = ()> {}
+    fn drop(&mut self) {}
 }
 
 fn overlap_move_points() -> impl Coroutine<Yield = ()> {
-    static || {
+    #[coroutine] static || {
         let first = Foo([0; FOO_SIZE]);
         yield;
         let second = first;
         yield;
         let second = first;
+        //~^ ERROR: use of moved value: `first` [E0382]
         yield;
     }
 }
+
+fn main() {}
diff --git a/tests/ui/coroutine/moved-twice.stderr b/tests/ui/coroutine/moved-twice.stderr
new file mode 100644
index 00000000000..2b21f6c59f0
--- /dev/null
+++ b/tests/ui/coroutine/moved-twice.stderr
@@ -0,0 +1,24 @@
+error[E0382]: use of moved value: `first`
+  --> $DIR/moved-twice.rs:21:22
+   |
+LL |         let first = Foo([0; FOO_SIZE]);
+   |             ----- move occurs because `first` has type `Foo`, which does not implement the `Copy` trait
+LL |         yield;
+LL |         let second = first;
+   |                      ----- value moved here
+LL |         yield;
+LL |         let second = first;
+   |                      ^^^^^ value used here after move
+   |
+note: if `Foo` implemented `Clone`, you could clone the value
+  --> $DIR/moved-twice.rs:9:1
+   |
+LL | struct Foo([u8; FOO_SIZE]);
+   | ^^^^^^^^^^ consider implementing `Clone` for this type
+...
+LL |         let second = first;
+   |                      ----- you could clone this value
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs
new file mode 100644
index 00000000000..5541c5267f3
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs
@@ -0,0 +1,19 @@
+//! Regression test for ICE #139556
+
+#![feature(type_alias_impl_trait)]
+
+trait T {}
+
+type Alias<'a> = impl T;
+
+struct S;
+impl<'a> T for &'a S {}
+
+#[define_opaque(Alias)]
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+//~^ WARN: function cannot return without recursing
+    with_positive(|&n| ());
+    //~^ ERROR: cannot move out of a shared reference
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr
new file mode 100644
index 00000000000..e1fdd222ee1
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr
@@ -0,0 +1,30 @@
+warning: function cannot return without recursing
+  --> $DIR/recursive-drop-elaboration-2.rs:13:1
+   |
+LL | fn with_positive(fun: impl Fn(Alias<'_>)) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL |
+LL |     with_positive(|&n| ());
+   |     ---------------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/recursive-drop-elaboration-2.rs:15:20
+   |
+LL |     with_positive(|&n| ());
+   |                    ^-
+   |                     |
+   |                     data moved here
+   |                     move occurs because `n` has type `S`, which does not implement the `Copy` trait
+   |
+help: consider removing the borrow
+   |
+LL -     with_positive(|&n| ());
+LL +     with_positive(|n| ());
+   |
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs
new file mode 100644
index 00000000000..dd28732ebb2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs
@@ -0,0 +1,24 @@
+//! Regression test for #122904.
+
+#![feature(type_alias_impl_trait)]
+
+trait T {}
+
+type Alias<'a> = impl T;
+
+struct S;
+impl<'a> T for &'a S {}
+
+#[define_opaque(Alias)]
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+//~^ WARN: function cannot return without recursing
+    with_positive(|&n| ());
+    //~^ ERROR: cannot move out of a shared reference
+}
+
+#[define_opaque(Alias)]
+fn main(_: Alias<'_>) {
+//~^ ERROR: `main` function has wrong type [E0580]
+    with_positive(|&a| ());
+    //~^ ERROR: cannot move out of a shared reference
+}
diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr
new file mode 100644
index 00000000000..8b5dc950afd
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr
@@ -0,0 +1,58 @@
+warning: function cannot return without recursing
+  --> $DIR/recursive-drop-elaboration.rs:13:1
+   |
+LL | fn with_positive(fun: impl Fn(Alias<'_>)) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
+LL |
+LL |     with_positive(|&n| ());
+   |     ---------------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/recursive-drop-elaboration.rs:15:20
+   |
+LL |     with_positive(|&n| ());
+   |                    ^-
+   |                     |
+   |                     data moved here
+   |                     move occurs because `n` has type `S`, which does not implement the `Copy` trait
+   |
+help: consider removing the borrow
+   |
+LL -     with_positive(|&n| ());
+LL +     with_positive(|n| ());
+   |
+
+error[E0507]: cannot move out of a shared reference
+  --> $DIR/recursive-drop-elaboration.rs:22:20
+   |
+LL |     with_positive(|&a| ());
+   |                    ^-
+   |                     |
+   |                     data moved here
+   |                     move occurs because `a` has type `S`, which does not implement the `Copy` trait
+   |
+help: consider removing the borrow
+   |
+LL -     with_positive(|&a| ());
+LL +     with_positive(|a| ());
+   |
+
+error[E0580]: `main` function has wrong type
+  --> $DIR/recursive-drop-elaboration.rs:20:1
+   |
+LL | type Alias<'a> = impl T;
+   |                  ------ the found opaque type
+...
+LL | fn main(_: Alias<'_>) {
+   | ^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters
+   |
+   = note: expected signature `fn()`
+              found signature `for<'a> fn(Alias<'a>)`
+
+error: aborting due to 3 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0507, E0580.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/tests/crashes/125185.rs b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.rs
index e77666ca73d..c0fb9007865 100644
--- a/tests/crashes/125185.rs
+++ b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.rs
@@ -1,4 +1,4 @@
-//@ known-bug: rust-lang/rust#125185
+//! Regression test for #125185
 //@ compile-flags: -Zvalidate-mir
 
 #![feature(type_alias_impl_trait)]
@@ -10,6 +10,7 @@ struct A;
 #[define_opaque(Foo)]
 const fn foo() -> Foo {
     value()
+    //~^ ERROR: cannot find function `value` in this scope
 }
 
 const VALUE: Foo = foo();
diff --git a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr
new file mode 100644
index 00000000000..1cb33eabd90
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr
@@ -0,0 +1,12 @@
+error[E0425]: cannot find function `value` in this scope
+  --> $DIR/type-error-drop-elaboration.rs:12:5
+   |
+LL |     value()
+   |     ^^^^^ help: a constant with a similar name exists: `VALUE`
+...
+LL | const VALUE: Foo = foo();
+   | ------------------------- similarly named constant `VALUE` defined here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0425`.