From 40d132f0f826b0f0ae203219ab30d23da8f55573 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 24 Jul 2024 22:59:38 -0400 Subject: [PATCH] Make sure that args are compatible in resolve_associated_item --- compiler/rustc_ty_utils/src/instance.rs | 15 +++++++-- tests/crashes/120792.rs | 25 --------------- tests/crashes/120793-2.rs | 22 ------------- tests/crashes/120793.rs | 21 ------------ tests/crashes/121063.rs | 20 ------------ tests/crashes/121957-1.rs | 20 ------------ tests/crashes/121957-2.rs | 20 ------------ .../inline-incorrect-early-bound.rs | 27 ++++++++++++++++ .../inline-incorrect-early-bound.stderr | 15 +++++++++ .../inline-incorrect-early-bound-in-ctfe.rs | 32 +++++++++++++++++++ ...nline-incorrect-early-bound-in-ctfe.stderr | 21 ++++++++++++ 11 files changed, 108 insertions(+), 130 deletions(-) delete mode 100644 tests/crashes/120792.rs delete mode 100644 tests/crashes/120793-2.rs delete mode 100644 tests/crashes/120793.rs delete mode 100644 tests/crashes/121063.rs delete mode 100644 tests/crashes/121957-1.rs delete mode 100644 tests/crashes/121957-2.rs create mode 100644 tests/ui/polymorphization/inline-incorrect-early-bound.rs create mode 100644 tests/ui/polymorphization/inline-incorrect-early-bound.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/inline-incorrect-early-bound-in-ctfe.stderr diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 7b6d86d22a578..a2bed61a7ae1a 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 51889251787d4..0000000000000 --- 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 {} - -impl Foo for F { - fn main() { - ().foo((), ()); - } -} - -trait Trait { - 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 0ce5e4df2247c..0000000000000 --- 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 7e9166a50e553..0000000000000 --- 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) -> 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 cb9db2853c2ac..0000000000000 --- 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 for AbsPathBuf { - type Error = PathBuf; - fn try_from(path: impl AsRef) -> Result {} -} - -impl TryFrom<&str> for AbsPathBuf { - fn try_from(path: &str) -> Result { - 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 74b4649cc9d95..0000000000000 --- 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() -> 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 74b4649cc9d95..0000000000000 --- 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() -> 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 0000000000000..e69e4a4faa05d --- /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(self, _: K) { + //~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration + todo!(); + } +} + +pub fn qux() { + ().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 0000000000000..3a1d05e8a3613 --- /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(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 0000000000000..e3adcce17b42c --- /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(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 0000000000000..2e7801c0b8acd --- /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 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(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`.