Skip to content

Commit

Permalink
Taint obligations in confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jul 29, 2024
1 parent 484a281 commit ed019dc
Show file tree
Hide file tree
Showing 24 changed files with 138 additions and 228 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let is_method = mode == Mode::MethodCall;
let unsatisfied_predicates = &no_match_data.unsatisfied_predicates;
if let Err(guar) = unsatisfied_predicates.error_reported() {
return guar;
}

let similar_candidate = no_match_data.similar_candidate;
let item_kind = if is_method {
"method"
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/ty/generic_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_errors::{DiagArgValue, IntoDiagArg};
use rustc_hir::def_id::DefId;
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_serialize::{Decodable, Encodable};
use rustc_span::ErrorGuaranteed;
use rustc_type_ir::WithCachedTypeInfo;
use smallvec::SmallVec;

Expand Down Expand Up @@ -302,6 +303,14 @@ impl<'tcx> GenericArg<'tcx> {
GenericArgKind::Const(ct) => ct.is_ct_infer(),
}
}

pub fn to_error(self, tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
match self.unpack() {
ty::GenericArgKind::Lifetime(_) => ty::Region::new_error(tcx, guar).into(),
ty::GenericArgKind::Type(_) => Ty::new_error(tcx, guar).into(),
ty::GenericArgKind::Const(_) => ty::Const::new_error(tcx, guar).into(),
}
}
}

impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> {
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2766,6 +2766,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// `$1: Copy`, so we must ensure the obligations are emitted in
// that order.
let predicates = tcx.predicates_of(def_id);
if let Err(guar) = predicates.errored_due_to_unconstrained_params {
self.infcx.set_tainted_by_errors(guar);
// Constrain any inference variables to their error variant to ensure unconstrained
// generic parameters don't leak as they'll never get constrained.
for arg in args {
let _ = self.infcx.at(cause, param_env).eq(
DefineOpaqueTypes::Yes,
arg,
arg.to_error(tcx, guar),
);
}
}
assert_eq!(predicates.parent, None);
let predicates = predicates.instantiate_own(tcx, args);
let mut obligations = Vec::with_capacity(predicates.len());
Expand Down
23 changes: 0 additions & 23 deletions tests/crashes/123141.rs

This file was deleted.

17 changes: 0 additions & 17 deletions tests/crashes/124350.rs

This file was deleted.

22 changes: 0 additions & 22 deletions tests/crashes/125874.rs

This file was deleted.

11 changes: 0 additions & 11 deletions tests/crashes/126942.rs

This file was deleted.

18 changes: 18 additions & 0 deletions tests/ui/associated-item/unconstrained_impl_param.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! This test used to ICE during the normalization of
//! `I`'s type, because of the mismatch of generic parameters
//! on the impl with the generic parameters the projection can
//! fulfill.
struct Thing;

pub trait Every {
type Assoc;
}
impl<T: ?Sized> Every for Thing {
//~^ ERROR: `T` is not constrained
type Assoc = T;
}

static I: <Thing as Every>::Assoc = 3;

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/associated-item/unconstrained_impl_param.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> $DIR/unconstrained_impl_param.rs:11:6
|
LL | impl<T: ?Sized> Every for Thing {
| ^ unconstrained type parameter

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0207`.
14 changes: 14 additions & 0 deletions tests/ui/const-generics/kind_mismatch2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
struct Node<const D: usize> {}

impl<const D: usize> Node<{ D }>
where
SmallVec<D>:, //~ ERROR: constant provided when a type was expected
{
fn new() {}
}

struct SmallVec<T>(T);

fn main() {
Node::new();
}
9 changes: 9 additions & 0 deletions tests/ui/const-generics/kind_mismatch2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0747]: constant provided when a type was expected
--> $DIR/kind_mismatch2.rs:5:14
|
LL | SmallVec<D>:,
| ^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0747`.
68 changes: 1 addition & 67 deletions tests/ui/generic-associated-types/bugs/issue-87735.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,73 +22,7 @@ help: consider adding an explicit lifetime bound
LL | type Output<'a> = FooRef<'a, U> where Self: 'a, U: 'a;
| +++++++

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/issue-87735.rs:31:15
|
LL | impl<'b, T, U> AsRef2 for Foo<T>
| -- the parameter type `T` must be valid for the lifetime `'b` as defined here...
...
LL | T: AsRef2<Output<'b> = &'b [U]>,
| ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/issue-87735.rs:7:31
|
LL | type Output<'a> where Self: 'a;
| ^^
help: consider adding an explicit lifetime bound
|
LL | T: AsRef2<Output<'b> = &'b [U]> + 'b,
| ++++

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/issue-87735.rs:36:31
|
LL | impl<'b, T, U> AsRef2 for Foo<T>
| -- the parameter type `T` must be valid for the lifetime `'b` as defined here...
...
LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
| ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/issue-87735.rs:7:31
|
LL | type Output<'a> where Self: 'a;
| ^^
help: consider adding an explicit lifetime bound
|
LL | T: AsRef2<Output<'b> = &'b [U]> + 'b,
| ++++

error: lifetime may not live long enough
--> $DIR/issue-87735.rs:37:5
|
LL | impl<'b, T, U> AsRef2 for Foo<T>
| -- lifetime `'b` defined here
...
LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
| -- lifetime `'a` defined here
LL | FooRef(self.0.as_ref2())
| ^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`

error: lifetime may not live long enough
--> $DIR/issue-87735.rs:37:12
|
LL | impl<'b, T, U> AsRef2 for Foo<T>
| -- lifetime `'b` defined here
...
LL | fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
| -- lifetime `'a` defined here
LL | FooRef(self.0.as_ref2())
| ^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`

help: `'b` and `'a` must be the same: replace one with the other

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

Some errors have detailed explanations: E0207, E0309.
For more information about an error, try `rustc --explain E0207`.
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/in-trait/refine-resolution-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ impl<T: ?Sized> Mirror for () {

pub trait First {
async fn first() -> <() as Mirror>::Assoc;
//~^ ERROR type annotations needed
}

impl First for () {
async fn first() {}
//~^ WARN does not match trait method signature
}

fn main() {}
22 changes: 16 additions & 6 deletions tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,23 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
LL | impl<T: ?Sized> Mirror for () {
| ^ unconstrained type parameter

error[E0282]: type annotations needed
--> $DIR/refine-resolution-errors.rs:15:5
warning: impl trait in impl method signature does not match trait method signature
--> $DIR/refine-resolution-errors.rs:19:5
|
LL | async fn first() -> <() as Mirror>::Assoc;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
| ------------------------------------------ return type from trait method defined here
...
LL | async fn first() {}
| ^^^^^^^^^^^^^^^^ this bound is stronger than that defined on the trait
|
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
= note: `#[warn(refining_impl_trait_reachable)]` on by default
help: replace the return type so that it matches the trait
|
LL | <() as Mirror>::Assoc {}
| ~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 2 previous errors
error: aborting due to 1 previous error; 1 warning emitted

Some errors have detailed explanations: E0207, E0282.
For more information about an error, try `rustc --explain E0207`.
For more information about this error, try `rustc --explain E0207`.
2 changes: 0 additions & 2 deletions tests/ui/impl-trait/issues/issue-87340.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ impl<T> X for () {
//~^ ERROR `T` is not constrained by the impl trait, self type, or predicates
type I = impl Sized;
fn f() -> Self::I {}
//~^ ERROR type annotations needed
//~| ERROR type annotations needed
}

fn main() {}
17 changes: 2 additions & 15 deletions tests/ui/impl-trait/issues/issue-87340.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
LL | impl<T> X for () {
| ^ unconstrained type parameter

error[E0282]: type annotations needed
--> $DIR/issue-87340.rs:11:23
|
LL | fn f() -> Self::I {}
| ^^ cannot infer type for type parameter `T`

error[E0282]: type annotations needed
--> $DIR/issue-87340.rs:11:15
|
LL | fn f() -> Self::I {}
| ^^^^^^^ cannot infer type for type parameter `T`

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

Some errors have detailed explanations: E0207, E0282.
For more information about an error, try `rustc --explain E0207`.
For more information about this error, try `rustc --explain E0207`.
7 changes: 3 additions & 4 deletions tests/ui/impl-unused-tps.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized

trait Foo<A> {
fn get(&self, A: &A) { }
}
Expand Down Expand Up @@ -36,7 +34,7 @@ impl<T,U> Bar for T {
// Using `U` in an associated type within the impl is not good enough!
}

impl<T,U> Bar for T
impl<T,U> Bar for T //~ ERROR conflicting implementations
where T : Bar<Out=U>
{
//~^^^ ERROR the type parameter `U` is not constrained
Expand All @@ -49,12 +47,13 @@ impl<T,U,V> Foo<T> for T
{
//~^^^ ERROR the type parameter `U` is not constrained
//~| ERROR the type parameter `V` is not constrained
//~| ERROR conflicting implementations

// Here, `V` is bound by an output type parameter, but the inputs
// are not themselves constrained.
}

impl<T,U,V> Foo<(T,U)> for T
impl<T,U,V> Foo<(T,U)> for T //~ ERROR conflicting implementations
where (T,U): Bar<Out=V>
{
// As above, but both T and U ARE constrained.
Expand Down
Loading

0 comments on commit ed019dc

Please sign in to comment.