Skip to content

Commit 7147449

Browse files
Remove default methods for RPITITs
1 parent 8574c42 commit 7147449

23 files changed

+226
-51
lines changed

compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl

+7
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,10 @@ hir_analysis_linkage_type =
124124
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
125125
.label = deref recursion limit reached
126126
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
127+
128+
hir_analysis_default_async_fn_not_allowed = default body not allowed on async trait method
129+
.remove_label = remove this body, or move it to an impl instead
130+
131+
hir_analysis_default_rpitit_fn_not_allowed = default body not allowed on trait method with `impl Trait`
132+
.label = this `impl Trait`
133+
.remove_label = remove this body, or move it to an impl instead

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+58
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::autoderef::Autoderef;
22
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
3+
use crate::errors;
34

45
use hir::def::DefKind;
56
use rustc_ast as ast;
@@ -15,6 +16,7 @@ use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
1516
use rustc_middle::mir::ConstraintCategory;
1617
use rustc_middle::ty::query::Providers;
1718
use rustc_middle::ty::trait_def::TraitSpecializationKind;
19+
use rustc_middle::ty::visit::TypeVisitableExt;
1820
use rustc_middle::ty::{
1921
self, ir::TypeVisitor, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
2022
TypeSuperVisitable,
@@ -278,6 +280,62 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
278280
check_object_unsafe_self_trait_by_name(tcx, trait_item);
279281
check_associated_item(tcx, def_id, span, method_sig);
280282

283+
struct FindImplTraitInTrait<'tcx>(TyCtxt<'tcx>);
284+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindImplTraitInTrait<'tcx> {
285+
type BreakTy = DefId;
286+
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
287+
if let ty::Alias(ty::Projection, alias_ty) = *ty.kind()
288+
&& self.0.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder
289+
{
290+
return ControlFlow::Break(alias_ty.def_id);
291+
} else if ty.has_projections() {
292+
ty.super_visit_with(self)
293+
} else {
294+
ControlFlow::Continue(())
295+
}
296+
}
297+
}
298+
if let hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)) = trait_item.kind
299+
&& let ControlFlow::Break(def_id) = tcx
300+
.fn_sig(def_id)
301+
.skip_binder()
302+
.output()
303+
.visit_with(&mut FindImplTraitInTrait(tcx))
304+
{
305+
let hir::ItemKind::OpaqueTy(opaque) = &tcx.hir().expect_item(def_id.expect_local()).kind else {
306+
bug!();
307+
};
308+
match opaque.origin {
309+
hir::OpaqueTyOrigin::FnReturn(_) => {
310+
let mut diag = tcx.sess.create_err(
311+
errors::DefaultRpititMethodNotAllowed::ReturnPositionImplTrait {
312+
body_span: tcx.hir().span(body_id.hir_id).shrink_to_lo(),
313+
rpitit_span: tcx.def_span(def_id),
314+
},
315+
);
316+
if tcx.features().return_position_impl_trait_in_trait {
317+
diag.emit();
318+
} else {
319+
diag.delay_as_bug();
320+
}
321+
}
322+
hir::OpaqueTyOrigin::AsyncFn(_) => {
323+
let mut diag =
324+
tcx.sess.create_err(errors::DefaultRpititMethodNotAllowed::AsyncFn {
325+
body_span: tcx.hir().span(body_id.hir_id).shrink_to_lo(),
326+
});
327+
if tcx.features().async_fn_in_trait {
328+
diag.emit();
329+
} else {
330+
diag.delay_as_bug();
331+
}
332+
}
333+
hir::OpaqueTyOrigin::TyAlias => {
334+
// TAIT comes from alias expansion, so it's fine.
335+
}
336+
}
337+
}
338+
281339
let encl_trait_def_id = tcx.local_parent(def_id);
282340
let encl_trait = tcx.hir().expect_item(encl_trait_def_id);
283341
let encl_trait_def_id = encl_trait.owner_id.to_def_id();

compiler/rustc_hir_analysis/src/errors.rs

+18
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,21 @@ pub struct AutoDerefReachedRecursionLimit<'a> {
312312
pub suggested_limit: rustc_session::Limit,
313313
pub crate_name: Symbol,
314314
}
315+
316+
#[derive(Diagnostic)]
317+
pub enum DefaultRpititMethodNotAllowed {
318+
#[diag(hir_analysis_default_async_fn_not_allowed)]
319+
AsyncFn {
320+
#[primary_span]
321+
#[label(remove_label)]
322+
body_span: Span,
323+
},
324+
#[diag(hir_analysis_default_rpitit_fn_not_allowed)]
325+
ReturnPositionImplTrait {
326+
#[primary_span]
327+
#[label(remove_label)]
328+
body_span: Span,
329+
#[label]
330+
rpitit_span: Span,
331+
},
332+
}

tests/ui/async-await/async-trait-fn.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// edition:2018
22
trait T {
33
async fn foo() {} //~ ERROR functions in traits cannot be declared `async`
4+
//~^ ERROR mismatched types
45
async fn bar(&self) {} //~ ERROR functions in traits cannot be declared `async`
6+
//~^ ERROR mismatched types
57
async fn baz() { //~ ERROR functions in traits cannot be declared `async`
8+
//~^ ERROR mismatched types
69
// Nested item must not ICE.
710
fn a() {}
811
}

tests/ui/async-await/async-trait-fn.stderr

+52-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ LL | async fn foo() {}
1212
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
1313

1414
error[E0706]: functions in traits cannot be declared `async`
15-
--> $DIR/async-trait-fn.rs:4:5
15+
--> $DIR/async-trait-fn.rs:5:5
1616
|
1717
LL | async fn bar(&self) {}
1818
| -----^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL | async fn bar(&self) {}
2525
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
2626

2727
error[E0706]: functions in traits cannot be declared `async`
28-
--> $DIR/async-trait-fn.rs:5:5
28+
--> $DIR/async-trait-fn.rs:7:5
2929
|
3030
LL | async fn baz() {
3131
| -----^^^^^^^^^
@@ -37,6 +37,54 @@ LL | async fn baz() {
3737
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
3838
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
3939

40-
error: aborting due to 3 previous errors
40+
error[E0308]: mismatched types
41+
--> $DIR/async-trait-fn.rs:3:20
42+
|
43+
LL | async fn foo() {}
44+
| ^^
45+
| |
46+
| expected associated type, found `async fn` body
47+
| arguments to this function are incorrect
48+
|
49+
= note: expected associated type `impl Future<Output = ()>`
50+
found `async fn` body `[async fn body@$DIR/async-trait-fn.rs:3:20: 3:22]`
51+
note: function defined here
52+
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
53+
54+
error[E0308]: mismatched types
55+
--> $DIR/async-trait-fn.rs:5:25
56+
|
57+
LL | async fn bar(&self) {}
58+
| ^^
59+
| |
60+
| expected associated type, found `async fn` body
61+
| arguments to this function are incorrect
62+
|
63+
= note: expected associated type `impl Future<Output = ()>`
64+
found `async fn` body `[async fn body@$DIR/async-trait-fn.rs:5:25: 5:27]`
65+
note: function defined here
66+
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
67+
68+
error[E0308]: mismatched types
69+
--> $DIR/async-trait-fn.rs:7:20
70+
|
71+
LL | async fn baz() {
72+
| ____________________-
73+
LL | |
74+
LL | | // Nested item must not ICE.
75+
LL | | fn a() {}
76+
LL | | }
77+
| | ^
78+
| | |
79+
| |_____expected associated type, found `async fn` body
80+
| arguments to this function are incorrect
81+
|
82+
= note: expected associated type `impl Future<Output = ()>`
83+
found `async fn` body `[async fn body@$DIR/async-trait-fn.rs:7:20: 11:6]`
84+
note: function defined here
85+
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
86+
87+
error: aborting due to 6 previous errors
4188

42-
For more information about this error, try `rustc --explain E0706`.
89+
Some errors have detailed explanations: E0308, E0706.
90+
For more information about an error, try `rustc --explain E0308`.

tests/ui/async-await/edition-deny-async-fns-2015.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impl Foo {
1717
trait Bar {
1818
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
1919
//~^ ERROR functions in traits cannot be declared `async`
20+
//~| ERROR mismatched types
2021
}
2122

2223
fn main() {

tests/ui/async-await/edition-deny-async-fns-2015.stderr

+20-6
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ LL | async fn foo() {}
5353
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
5454

5555
error[E0670]: `async fn` is not permitted in Rust 2015
56-
--> $DIR/edition-deny-async-fns-2015.rs:36:9
56+
--> $DIR/edition-deny-async-fns-2015.rs:37:9
5757
|
5858
LL | async fn bar() {}
5959
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -62,7 +62,7 @@ LL | async fn bar() {}
6262
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
6363

6464
error[E0670]: `async fn` is not permitted in Rust 2015
65-
--> $DIR/edition-deny-async-fns-2015.rs:26:9
65+
--> $DIR/edition-deny-async-fns-2015.rs:27:9
6666
|
6767
LL | async fn foo() {}
6868
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -71,7 +71,7 @@ LL | async fn foo() {}
7171
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
7272

7373
error[E0670]: `async fn` is not permitted in Rust 2015
74-
--> $DIR/edition-deny-async-fns-2015.rs:31:13
74+
--> $DIR/edition-deny-async-fns-2015.rs:32:13
7575
|
7676
LL | async fn bar() {}
7777
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
@@ -92,7 +92,21 @@ LL | async fn foo() {}
9292
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
9393
= help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
9494

95-
error: aborting due to 10 previous errors
95+
error[E0308]: mismatched types
96+
--> $DIR/edition-deny-async-fns-2015.rs:18:20
97+
|
98+
LL | async fn foo() {}
99+
| ^^
100+
| |
101+
| expected associated type, found `async fn` body
102+
| arguments to this function are incorrect
103+
|
104+
= note: expected associated type `impl Future<Output = ()>`
105+
found `async fn` body `[async fn body@$DIR/edition-deny-async-fns-2015.rs:18:20: 18:22]`
106+
note: function defined here
107+
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
108+
109+
error: aborting due to 11 previous errors
96110

97-
Some errors have detailed explanations: E0670, E0706.
98-
For more information about an error, try `rustc --explain E0670`.
111+
Some errors have detailed explanations: E0308, E0670, E0706.
112+
For more information about an error, try `rustc --explain E0308`.

tests/ui/async-await/in-trait/return-type-suggestion.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
// edition: 2021
2+
// known-bug: #108142
23

34
#![feature(async_fn_in_trait)]
4-
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
55

66
trait A {
77
async fn e() {
88
Ok(())
9-
//~^ ERROR mismatched types
10-
//~| HELP consider using a semicolon here
119
}
1210
}
1311

Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/return-type-suggestion.rs:3:12
2+
--> $DIR/return-type-suggestion.rs:4:12
33
|
44
LL | #![feature(async_fn_in_trait)]
55
| ^^^^^^^^^^^^^^^^^
66
|
77
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error[E0308]: mismatched types
11-
--> $DIR/return-type-suggestion.rs:8:9
10+
error: default body not allowed on async trait method
11+
--> $DIR/return-type-suggestion.rs:7:18
1212
|
13-
LL | Ok(())
14-
| ^^^^^^- help: consider using a semicolon here: `;`
15-
| |
16-
| expected `()`, found `Result<(), _>`
17-
|
18-
= note: expected unit type `()`
19-
found enum `Result<(), _>`
13+
LL | async fn e() {
14+
| ^ remove this body, or move it to an impl instead
2015

2116
error: aborting due to previous error; 1 warning emitted
2217

23-
For more information about this error, try `rustc --explain E0308`.

tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// check-pass
1+
// known-bug: #108142
22

33
#![feature(return_position_impl_trait_in_trait)]
4-
//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete
54

65
struct TestA {}
76
struct TestB {}

tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,13 @@ LL | #![feature(return_position_impl_trait_in_trait)]
77
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
warning: 1 warning emitted
10+
error: default body not allowed on trait method with `impl Trait`
11+
--> $DIR/box-coerce-span-in-default.rs:37:68
12+
|
13+
LL | fn test_func(&self, func: &str) -> impl TestTrait<Output = ()> {
14+
| --------------------------- ^ remove this body, or move it to an impl instead
15+
| |
16+
| this `impl Trait`
17+
18+
error: aborting due to previous error; 1 warning emitted
1119

tests/ui/impl-trait/in-trait/default-body-type-err-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// edition:2021
2+
// known-bug: #108142
23

34
#![allow(incomplete_features)]
45
#![feature(async_fn_in_trait)]
56

67
pub trait Foo {
78
async fn woopsie_async(&self) -> String {
89
42
9-
//~^ ERROR mismatched types
1010
}
1111
}
1212

Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/default-body-type-err-2.rs:8:9
1+
error: default body not allowed on async trait method
2+
--> $DIR/default-body-type-err-2.rs:8:45
33
|
4-
LL | 42
5-
| ^^- help: try using a conversion method: `.to_string()`
6-
| |
7-
| expected `String`, found integer
4+
LL | async fn woopsie_async(&self) -> String {
5+
| ^ remove this body, or move it to an impl instead
86

97
error: aborting due to previous error
108

11-
For more information about this error, try `rustc --explain E0308`.

tests/ui/impl-trait/in-trait/default-body-type-err.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
// known-bug: #108142
2+
13
#![allow(incomplete_features)]
24
#![feature(return_position_impl_trait_in_trait)]
35

46
use std::ops::Deref;
57

68
pub trait Foo {
79
fn lol(&self) -> impl Deref<Target = String> {
8-
//~^ type mismatch resolving `<&i32 as Deref>::Target == String`
910
&1i32
1011
}
1112
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
2-
--> $DIR/default-body-type-err.rs:7:22
1+
error: default body not allowed on trait method with `impl Trait`
2+
--> $DIR/default-body-type-err.rs:9:50
33
|
44
LL | fn lol(&self) -> impl Deref<Target = String> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
6-
LL |
7-
LL | &1i32
8-
| ----- return type was inferred to be `&i32` here
5+
| --------------------------- ^ remove this body, or move it to an impl instead
6+
| |
7+
| this `impl Trait`
98

109
error: aborting due to previous error
1110

12-
For more information about this error, try `rustc --explain E0271`.

tests/ui/impl-trait/in-trait/default-body-with-rpit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// check-pass
21
// edition:2021
2+
// known-bug: #108142
33

44
#![feature(async_fn_in_trait, return_position_impl_trait_in_trait)]
55
#![allow(incomplete_features)]

0 commit comments

Comments
 (0)