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

Do not eagerly reject inference vars when trying to resolve method calls. #126316

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let rcvr_t = self.check_expr(rcvr);
// no need to check for bot/err -- callee does that
let rcvr_t = self.structurally_resolve_type(rcvr.span, rcvr_t);
let rcvr_t = self.try_structurally_resolve_type(rcvr.span, rcvr_t);

let method = match self.lookup_method(rcvr_t, segment, segment.ident.span, expr, rcvr, args)
{
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ fn method_autoderef_steps<'tcx>(

let final_ty = autoderef.final_ty(true);
let opt_bad_ty = match final_ty.kind() {
ty::Infer(ty::TyVar(_)) if !reached_raw_pointer => None,
ty::Infer(ty::TyVar(_)) | ty::Error(_) => Some(MethodAutoderefBadTy {
reached_raw_pointer,
ty: infcx.make_query_response_ignoring_pending_obligations(inference_vars, final_ty),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2532,7 +2532,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
let InferOk { obligations, .. } = self
.infcx
.at(&cause, obligation.param_env)
.eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref)
.eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref)
.map_err(|e| {
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
})?;
Expand Down
28 changes: 0 additions & 28 deletions tests/crashes/121613-2.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
//@ known-bug: #121613
//! This test used to ICE #121613
//! Using a generic parameter where there are none expected
//! caused an ICE, hiding the important later errors.

#![feature(more_qualified_paths)]

fn main() {
let _ = <Foo as A>::Assoc { br: 2 };

let <E>::V(..) = E::V(|a, b| a.cmp(b));
//~^ ERROR: multiple applicable items in scope
}

struct StructStruct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0034]: multiple applicable items in scope
--> $DIR/param_mismatch_on_associatedtype_constructor.rs:10:36
|
LL | let <E>::V(..) = E::V(|a, b| a.cmp(b));
| ^^^ multiple `cmp` found
|
note: candidate #1 is defined in the trait `Iterator`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
note: candidate #2 is defined in the trait `Ord`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
help: disambiguate the method for candidate #1
|
LL | let <E>::V(..) = E::V(|a, b| Iterator::cmp(a, b));
| ~~~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | let <E>::V(..) = E::V(|a, b| Ord::cmp(&a, b));
| ~~~~~~~~~~~~~~~

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0034`.
19 changes: 19 additions & 0 deletions tests/ui/auto-traits/opaque_type_candidate_selection.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0119]: conflicting implementations of trait `Trait<_>`
--> $DIR/opaque_type_candidate_selection.rs:28:1
|
LL | impl<T> Trait<T> for T {
| ---------------------- first implementation here
...
LL | impl<T> Trait<T> for defining_scope::Alias<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

error[E0282]: type annotations needed
--> $DIR/opaque_type_candidate_selection.rs:11:20
|
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
| ^ cannot infer type

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0119, E0282.
For more information about an error, try `rustc --explain E0119`.
21 changes: 21 additions & 0 deletions tests/ui/auto-traits/opaque_type_candidate_selection.old.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0284]: type annotations needed
--> $DIR/opaque_type_candidate_selection.rs:11:20
|
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
| ^ cannot infer type
|
= note: cannot satisfy `<Alias<T> as Trait<T>>::Assoc == _`
note: required because it appears within the type `Container<Alias<T>, T>`
--> $DIR/opaque_type_candidate_selection.rs:17:8
|
LL | struct Container<T: Trait<U>, U> {
| ^^^^^^^^^
= help: unsized fn params are gated as an unstable feature
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | pub fn cast<T>(x: &Container<Alias<T>, T>) -> Container<T, T> {
| +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0284`.
7 changes: 5 additions & 2 deletions tests/ui/auto-traits/opaque_type_candidate_selection.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
//! used to ICE: #119272
//@revisions: old next
//@[next] compile-flags: -Znext-solver

//@ check-pass
//! used to ICE: #119272

#![feature(type_alias_impl_trait)]
mod defining_scope {
use super::*;
pub type Alias<T> = impl Sized;

pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
//~^ ERROR: type annotations needed
x
}
}
Expand All @@ -24,6 +26,7 @@ impl<T> Trait<T> for T {
type Assoc = Box<u32>;
}
impl<T> Trait<T> for defining_scope::Alias<T> {
//[next]~^ ERROR conflicting implementations of trait
type Assoc = usize;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ impl<F> Deref for Value<Rc<F>> {

fn main() {
let var_fn = Value::wrap();
//~^ ERROR type annotations needed for `Value<Rc<_>>`

// The combination of `Value: Wrap` obligation plus the autoderef steps
// (caused by the `Deref` impl above) actually means that the self type
// of the method fn below is constrained to be `Value<Rc<dyn Fn(?0, ?1) -> ?2>>`.
// However, that's only known to us on the error path -- we still need
// to emit an ambiguity error, though.
let _ = var_fn.clone();
//~^ ERROR: the size for values of type `dyn Fn(_, _) -> _` cannot be known
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
error[E0282]: type annotations needed for `Value<Rc<_>>`
--> $DIR/deref-ambiguity-becomes-nonambiguous.rs:31:9
error[E0277]: the size for values of type `dyn Fn(_, _) -> _` cannot be known at compilation time
--> $DIR/deref-ambiguity-becomes-nonambiguous.rs:38:13
|
LL | let var_fn = Value::wrap();
| ^^^^^^
...
LL | let _ = var_fn.clone();
| ----- type must be known at this point
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified
= help: the trait `Sized` is not implemented for `dyn Fn(_, _) -> _`, which is required by `Value<Rc<_>>: Deref`
note: required for `Value<Rc<dyn Fn(_, _) -> _>>` to implement `Deref`
--> $DIR/deref-ambiguity-becomes-nonambiguous.rs:22:9
|
LL | let var_fn: Value<Rc<_>> = Value::wrap();
| ++++++++++++++
LL | impl<F> Deref for Value<Rc<F>> {
| - ^^^^^ ^^^^^^^^^^^^
| |
| unsatisfied trait bound introduced here

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0282`.
For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | needs_foo(|x| {
| ^
...
LL | x.to_string();
| - type must be known at this point
| ------------- type must be known at this point
|
help: consider giving this closure parameter an explicit type
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/coherence/occurs-check/opaques.next.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0119]: conflicting implementations of trait `Trait<_>`
--> $DIR/opaques.rs:30:1
--> $DIR/opaques.rs:29:1
|
LL | impl<T> Trait<T> for T {
| ---------------------- first implementation here
Expand All @@ -8,7 +8,7 @@ LL | impl<T> Trait<T> for defining_scope::Alias<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

error[E0282]: type annotations needed
--> $DIR/opaques.rs:13:20
--> $DIR/opaques.rs:12:20
|
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
| ^ cannot infer type
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/coherence/occurs-check/opaques.old.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0284]: type annotations needed
--> $DIR/opaques.rs:12:20
|
LL | pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
| ^ cannot infer type
|
= note: cannot satisfy `<Alias<T> as Trait<T>>::Assoc == _`
note: required because it appears within the type `Container<Alias<T>, T>`
--> $DIR/opaques.rs:18:8
|
LL | struct Container<T: Trait<U>, U> {
| ^^^^^^^^^
= help: unsized fn params are gated as an unstable feature
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | pub fn cast<T>(x: &Container<Alias<T>, T>) -> Container<T, T> {
| +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0284`.
1 change: 0 additions & 1 deletion tests/ui/coherence/occurs-check/opaques.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// A regression test for #105787

//@[old] known-bug: #105787
//@[old] check-pass
#![feature(type_alias_impl_trait)]
mod defining_scope {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/call_method_ambiguous.next.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | let mut iter = foo(n - 1, m);
| ^^^^^^^^
LL |
LL | assert_eq!(iter.get(), 1);
| ---- type must be known at this point
| ---------- type must be known at this point
|
help: consider giving `iter` an explicit type
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | let x = my_foo();
| ^
LL |
LL | x.my_debug();
| - type must be known at this point
| ------------ type must be known at this point
|
help: consider giving `x` an explicit type
|
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
error[E0282]: type annotations needed for `&_`
--> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:14:13
--> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:15:13
|
LL | let x = &my_foo();
| ^
LL |
LL | x.my_debug();
| -------- type must be known at this point
| ------------ type must be known at this point
|
help: consider giving `x` an explicit type, where the placeholders `_` are specified
|
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@[current] check-pass

trait MyDebug {
fn my_debug(&self);
Expand All @@ -11,10 +12,8 @@ impl MyDebug for &() {

fn my_foo() -> impl std::fmt::Debug {
if false {
let x = &my_foo();
//[next]~^ ERROR: type annotations needed
let x = &my_foo(); //[next]~ ERROR: type annotations needed
x.my_debug();
//[current]~^ ERROR: no method named `my_debug`
}
()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | let x = my_foo();
| ^
LL |
LL | x.my_debug();
| - type must be known at this point
| ------------ type must be known at this point
|
help: consider giving `x` an explicit type
|
Expand All @@ -19,7 +19,7 @@ LL | let x = &my_bar();
| ^
LL |
LL | x.my_debug();
| -------- type must be known at this point
| ------------ type must be known at this point
|
help: consider giving `x` an explicit type, where the placeholders `_` are specified
|
Expand Down
13 changes: 8 additions & 5 deletions tests/ui/impl-trait/equality.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo {
0
} else {
n + sum_to(n - 1)
//~^ ERROR cannot add `impl Foo` to `u32`
//~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
}
}

Expand All @@ -32,12 +32,15 @@ trait Leak: Sized {
}
impl<T> Leak for T {
default type T = ();
default fn leak(self) -> Self::T { panic!() }
default fn leak(self) -> Self::T {
panic!()
}
}
impl Leak for i32 {
type T = i32;
fn leak(self) -> i32 { self }
fn leak(self) -> i32 {
self
}
}

fn main() {
}
fn main() {}
15 changes: 4 additions & 11 deletions tests/ui/impl-trait/equality.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,13 @@ help: change the type of the numeric literal from `u32` to `i32`
LL | 0_i32
| ~~~

error[E0277]: cannot add `impl Foo` to `u32`
error[E0284]: type annotations needed: cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`
--> $DIR/equality.rs:24:11
|
LL | n + sum_to(n - 1)
| ^ no implementation for `u32 + impl Foo`
|
= help: the trait `Add<impl Foo>` is not implemented for `u32`
= help: the following other types implement trait `Add<Rhs>`:
`&'a u32` implements `Add<u32>`
`&u32` implements `Add<&u32>`
`u32` implements `Add<&u32>`
`u32` implements `Add`
| ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == i32`

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

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0284, E0308.
For more information about an error, try `rustc --explain E0284`.
Loading
Loading