Skip to content

Commit e8b955c

Browse files
committed
Auto merge of rust-lang#123962 - oli-obk:define_opaque_types5, r=<try>
Method resolution constrains hidden types instead of rejecting method candidates Some of these are in probes and may affect inference. This allows new code to compile on stable: ```rust trait Trait {} impl Trait for u32 {} struct Bar<T>(T); impl Bar<u32> { fn foo(self) {} } fn foo(x: bool) -> Bar<impl Sized> { if x { let x = foo(false); x.foo(); //^ this used to not find the `foo` method, because while we did equate `x`'s type with possible candidates, we didn't allow opaque type inference while doing so } todo!() } ``` r? `@compiler-errors`
2 parents 5dcb678 + a6c6b29 commit e8b955c

16 files changed

+194
-57
lines changed

compiler/rustc_hir_typeck/src/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
637637
return;
638638
};
639639

640-
let pick = self.confirm_method(
640+
let pick = self.confirm_method_for_diagnostic(
641641
call_expr.span,
642642
callee_expr,
643643
call_expr,

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ fn ham() -> Foo {
2727

2828
fn oof(_: Foo) -> impl std::fmt::Debug {
2929
let mut bar = ham();
30-
let func = bar.next().unwrap();
31-
return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type
30+
let func = bar.next().unwrap(); //~ ERROR: type annotations needed
31+
return func(&"oof");
3232
}
3333

3434
fn main() {
+9-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
error: opaque type's hidden type cannot be another opaque type from the same scope
2-
--> $DIR/issue-70877.rs:31:12
1+
error[E0282]: type annotations needed
2+
--> $DIR/issue-70877.rs:30:9
33
|
4+
LL | let func = bar.next().unwrap();
5+
| ^^^^
46
LL | return func(&"oof");
5-
| ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope
7+
| ------------ type must be known at this point
68
|
7-
note: opaque type whose hidden type is being assigned
8-
--> $DIR/issue-70877.rs:28:19
9+
help: consider giving `func` an explicit type
910
|
10-
LL | fn oof(_: Foo) -> impl std::fmt::Debug {
11-
| ^^^^^^^^^^^^^^^^^^^^
12-
note: opaque type being used as hidden type
13-
--> $DIR/issue-70877.rs:4:15
14-
|
15-
LL | type FooRet = impl std::fmt::Debug;
16-
| ^^^^^^^^^^^^^^^^^^^^
11+
LL | let func: /* Type */ = bar.next().unwrap();
12+
| ++++++++++++
1713

1814
error: aborting due to 1 previous error
1915

16+
For more information about this error, try `rustc --explain E0282`.
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ check-pass
2+
3+
trait Trait {}
4+
5+
impl Trait for u32 {}
6+
7+
struct Bar<T>(T);
8+
9+
impl Bar<u32> {
10+
fn foo(self) {}
11+
}
12+
13+
fn foo(x: bool) -> Bar<impl Sized> {
14+
if x {
15+
let x = foo(false);
16+
x.foo();
17+
}
18+
todo!()
19+
}
20+
21+
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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![feature(type_alias_impl_trait)]
2+
3+
type Foo = impl Sized;
4+
5+
struct Bar<T>(T);
6+
7+
impl Bar<Foo> {
8+
fn bar(self) {}
9+
}
10+
11+
impl Bar<u32> {
12+
fn foo(self) {
13+
self.bar()
14+
//~^ ERROR: no method named `bar`
15+
}
16+
}
17+
18+
fn foo() -> Foo {
19+
42_u32
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
2+
--> $DIR/method_resolution.rs:13:14
3+
|
4+
LL | struct Bar<T>(T);
5+
| ------------- method `bar` not found for this struct
6+
...
7+
LL | self.bar()
8+
| ^^^ method not found in `Bar<u32>`
9+
|
10+
= note: the method was found for
11+
- `Bar<Foo>`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0599`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![feature(type_alias_impl_trait)]
2+
//@ check-pass
3+
4+
type Foo = impl Sized;
5+
6+
struct Bar<T>(T);
7+
8+
impl Bar<Foo> {
9+
fn bar(self) {
10+
self.foo()
11+
}
12+
}
13+
14+
impl Bar<u32> {
15+
fn foo(self) {}
16+
}
17+
18+
fn foo() -> Foo {
19+
42_u32
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![feature(type_alias_impl_trait, arbitrary_self_types)]
2+
3+
type Foo = impl Copy;
4+
5+
#[derive(Copy, Clone)]
6+
struct Bar<T>(T);
7+
8+
impl Bar<Foo> {
9+
fn bar(self: Bar<u32>) {
10+
//~^ ERROR: invalid `self` parameter
11+
self.foo()
12+
}
13+
fn baz(self: &Bar<u32>) {
14+
//~^ ERROR: invalid `self` parameter
15+
self.foo()
16+
}
17+
}
18+
19+
impl Bar<u32> {
20+
fn foo(self) {}
21+
}
22+
23+
fn foo() -> Foo {
24+
42_u32
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0307]: invalid `self` parameter type: Bar<u32>
2+
--> $DIR/method_resolution3.rs:9:18
3+
|
4+
LL | fn bar(self: Bar<u32>) {
5+
| ^^^^^^^^
6+
|
7+
= note: type of `self` must be `Self` or a type that dereferences to it
8+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
9+
10+
error[E0307]: invalid `self` parameter type: &Bar<u32>
11+
--> $DIR/method_resolution3.rs:13:18
12+
|
13+
LL | fn baz(self: &Bar<u32>) {
14+
| ^^^^^^^^^
15+
|
16+
= note: type of `self` must be `Self` or a type that dereferences to it
17+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0307`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![feature(type_alias_impl_trait, arbitrary_self_types)]
2+
3+
type Foo = impl Copy;
4+
5+
#[derive(Copy, Clone)]
6+
struct Bar<T>(T);
7+
8+
impl Bar<Foo> {
9+
fn bar(self) {}
10+
}
11+
12+
impl Bar<u32> {
13+
fn foo(self: Bar<Foo>) {
14+
//~^ ERROR: invalid `self` parameter
15+
self.bar()
16+
}
17+
fn foomp(self: &Bar<Foo>) {
18+
//~^ ERROR: invalid `self` parameter
19+
self.bar()
20+
}
21+
}
22+
23+
fn foo() -> Foo {
24+
42_u32
25+
}
26+
27+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0307]: invalid `self` parameter type: Bar<Foo>
2+
--> $DIR/method_resolution4.rs:13:18
3+
|
4+
LL | fn foo(self: Bar<Foo>) {
5+
| ^^^^^^^^
6+
|
7+
= note: type of `self` must be `Self` or a type that dereferences to it
8+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
9+
10+
error[E0307]: invalid `self` parameter type: &Bar<Foo>
11+
--> $DIR/method_resolution4.rs:17:20
12+
|
13+
LL | fn foomp(self: &Bar<Foo>) {
14+
| ^^^^^^^^^
15+
|
16+
= note: type of `self` must be `Self` or a type that dereferences to it
17+
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0307`.

0 commit comments

Comments
 (0)