Make sure that args are compatible in resolve_associated_item

This commit is contained in:
Michael Goulet 2024-07-24 22:59:38 -04:00
parent 2ccafed862
commit 40d132f0f8
11 changed files with 108 additions and 130 deletions

View File

@ -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);

View File

@ -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() {}

View File

@ -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()];
}

View File

@ -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
}

View File

@ -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))
}
}

View File

@ -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::<()>();
}

View File

@ -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::<()>();
}

View File

@ -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() {}

View File

@ -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`.

View File

@ -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() {}

View File

@ -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`.