Auto merge of #127311 - oli-obk:do_not_count_errors, r=compiler-errors

Avoid follow-up errors and ICEs after missing lifetime errors on data structures

Tuple struct constructors are functions, so when we call them typeck will use the signature tuple struct constructor function to provide type hints. Since typeck mostly ignores and erases lifetimes, we end up never seeing the error lifetime in writeback, thus not tainting the typeck result.

Now, we eagerly taint typeck results by tainting from `resolve_vars_if_possible`, which is called all over the place.

I did not carry over all the `crashes` test suite tests, as they are really all the same cause (missing or unknown lifetime names in tuple struct definitions or generic arg lists).

fixes #124262
fixes #124083
fixes #125155
fixes #125888
fixes #125992
fixes #126666
fixes #126648
fixes #127268
fixes #127266
fixes #127304
This commit is contained in:
bors 2024-07-11 11:51:33 +00:00
commit c92a8e4d4d
22 changed files with 37 additions and 211 deletions

1
.gitignore vendored
View File

@ -50,6 +50,7 @@ build/
/target
/src/bootstrap/target
/src/tools/x/target
/inc-fat/
# Created by default with `src/ci/docker/run.sh`
/obj/
/rustc-ice*

View File

@ -1264,6 +1264,9 @@ impl<'tcx> InferCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
if let Err(guar) = value.error_reported() {
self.set_tainted_by_errors(guar);
}
if !value.has_non_region_infer() {
return value;
}

View File

@ -1,9 +0,0 @@
//@ known-bug: #124083
struct Outest(&'a ());
fn make() -> Outest {}
fn main() {
if let Outest("foo") = make() {}
}

View File

@ -1,5 +0,0 @@
//@ known-bug: #124262
//@ edition:2021
struct Foo(<&[fn()] as ::core::ops::Deref>::Target);
const _: *const Foo = 0 as _;

View File

@ -1,17 +0,0 @@
//@ known-bug: rust-lang/rust#125155
enum NestedEnum {
First,
Second,
Third
}
enum Enum {
Variant2(Option<*mut &'a &'b ()>)
}
fn foo(x: Enum) -> isize {
match x {
Enum::Variant2(NestedEnum::Third) => 4,
}
}

View File

@ -1,17 +0,0 @@
//@ known-bug: rust-lang/rust#125888
enum NestedEnum {
First,
Second,
}
enum Enum {
Variant(*const &'a ()),
}
fn foo(x: Enum) {
match x {
Enum::Variant(NestedEnum::Second) => {}
}
}
fn main() {}

View File

@ -1,19 +0,0 @@
//@ known-bug: rust-lang/rust#125992
//@ compile-flags: -Zpolonius=next
#![feature(inherent_associated_types)]
type Function = for<'a> fn(&'a i32) -> S<'a>::P;
struct S<'a>(&'a ());
impl<'a> S {
type P = &'a i32;
}
fn ret_ref_local<'e>() -> &'e i32 {
let f: Function = |x| x;
let local = 0;
f(&local)
}

View File

@ -1,8 +0,0 @@
//@ known-bug: rust-lang/rust#126648
struct Outest(*const &'a ());
fn make() -> Outest {}
fn main() {
if let Outest("foo") = make() {}
}

View File

@ -1,18 +0,0 @@
//@ known-bug: rust-lang/rust#126666
#![feature(const_mut_refs)]
#![feature(const_refs_to_static)]
#![feature(object_safe_for_dispatch)]
struct Meh {
x: &'static dyn UnsafeCell,
}
const MUH: Meh = Meh {
x: &mut *(&READONLY as *const _ as *mut _),
};
static READONLY: i32 = 0;
trait UnsafeCell<'a> {}
pub fn main() {}

View File

@ -1,17 +0,0 @@
//@ known-bug: rust-lang/rust#127266
#![feature(const_mut_refs)]
#![feature(const_refs_to_static)]
struct Meh {
x: &'static dyn UnsafeCell,
}
const MUH: Meh = Meh {
x: &mut *(READONLY as *mut _),
};
static READONLY: i32 = 0;
trait UnsafeCell<'a> {}
pub fn main() {}

View File

@ -1,20 +0,0 @@
//@ known-bug: rust-lang/rust #127304
#![feature(adt_const_params)]
trait Trait<T> {}
impl Trait<u16> for () {}
struct MyStr(str);
impl std::marker::ConstParamTy for MyStr {}
fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
S
}
impl MyStr {
const fn new(s: &Trait str) -> &'static MyStr {}
}
pub fn main() {
let f = function_with_my_str::<{ MyStr::new("hello") }>();
}

View File

@ -4,7 +4,6 @@ pub struct Foo<'a, 'b, T> {
field1: dyn Bar<'a, 'b>,
//~^ ERROR
//~| ERROR
//~| ERROR
}
pub trait Bar<'x, 's, U>

View File

@ -5,7 +5,7 @@ LL | field1: dyn Bar<'a, 'b>,
| ^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `U`
--> $DIR/unable-fulfill-trait.rs:10:11
--> $DIR/unable-fulfill-trait.rs:9:11
|
LL | pub trait Bar<'x, 's, U>
| ^^^ -
@ -20,24 +20,7 @@ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
LL | field1: dyn Bar<'a, 'b>,
| ^^^^^^^^^^^^^^^
error[E0478]: lifetime bound not satisfied
--> $DIR/unable-fulfill-trait.rs:4:13
|
LL | field1: dyn Bar<'a, 'b>,
| ^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'b` as defined here
--> $DIR/unable-fulfill-trait.rs:3:20
|
LL | pub struct Foo<'a, 'b, T> {
| ^^
note: but lifetime parameter must outlive the lifetime `'a` as defined here
--> $DIR/unable-fulfill-trait.rs:3:16
|
LL | pub struct Foo<'a, 'b, T> {
| ^^
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0107, E0227, E0478.
Some errors have detailed explanations: E0107, E0227.
For more information about an error, try `rustc --explain E0107`.

View File

@ -7,25 +7,13 @@ LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
= note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-71381.rs:24:40
--> $DIR/issue-71381.rs:23:40
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args`
|
= note: type parameters may not be used in the type of const parameters
error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
--> $DIR/issue-71381.rs:17:9
|
LL | self.0 = Self::trampiline::<Args, IDX, FN> as _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&mut self) {
| ~~~~~~~~~
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0594, E0770.
For more information about an error, try `rustc --explain E0594`.
For more information about this error, try `rustc --explain E0770`.

View File

@ -7,7 +7,7 @@ LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
= note: type parameters may not be used in the type of const parameters
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/issue-71381.rs:24:40
--> $DIR/issue-71381.rs:23:40
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args`
@ -23,25 +23,13 @@ LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "
= note: the only supported types are integers, `bool` and `char`
error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:24:19
--> $DIR/issue-71381.rs:23:19
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`
error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
--> $DIR/issue-71381.rs:17:9
|
LL | self.0 = Self::trampiline::<Args, IDX, FN> as _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&mut self) {
| ~~~~~~~~~
error: aborting due to 4 previous errors
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0594, E0770.
For more information about an error, try `rustc --explain E0594`.
For more information about this error, try `rustc --explain E0770`.

View File

@ -15,7 +15,6 @@ impl Test {
//~^ ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^^ ERROR: using function pointers as const generic parameters is forbidden
self.0 = Self::trampiline::<Args, IDX, FN> as _
//~^ ERROR: cannot assign to `self.0`
}
unsafe extern "C" fn trampiline<

View File

@ -15,7 +15,6 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint>
fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
//~^ ERROR: failed to resolve
//~| ERROR: `()` is not an iterator
unimplemented!()
}

View File

@ -1,11 +1,3 @@
error[E0277]: `()` is not an iterator
--> $DIR/issue-72911.rs:16:20
|
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
error[E0433]: failed to resolve: use of undeclared crate or module `foo`
--> $DIR/issue-72911.rs:11:33
|
@ -18,7 +10,6 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo`
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
| ^^^ use of undeclared crate or module `foo`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0433.
For more information about an error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0433`.

View File

@ -9,7 +9,6 @@ impl<T, S: Iterator<Item = T>> Iterator for ChunkingIterator<T, S> {
type Item = IteratorChunk<T, S>; //~ ERROR missing lifetime
fn next(&mut self) -> Option<IteratorChunk<T, S>> {
//~^ ERROR `impl` item signature doesn't match `trait` item signature
todo!()
}
}

View File

@ -9,20 +9,6 @@ help: consider introducing a named lifetime parameter
LL | type Item<'a> = IteratorChunk<'a, T, S>;
| ++++ +++
error: `impl` item signature doesn't match `trait` item signature
--> $DIR/issue-74918-missing-lifetime.rs:11:5
|
LL | fn next(&mut self) -> Option<IteratorChunk<T, S>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
= note: expected `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'2, T, S>>`
|
= note: expected signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'2, T, S>>`
found signature `fn(&'1 mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'1, T, S>>`
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0106`.

View File

@ -0,0 +1,9 @@
//! This test checks that we taint typeck results when there are
//! error lifetimes, even though typeck doesn't actually care about lifetimes.
struct Slice(&'reborrow [&'static [u8]]);
//~^ ERROR undeclared lifetime
static MAP: Slice = Slice(&[b"" as &'static [u8]]);
fn main() {}

View File

@ -0,0 +1,11 @@
error[E0261]: use of undeclared lifetime name `'reborrow`
--> $DIR/missing_lifetime.rs:4:15
|
LL | struct Slice(&'reborrow [&'static [u8]]);
| - ^^^^^^^^^ undeclared lifetime
| |
| help: consider introducing lifetime `'reborrow` here: `<'reborrow>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0261`.