Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Silence follow-up errors directly based on error types and regions #125667

Merged
merged 2 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
placeholder_indices,
placeholder_index_to_region: _,
liveness_constraints,
outlives_constraints,
member_constraints,
mut outlives_constraints,
mut member_constraints,
universe_causes,
type_tests,
} = constraints;
Expand All @@ -144,6 +144,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
&universal_region_relations,
);

if let Some(guar) = universal_regions.tainted_by_errors() {
// Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
// outlives bounds that we may end up checking.
outlives_constraints = Default::default();
member_constraints = Default::default();

// Also taint the entire scope.
infcx.set_tainted_by_errors(guar);
}

let mut regioncx = RegionInferenceContext::new(
infcx,
var_origins,
Expand Down
20 changes: 17 additions & 3 deletions compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, T
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::{kw, sym};
use rustc_span::Symbol;
use rustc_span::{ErrorGuaranteed, Symbol};
use std::cell::Cell;
use std::iter;

use crate::renumber::RegionCtxt;
Expand Down Expand Up @@ -186,6 +187,10 @@ struct UniversalRegionIndices<'tcx> {

/// The vid assigned to `'static`. Used only for diagnostics.
pub fr_static: RegionVid,

/// Whether we've encountered an error region. If we have, cancel all
/// outlives errors, as they are likely bogus.
pub tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -408,6 +413,10 @@ impl<'tcx> UniversalRegions<'tcx> {
}
}
}

pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
self.indices.tainted_by_errors.get()
}
}

struct UniversalRegionsBuilder<'cx, 'tcx> {
Expand Down Expand Up @@ -663,7 +672,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));

UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
UniversalRegionIndices {
indices: global_mapping.chain(arg_mapping).collect(),
fr_static,
tainted_by_errors: Cell::new(None),
}
}

fn compute_inputs_and_output(
Expand Down Expand Up @@ -868,7 +881,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReVar(..) = *r {
r.as_var()
} else if r.is_error() {
} else if let ty::ReError(guar) = *r {
self.tainted_by_errors.set(Some(guar));
// We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the
// `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if
// errors are being emitted and 2) it leaves the happy path unaffected.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
bug!("unexpected sort of node in type_of(): {:?}", x);
}
};
if let Err(e) = icx.check_tainted_by_errors() {
if let Err(e) = icx.check_tainted_by_errors()
&& !output.references_error()
{
ty::EarlyBinder::bind(Ty::new_error(tcx, e))
} else {
ty::EarlyBinder::bind(output)
Expand Down
13 changes: 8 additions & 5 deletions tests/rustdoc-ui/unable-fulfill-trait.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
// This test ensures that it's not crashing rustdoc.

pub struct Foo<'a, 'b, T> {
field1: dyn Bar<'a, 'b,>,
field1: dyn Bar<'a, 'b>,
//~^ ERROR
//~| ERROR
//~| ERROR
}

pub trait Bar<'x, 's, U>
where U: 'x,
Self:'x,
Self:'s
{}
where
U: 'x,
Self: 'x,
Self: 's,
{
}
31 changes: 24 additions & 7 deletions tests/rustdoc-ui/unable-fulfill-trait.stderr
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/unable-fulfill-trait.rs:4:17
|
LL | field1: dyn Bar<'a, 'b,>,
LL | field1: dyn Bar<'a, 'b>,
| ^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `U`
--> $DIR/unable-fulfill-trait.rs:9:11
--> $DIR/unable-fulfill-trait.rs:10:11
|
LL | pub trait Bar<'x, 's, U>
| ^^^ -
help: add missing generic argument
|
LL | field1: dyn Bar<'a, 'b, U,>,
LL | field1: dyn Bar<'a, 'b, U>,
| +++

error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
--> $DIR/unable-fulfill-trait.rs:4:13
|
LL | field1: dyn Bar<'a, 'b,>,
| ^^^^^^^^^^^^^^^^
LL | field1: dyn Bar<'a, 'b>,
| ^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
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 3 previous errors

Some errors have detailed explanations: E0107, E0227.
Some errors have detailed explanations: E0107, E0227, E0478.
For more information about an error, try `rustc --explain E0107`.
2 changes: 1 addition & 1 deletion tests/ui/associated-inherent-types/issue-109071.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl<T> Windows { //~ ERROR: missing generics for struct `Windows`

impl<T> Windows<T> {
fn T() -> Option<Self::Item> {}
//~^ ERROR: ambiguous associated type
//[no_gate]~^ ERROR: ambiguous associated type
}

fn main() {}
17 changes: 2 additions & 15 deletions tests/ui/associated-inherent-types/issue-109071.with_gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,7 @@ help: add missing generic argument
LL | impl<T> Windows<T> {
| +++

error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^
|
help: use fully-qualified syntax
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0107, E0223, E0637.
Some errors have detailed explanations: E0107, E0637.
For more information about an error, try `rustc --explain E0107`.
1 change: 0 additions & 1 deletion tests/ui/associated-inherent-types/issue-109299.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d`
}

fn test(_: Lexer::Cursor) {}
//~^ ERROR: lifetime may not live long enough

fn main() {}
11 changes: 1 addition & 10 deletions tests/ui/associated-inherent-types/issue-109299.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ LL | impl Lexer<'d> {
| |
| help: consider introducing lifetime `'d` here: `<'d>`

error: lifetime may not live long enough
--> $DIR/issue-109299.rs:10:1
|
LL | fn test(_: Lexer::Cursor) {}
| ^^^^^^^^-^^^^^^^^^^^^^^^^
| | |
| | has type `Lexer<'1>::Cursor`
| requires that `'1` must outlive `'static`

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0261`.
1 change: 0 additions & 1 deletion tests/ui/borrowck/generic_const_early_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ struct DataWrapper<'static> {
//~^ ERROR invalid lifetime parameter name: `'static`
data: &'a [u8; Self::SIZE],
//~^ ERROR use of undeclared lifetime name `'a`
//~^^ ERROR lifetime may not live long enough
}

impl DataWrapper<'a> {
Expand Down
10 changes: 2 additions & 8 deletions tests/ui/borrowck/generic_const_early_param.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LL | data: &'a [u8; Self::SIZE],
| ^^ undeclared lifetime

error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/generic_const_early_param.rs:11:18
--> $DIR/generic_const_early_param.rs:10:18
|
LL | impl DataWrapper<'a> {
| - ^^ undeclared lifetime
Expand All @@ -30,13 +30,7 @@ LL | #![feature(generic_const_exprs)]
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
= note: `#[warn(incomplete_features)]` on by default

error: lifetime may not live long enough
--> $DIR/generic_const_early_param.rs:6:20
|
LL | data: &'a [u8; Self::SIZE],
| ^^^^^^^^^^ requires that `'_` must outlive `'static`

error: aborting due to 4 previous errors; 1 warning emitted
error: aborting due to 3 previous errors; 1 warning emitted

Some errors have detailed explanations: E0261, E0262.
For more information about an error, try `rustc --explain E0261`.
2 changes: 1 addition & 1 deletion tests/ui/const-generics/issues/issue-71381.full.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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:22:40
--> $DIR/issue-71381.rs:23:40
|
LL | const FN: unsafe extern "C" fn(Args),
| ^^^^ the type must not depend on the parameter `Args`
Expand Down
20 changes: 18 additions & 2 deletions tests/ui/const-generics/issues/issue-71381.min.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@ 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:22: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: aborting due to 2 previous errors
error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71381.rs:14:61
|
LL | pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`

error: using function pointers as const generic parameters is forbidden
--> $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: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0770`.
2 changes: 2 additions & 0 deletions tests/ui/const-generics/issues/issue-71381.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ unsafe extern "C" fn pass(args: PassArg) {
impl Test {
pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
//~^ 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 _
}

Expand All @@ -21,6 +22,7 @@ impl Test {
const IDX: usize,
const FN: unsafe extern "C" fn(Args),
//~^ ERROR: the type of const parameters must not depend on other generic parameters
//[min]~^^ ERROR: using function pointers as const generic parameters is forbidden
>(
args: Args,
) {
Expand Down
10 changes: 9 additions & 1 deletion tests/ui/const-generics/issues/issue-71611.min.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ LL | fn func<A, const F: fn(inner: A)>(outer: A) {
|
= note: type parameters may not be used in the type of const parameters

error: aborting due to 1 previous error
error: using function pointers as const generic parameters is forbidden
--> $DIR/issue-71611.rs:5:21
|
LL | fn func<A, const F: fn(inner: A)>(outer: A) {
| ^^^^^^^^^^^^
|
= note: the only supported types are integers, `bool` and `char`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0770`.
1 change: 1 addition & 0 deletions tests/ui/const-generics/issues/issue-71611.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

fn func<A, const F: fn(inner: A)>(outer: A) {
//~^ ERROR: the type of const parameters must not depend on other generic parameters
//[min]~| ERROR: using function pointers as const generic parameters is forbidden
F(outer);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ impl Opcode2 {
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
move |i| match msg_type {
Opcode2::OP2 => unimplemented!(),
//~^ ERROR: could not evaluate constant pattern
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ help: you might be missing a type parameter
LL | pub struct Opcode2<S>(&'a S);
| +++

error: aborting due to 2 previous errors
error: could not evaluate constant pattern
--> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
|
LL | Opcode2::OP2 => unimplemented!(),
| ^^^^^^^^^^^^

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0261, E0412.
For more information about an error, try `rustc --explain E0261`.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
//~^ ERROR missing generics for associated type
//~^^ ERROR missing generics for associated type
//~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
//~| ERROR may not live long enough
t
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,7 @@ help: add missing lifetime argument
LL | fn foo<'a, T1: X<Y<'a> = T1>>(t : T1) -> T1::Y<'a> {
| ++++

error: lifetime may not live long enough
--> $DIR/gat-trait-path-missing-lifetime.rs:8:3
|
LL | fn foo<'a, T1: X<Y = T1>>(t : T1) -> T1::Y<'a> {
| ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | lifetime `'a` defined here
| requires that `'a` must outlive `'static`

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0046, E0049, E0107.
For more information about an error, try `rustc --explain E0046`.
1 change: 0 additions & 1 deletion tests/ui/generic-associated-types/issue-70304.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,4 @@ fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
pub fn main() {
let doc = create_doc();
let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
//~^ ERROR: `doc` does not live long enough
}
Loading
Loading