Skip to content

Commit af980d5

Browse files
committed
Method resolution constrains hidden types instead of rejecting method candidates
1 parent 9df4a9d commit af980d5

22 files changed

+87
-132
lines changed

compiler/rustc_data_structures/src/obligation_forest/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,10 @@ impl<O: ForestObligation> ObligationForest<O> {
359359
Entry::Vacant(v) => {
360360
let obligation_tree_id = match parent {
361361
Some(parent_index) => self.nodes[parent_index].obligation_tree_id,
362-
None => self.obligation_tree_id_generator.next().unwrap(),
362+
// FIXME(type_alias_impl_trait): with `#[defines]` attributes required to define hidden
363+
// types we can convert this back to a `next` method call, as this function shouldn't be
364+
// defining a hidden type anyway.
365+
None => Iterator::next(&mut self.obligation_tree_id_generator).unwrap(),
363366
};
364367

365368
let already_failed = parent.is_some()

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1448,7 +1448,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14481448
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
14491449
let self_ty = self.normalize(span, self_ty);
14501450
match self.at(&self.misc(span), self.param_env).eq(
1451-
DefineOpaqueTypes::No,
1451+
DefineOpaqueTypes::Yes,
14521452
impl_ty,
14531453
self_ty,
14541454
) {

compiler/rustc_hir_typeck/src/method/confirm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
499499
args,
500500
})),
501501
);
502-
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) {
502+
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) {
503503
Ok(InferOk { obligations, value: () }) => {
504504
self.register_predicates(obligations);
505505
}

compiler/rustc_hir_typeck/src/method/probe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14881488
self.probe(|_| {
14891489
// First check that the self type can be related.
14901490
let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup(
1491-
DefineOpaqueTypes::No,
1491+
DefineOpaqueTypes::Yes,
14921492
probe.xform_self_ty,
14931493
self_ty,
14941494
) {

tests/ui/impl-trait/issues/issue-70877.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ fn ham() -> Foo {
2727

2828
fn oof(_: Foo) -> impl std::fmt::Debug {
2929
let mut bar = ham();
30-
let func = bar.next().unwrap();
30+
// Need to UFC invoke `Iterator::next`,
31+
// as otherwise the hidden type gets constrained to `&mut _`
32+
let func = Iterator::next(&mut bar).unwrap();
3133
return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
3234
}
3335

tests/ui/impl-trait/issues/issue-70877.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: opaque type's hidden type cannot be another opaque type from the same scope
2-
--> $DIR/issue-70877.rs:31:12
2+
--> $DIR/issue-70877.rs:33:12
33
|
44
LL | return func(&"oof");
55
| ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope

tests/ui/impl-trait/method-resolution.current.stderr

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
1-
error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
2-
--> $DIR/method-resolution.rs:23:11
1+
error[E0599]: no method named `foo` found for struct `Bar` in the current scope
2+
--> $DIR/method-resolution.rs:22:11
33
|
44
LL | struct Bar<T>(T);
5-
| ------------- method `bar` not found for this struct
5+
| ------------- method `foo` not found for this struct
66
...
7-
LL | x.bar();
7+
LL | x.foo();
88
| ^^^ method not found in `Bar<impl Sized>`
9-
|
10-
= note: the method was found for
11-
- `Bar<u32>`
129

1310
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
14-
--> $DIR/method-resolution.rs:19:24
11+
--> $DIR/method-resolution.rs:18:24
1512
|
1613
LL | fn foo(x: bool) -> Bar<impl Sized> {
1714
| ^^^^^^^^^^
1815
|
1916
note: ...which requires type-checking `foo`...
20-
--> $DIR/method-resolution.rs:23:9
17+
--> $DIR/method-resolution.rs:22:9
2118
|
22-
LL | x.bar();
19+
LL | x.foo();
2320
| ^
2421
= note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
2522
= note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
2623
note: cycle used when computing type of `foo::{opaque#0}`
27-
--> $DIR/method-resolution.rs:19:24
24+
--> $DIR/method-resolution.rs:18:24
2825
|
2926
LL | fn foo(x: bool) -> Bar<impl Sized> {
3027
| ^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0599]: no method named `foo` found for struct `Bar` in the current scope
2+
--> $DIR/method-resolution.rs:22:11
3+
|
4+
LL | struct Bar<T>(T);
5+
| ------------- method `foo` not found for this struct
6+
...
7+
LL | x.foo();
8+
| ^^^ method not found in `Bar<_>`
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0599`.

tests/ui/impl-trait/method-resolution.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
55
//@ revisions: current next
66
//@[next] compile-flags: -Znext-solver
7-
//@[next] check-pass
87

98
trait Trait {}
109

@@ -17,11 +16,11 @@ impl Bar<u32> {
1716
}
1817

1918
fn foo(x: bool) -> Bar<impl Sized> {
20-
//[current]~^ ERROR: cycle detected
19+
//[current]~^ ERROR: cycle
2120
if x {
2221
let x = foo(false);
23-
x.bar();
24-
//[current]~^ ERROR: no method named `bar` found
22+
x.foo();
23+
//~^ ERROR: no method named `foo` found
2524
}
2625
todo!()
2726
}

tests/ui/impl-trait/method-resolution3.current.stderr

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
error[E0599]: no method named `bar` found for struct `Bar<impl Sized>` in the current scope
1+
error[E0599]: no method named `foo` found for struct `Bar` in the current scope
22
--> $DIR/method-resolution3.rs:22:11
33
|
44
LL | struct Bar<T>(T);
5-
| ------------- method `bar` not found for this struct
5+
| ------------- method `foo` not found for this struct
66
...
7-
LL | x.bar();
7+
LL | x.foo();
88
| ^^^ method not found in `Bar<impl Sized>`
9-
|
10-
= note: the method was found for
11-
- `Bar<i32>`
12-
- `Bar<u32>`
139

1410
error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}`
1511
--> $DIR/method-resolution3.rs:18:24
@@ -20,7 +16,7 @@ LL | fn foo(x: bool) -> Bar<impl Sized> {
2016
note: ...which requires type-checking `foo`...
2117
--> $DIR/method-resolution3.rs:22:9
2218
|
23-
LL | x.bar();
19+
LL | x.foo();
2420
| ^
2521
= note: ...which requires evaluating trait selection obligation `Bar<foo::{opaque#0}>: core::marker::Unpin`...
2622
= note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
1-
error[E0034]: multiple applicable items in scope
1+
error[E0599]: no method named `foo` found for struct `Bar` in the current scope
22
--> $DIR/method-resolution3.rs:22:11
33
|
4-
LL | x.bar();
5-
| ^^^ multiple `bar` found
6-
|
7-
note: candidate #1 is defined in an impl for the type `Bar<i32>`
8-
--> $DIR/method-resolution3.rs:15:5
9-
|
10-
LL | fn bar(self) {}
11-
| ^^^^^^^^^^^^
12-
note: candidate #2 is defined in an impl for the type `Bar<u32>`
13-
--> $DIR/method-resolution3.rs:11:5
14-
|
15-
LL | fn bar(self) {}
16-
| ^^^^^^^^^^^^
4+
LL | struct Bar<T>(T);
5+
| ------------- method `foo` not found for this struct
6+
...
7+
LL | x.foo();
8+
| ^^^ method not found in `Bar<_>`
179

1810
error: aborting due to 1 previous error
1911

20-
For more information about this error, try `rustc --explain E0034`.
12+
For more information about this error, try `rustc --explain E0599`.

tests/ui/impl-trait/method-resolution3.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ fn foo(x: bool) -> Bar<impl Sized> {
1919
//[current]~^ ERROR: cycle
2020
if x {
2121
let x = foo(false);
22-
x.bar();
23-
//[current]~^ ERROR: no method named `bar`
24-
//[next]~^^ ERROR: multiple applicable items in scope
22+
x.foo();
23+
//~^ ERROR: no method named `foo` found
2524
}
2625
todo!()
2726
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/method-resolution4.rs:15:5
3+
|
4+
LL | std::iter::empty()
5+
| ^^^^^^^^^^^^^^^^^^ expected `&mut _`, found `Empty<_>`
6+
|
7+
= note: expected mutable reference `&mut _`
8+
found struct `std::iter::Empty<_>`
9+
help: consider mutably borrowing here
10+
|
11+
LL | &mut std::iter::empty()
12+
| ++++
13+
14+
error: aborting due to 1 previous error
15+
16+
For more information about this error, try `rustc --explain E0308`.

tests/ui/impl-trait/method-resolution4.next.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0282]: type annotations needed
2-
--> $DIR/method-resolution4.rs:13:9
2+
--> $DIR/method-resolution4.rs:12:9
33
|
44
LL | foo(false).next().unwrap();
55
| ^^^^^^^^^^ cannot infer type
66

77
error[E0308]: mismatched types
8-
--> $DIR/method-resolution4.rs:16:5
8+
--> $DIR/method-resolution4.rs:15:5
99
|
1010
LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
1111
| ------------------------ the expected opaque type

tests/ui/impl-trait/method-resolution4.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
//! variable, but get a type mismatch when comparing `&mut _` with
55
//! `std::iter::Empty`.
66
7-
//@[current] check-pass
87
//@ revisions: current next
98
//@[next] compile-flags: -Znext-solver
109

@@ -14,7 +13,7 @@ fn foo(b: bool) -> impl Iterator<Item = ()> {
1413
//[next]~^ type annotations needed
1514
}
1615
std::iter::empty()
17-
//[next]~^ mismatched types
16+
//~^ mismatched types
1817
}
1918

2019
fn main() {}

tests/ui/methods/opaque_param_in_ufc.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#![feature(type_alias_impl_trait)]
2+
3+
//@ check-pass
4+
25
struct Foo<T>(T);
36

47
impl Foo<u32> {
@@ -15,14 +18,11 @@ fn bar() -> Bar {
1518
impl Foo<Bar> {
1619
fn foo() -> Bar {
1720
Self::method();
18-
//~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
1921
Foo::<Bar>::method();
20-
//~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
2122
let x = Foo(bar());
2223
Foo::method2(x);
2324
let x = Self(bar());
2425
Self::method2(x);
25-
//~^ ERROR: no function or associated item named `method2` found for struct `Foo<Bar>`
2626
todo!()
2727
}
2828
}

tests/ui/methods/opaque_param_in_ufc.stderr

-36
This file was deleted.

tests/ui/type-alias-impl-trait/method_resolution2.current.stderr

-36
This file was deleted.

tests/ui/type-alias-impl-trait/method_resolution2.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@
33
44
//@ revisions: current next
55
//@[next] compile-flags: -Znext-solver
6-
//@[next] check-pass
6+
//@ check-pass
77

88
#![feature(type_alias_impl_trait)]
99

1010
type Foo = impl Sized;
11-
//[current]~^ ERROR: cycle
1211

1312
struct Bar<T>(T);
1413

1514
impl Bar<Foo> {
1615
fn bar(self) {
1716
self.foo()
18-
//[current]~^ ERROR: no method named `foo`
1917
}
2018
}
2119

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0284]: type annotations needed
2+
--> $DIR/method_resolution_trait_method_from_opaque.rs:25:18
3+
|
4+
LL | self.bar.next().unwrap();
5+
| ^^^^
6+
|
7+
= note: cannot satisfy `<_ as Iterator>::Item == _`
8+
help: try using a fully qualified path to specify the expected types
9+
|
10+
LL | <_ as Iterator>::next(self.bar).unwrap();
11+
| ++++++++++++++++++++++ ~
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0284`.

tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0282]: type annotations needed
2-
--> $DIR/method_resolution_trait_method_from_opaque.rs:26:9
2+
--> $DIR/method_resolution_trait_method_from_opaque.rs:25:9
33
|
44
LL | self.bar.next().unwrap();
55
| ^^^^^^^^ cannot infer type

0 commit comments

Comments
 (0)