review
This commit is contained in:
parent
7c97a76b76
commit
2062f2ca82
@ -311,7 +311,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
goal: Goal<'tcx, G>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
|
||||
if let Some(ambig) = self.self_ty_infer_ambiguity_hack(goal) {
|
||||
if let Some(ambig) = self.assemble_self_ty_infer_ambiguity_response(goal) {
|
||||
return ambig;
|
||||
}
|
||||
|
||||
@ -324,13 +324,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
candidates
|
||||
}
|
||||
|
||||
/// HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule,
|
||||
/// `?0: Trait` is ambiguous, because it may be satisfied via a builtin rule,
|
||||
/// object bound, alias bound, etc. We are unable to determine this until we can at
|
||||
/// least structurally resolve the type one layer.
|
||||
///
|
||||
/// It would also require us to consider all impls of the trait, which is both pretty
|
||||
/// bad for perf and would also constrain the self type if there is just a single impl.
|
||||
fn self_ty_infer_ambiguity_hack<G: GoalKind<'tcx>>(
|
||||
fn assemble_self_ty_infer_ambiguity_response<G: GoalKind<'tcx>>(
|
||||
&mut self,
|
||||
goal: Goal<'tcx, G>,
|
||||
) -> Option<Vec<Candidate<'tcx>>> {
|
||||
@ -353,7 +353,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
goal: Goal<'tcx, G>,
|
||||
) -> Vec<Candidate<'tcx>> {
|
||||
debug_assert_eq!(goal, self.resolve_vars_if_possible(goal));
|
||||
if let Some(ambig) = self.self_ty_infer_ambiguity_hack(goal) {
|
||||
if let Some(ambig) = self.assemble_self_ty_infer_ambiguity_response(goal) {
|
||||
return ambig;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
// Checks that we do not get ambiguity by considering an impl
|
||||
// multiple times if we're able to normalize the self type.
|
||||
|
||||
trait Trait<'a> {}
|
||||
|
||||
impl<'a, T: 'a> Trait<'a> for T {}
|
||||
|
@ -1,23 +0,0 @@
|
||||
error[E0283]: type annotations needed: cannot satisfy `<T as Id>::Assoc: Trait<'_>`
|
||||
--> $DIR/assemble-normalizing-self-ty-impl-ambiguity.rs:19:5
|
||||
|
|
||||
LL | impls_trait::<<T as Id>::Assoc>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: cannot satisfy `<T as Id>::Assoc: Trait<'_>`
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/assemble-normalizing-self-ty-impl-ambiguity.rs:9:23
|
||||
|
|
||||
LL | fn impls_trait<'a, T: Trait<'a>>() {}
|
||||
| ^^^^^^^^^ required by this bound in `impls_trait`
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/assemble-normalizing-self-ty-impl-ambiguity.rs:24:5
|
||||
|
|
||||
LL | impls_trait::<<<() as Id>::Assoc as Id>::Assoc>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_trait`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0283.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
22
tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs
Normal file
22
tests/ui/traits/new-solver/dont-normalize-proj-with-error.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
|
||||
// Test that we don't incorrectly leak unconstrained inference variables
|
||||
// if the projection contained an error. This caused an ICE in writeback.
|
||||
|
||||
trait Mirror {
|
||||
type Assoc: ?Sized;
|
||||
}
|
||||
|
||||
struct Wrapper<T: ?Sized>(T);
|
||||
impl<T: ?Sized> Mirror for Wrapper<T> {
|
||||
type Assoc = T;
|
||||
}
|
||||
|
||||
fn mirror<W: Mirror>(_: W) -> Box<W::Assoc> { todo!() }
|
||||
|
||||
fn type_error() -> TypeError { todo!() }
|
||||
//~^ ERROR cannot find type `TypeError` in this scope
|
||||
|
||||
fn main() {
|
||||
let x = mirror(type_error());
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
error[E0412]: cannot find type `TypeError` in this scope
|
||||
--> $DIR/dont-normalize-proj-with-error.rs:17:20
|
||||
|
|
||||
LL | fn type_error() -> TypeError { todo!() }
|
||||
| ^^^^^^^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
Loading…
x
Reference in New Issue
Block a user