about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs15
-rw-r--r--tests/crashes/120792.rs25
-rw-r--r--tests/crashes/120793-2.rs22
-rw-r--r--tests/crashes/120793.rs21
-rw-r--r--tests/crashes/121063.rs20
-rw-r--r--tests/crashes/121957-1.rs20
-rw-r--r--tests/crashes/121957-2.rs20
-rw-r--r--tests/ui/polymorphization/inline-incorrect-early-bound.rs27
-rw-r--r--tests/ui/polymorphization/inline-incorrect-early-bound.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs32
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr21
11 files changed, 108 insertions, 130 deletions
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index 7b6d86d22a5..a2bed61a7ae 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -191,11 +191,22 @@ fn resolve_associated_item<'tcx>(
 
             // Any final impl is required to define all associated items.
             if !leaf_def.item.defaultness(tcx).has_value() {
-                let guard = tcx.dcx().span_delayed_bug(
+                let guar = tcx.dcx().span_delayed_bug(
                     tcx.def_span(leaf_def.item.def_id),
                     "missing value for assoc item in impl",
                 );
-                return Err(guard);
+                return Err(guar);
+            }
+
+            // Make sure that we're projecting to an item that has compatible args.
+            // This may happen if we are resolving an instance before codegen, such
+            // as during inlining. This check is also done in projection.
+            if !tcx.check_args_compatible(leaf_def.item.def_id, args) {
+                let guar = tcx.dcx().span_delayed_bug(
+                    tcx.def_span(leaf_def.item.def_id),
+                    "missing value for assoc item in impl",
+                );
+                return Err(guar);
             }
 
             let args = tcx.erase_regions(args);
diff --git a/tests/crashes/120792.rs b/tests/crashes/120792.rs
deleted file mode 100644
index 51889251787..00000000000
--- a/tests/crashes/120792.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//@ known-bug: #120792
-//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes
-
-impl Trait<()> for () {
-    fn foo<'a, K>(self, _: (), _: K) {
-        todo!();
-    }
-}
-
-trait Foo<T> {}
-
-impl<F, T> Foo<T> for F {
-    fn main() {
-        ().foo((), ());
-    }
-}
-
-trait Trait<T> {
-    fn foo<'a, K>(self, _: T, _: K)
-    where
-        T: 'a,
-        K: 'a;
-}
-
-pub fn main() {}
diff --git a/tests/crashes/120793-2.rs b/tests/crashes/120793-2.rs
deleted file mode 100644
index 0ce5e4df224..00000000000
--- a/tests/crashes/120793-2.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//@ known-bug: #120793
-// can't use build-fail, because this also fails check-fail, but
-// the ICE from #120787 only reproduces on build-fail.
-//@ compile-flags: --emit=mir
-
-#![feature(effects)]
-
-trait Dim {
-    fn dim() -> usize;
-}
-
-enum Dim3 {}
-
-impl Dim for Dim3 {
-    fn dim(x: impl Sized) -> usize {
-        3
-    }
-}
-
-fn main() {
-    [0; Dim3::dim()];
-}
diff --git a/tests/crashes/120793.rs b/tests/crashes/120793.rs
deleted file mode 100644
index 7e9166a50e5..00000000000
--- a/tests/crashes/120793.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ known-bug: #120793
-#![feature(effects)]
-
-trait Dim {
-    fn dim() -> usize;
-}
-
-enum Dim3 {}
-
-impl Dim for Dim3 {
-    fn dim(mut x: impl Iterator<Item = &'_ ()>) -> usize {
-        3
-    }
-}
-
-fn main() {
-    let array: [usize; Dim3::dim()]
-    //~^ ERROR E0015
-        = [0; Dim3::dim()];
-        //~^ ERROR E0015
-}
diff --git a/tests/crashes/121063.rs b/tests/crashes/121063.rs
deleted file mode 100644
index cb9db2853c2..00000000000
--- a/tests/crashes/121063.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: #121063
-//@ compile-flags: -Zpolymorphize=on --edition=2021 -Zinline-mir=yes
-
-use std::{
-    fmt, ops,
-    path::{Component, Path, PathBuf},
-};
-
-pub struct AbsPathBuf(PathBuf);
-
-impl TryFrom<PathBuf> for AbsPathBuf {
-    type Error = PathBuf;
-    fn try_from(path: impl AsRef<Path>) -> Result<AbsPathBuf, PathBuf> {}
-}
-
-impl TryFrom<&str> for AbsPathBuf {
-    fn try_from(path: &str) -> Result<AbsPathBuf, PathBuf> {
-        AbsPathBuf::try_from(PathBuf::from(path))
-    }
-}
diff --git a/tests/crashes/121957-1.rs b/tests/crashes/121957-1.rs
deleted file mode 100644
index 74b4649cc9d..00000000000
--- a/tests/crashes/121957-1.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: #121957
-#![feature(const_trait_impl, effects)]
-
-#[const_trait]
-trait Main {
-    fn compute<T: ~const Aux>() -> u32;
-}
-
-impl const Main for () {
-    fn compute<'x, 'y, 'z: 'x>() -> u32 {}
-}
-
-#[const_trait]
-trait Aux {}
-
-impl const Aux for () {}
-
-fn main() {
-    const _: u32 = <()>::compute::<()>();
-}
diff --git a/tests/crashes/121957-2.rs b/tests/crashes/121957-2.rs
deleted file mode 100644
index 74b4649cc9d..00000000000
--- a/tests/crashes/121957-2.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-//@ known-bug: #121957
-#![feature(const_trait_impl, effects)]
-
-#[const_trait]
-trait Main {
-    fn compute<T: ~const Aux>() -> u32;
-}
-
-impl const Main for () {
-    fn compute<'x, 'y, 'z: 'x>() -> u32 {}
-}
-
-#[const_trait]
-trait Aux {}
-
-impl const Aux for () {}
-
-fn main() {
-    const _: u32 = <()>::compute::<()>();
-}
diff --git a/tests/ui/polymorphization/inline-incorrect-early-bound.rs b/tests/ui/polymorphization/inline-incorrect-early-bound.rs
new file mode 100644
index 00000000000..e69e4a4faa0
--- /dev/null
+++ b/tests/ui/polymorphization/inline-incorrect-early-bound.rs
@@ -0,0 +1,27 @@
+// This test demonstrates an ICE that may occur when we try to resolve the instance
+// of a impl that has different generics than the trait it's implementing. This ensures
+// we first check that the args are compatible before resolving the body, just like
+// we do in projection before substituting a GAT.
+//
+// When polymorphization is enabled, we check the optimized MIR for unused parameters.
+// This will invoke the inliner, leading to this ICE.
+
+//@ compile-flags: -Zpolymorphize=on -Zinline-mir=yes
+
+trait Trait {
+    fn foo<'a, K: 'a>(self, _: K);
+}
+
+impl Trait for () {
+    #[inline]
+    fn foo<K>(self, _: K) {
+        //~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration
+        todo!();
+    }
+}
+
+pub fn qux<T>() {
+    ().foo(());
+}
+
+fn main() {}
diff --git a/tests/ui/polymorphization/inline-incorrect-early-bound.stderr b/tests/ui/polymorphization/inline-incorrect-early-bound.stderr
new file mode 100644
index 00000000000..3a1d05e8a36
--- /dev/null
+++ b/tests/ui/polymorphization/inline-incorrect-early-bound.stderr
@@ -0,0 +1,15 @@
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+  --> $DIR/inline-incorrect-early-bound.rs:17:11
+   |
+LL |     fn foo<'a, K: 'a>(self, _: K);
+   |           -----------
+   |           |       |
+   |           |       this bound might be missing in the impl
+   |           lifetimes in impl do not match this method in trait
+...
+LL |     fn foo<K>(self, _: K) {
+   |           ^^^ lifetimes do not match method in trait
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs
new file mode 100644
index 00000000000..e3adcce17b4
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs
@@ -0,0 +1,32 @@
+// This test demonstrates an ICE that may occur when we try to resolve the instance
+// of a impl that has different generics than the trait it's implementing. This ensures
+// we first check that the args are compatible before resolving the body, just like
+// we do in projection before substituting a GAT.
+//
+// Const traits aren't the only way to achieve this ICE, but it's a convenient way
+// to ensure the inliner is called.
+
+//@ compile-flags: -Znext-solver -Zinline-mir=yes
+
+#![feature(const_trait_impl, effects)]
+//~^ WARN the feature `effects` is incomplete
+
+trait Trait {
+    fn foo(self);
+}
+
+impl Trait for () {
+    #[inline]
+    fn foo<T>(self) {
+        //~^ ERROR  method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+        todo!();
+    }
+}
+
+const fn foo() {
+    ().foo();
+}
+
+const UWU: () = foo();
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr
new file mode 100644
index 00000000000..2e7801c0b8a
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr
@@ -0,0 +1,21 @@
+warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:11:30
+   |
+LL | #![feature(const_trait_impl, effects)]
+   |                              ^^^^^^^
+   |
+   = note: see issue #102090 <https://github.com/rust-lang/rust/issues/102090> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0049]: method `foo` has 1 type parameter but its trait declaration has 0 type parameters
+  --> $DIR/inline-incorrect-early-bound-in-ctfe.rs:20:12
+   |
+LL |     fn foo(self);
+   |           - expected 0 type parameters
+...
+LL |     fn foo<T>(self) {
+   |            ^ found 1 type parameter
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0049`.