Skip to content

Commit 67d984b

Browse files
Stabilize RTN
1 parent 7a08d03 commit 67d984b

File tree

95 files changed

+158
-407
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+158
-407
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -954,17 +954,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
954954
}
955955
}
956956
};
957-
let mut err = self.dcx().create_err(err);
958-
if !self.tcx.features().return_type_notation()
959-
&& self.tcx.sess.is_nightly_build()
960-
{
961-
add_feature_diagnostics(
962-
&mut err,
963-
&self.tcx.sess,
964-
sym::return_type_notation,
965-
);
966-
}
967-
err.emit();
957+
self.dcx().emit_err(err);
968958
GenericArgsCtor {
969959
args: Default::default(),
970960
constraints: &[],

compiler/rustc_ast_lowering/src/path.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_hir::GenericArg;
66
use rustc_hir::def::{DefKind, PartialRes, Res};
77
use rustc_hir::def_id::DefId;
88
use rustc_middle::span_bug;
9-
use rustc_session::parse::add_feature_diagnostics;
109
use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
1110
use smallvec::{SmallVec, smallvec};
1211
use tracing::{debug, instrument};
@@ -287,17 +286,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
287286
}
288287
}
289288
};
290-
let mut err = self.dcx().create_err(err);
291-
if !self.tcx.features().return_type_notation()
292-
&& self.tcx.sess.is_nightly_build()
293-
{
294-
add_feature_diagnostics(
295-
&mut err,
296-
&self.tcx.sess,
297-
sym::return_type_notation,
298-
);
299-
}
300-
err.emit();
289+
self.dcx().emit_err(err);
301290
(
302291
GenericArgsCtor {
303292
args: Default::default(),

compiler/rustc_ast_passes/src/feature_gate.rs

-1
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
498498
gate_all!(postfix_match, "postfix match is experimental");
499499
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
500500
gate_all!(global_registration, "global registration is experimental");
501-
gate_all!(return_type_notation, "return type notation is experimental");
502501
gate_all!(pin_ergonomics, "pinned reference syntax is experimental");
503502
gate_all!(unsafe_fields, "`unsafe` fields are experimental");
504503
gate_all!(unsafe_binders, "unsafe binder types are experimental");

compiler/rustc_feature/src/accepted.rs

+2
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ declare_features! (
364364
(accepted, result_ffi_guarantees, "1.84.0", Some(110503)),
365365
/// Allows return-position `impl Trait` in traits.
366366
(accepted, return_position_impl_trait_in_trait, "1.75.0", Some(91611)),
367+
/// Allows bounding the return type of AFIT/RPITIT.
368+
(accepted, return_type_notation, "CURRENT_RUSTC_VERSION", Some(109417)),
367369
/// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
368370
(accepted, rvalue_static_promotion, "1.21.0", Some(38865)),
369371
/// Allows `Self` in type definitions (RFC 2300).

compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,6 @@ declare_features! (
616616
(incomplete, repr128, "1.16.0", Some(56071)),
617617
/// Allows `repr(simd)` and importing the various simd intrinsics.
618618
(unstable, repr_simd, "1.4.0", Some(27731)),
619-
/// Allows bounding the return type of AFIT/RPITIT.
620-
(unstable, return_type_notation, "1.70.0", Some(109417)),
621619
/// Allows `extern "rust-cold"`.
622620
(unstable, rust_cold_cc, "1.63.0", Some(97544)),
623621
/// Allows use of x86 SHA512, SM3 and SM4 target-features and intrinsics

compiler/rustc_hir_analysis/src/check/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,11 @@ fn fn_sig_suggestion<'tcx>(
475475
""
476476
};
477477

478-
let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
478+
let output = if !output.is_unit() {
479+
with_types_for_signature!(format!(" -> {output}"))
480+
} else {
481+
String::new()
482+
};
479483

480484
let safety = sig.safety.prefix_str();
481485
let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);

compiler/rustc_lint/src/async_fn_in_trait.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait {
9595
&& let hir::IsAsync::Async(async_span) = sig.header.asyncness
9696
{
9797
// RTN can be used to bound `async fn` in traits in a better way than "always"
98-
if cx.tcx.features().return_type_notation() {
98+
// TODO:
99+
if true {
99100
return;
100101
}
101102

compiler/rustc_middle/src/ty/print/pretty.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1339,15 +1339,17 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
13391339
def_id: DefId,
13401340
args: ty::GenericArgsRef<'tcx>,
13411341
) -> Result<(), PrintError> {
1342-
let fn_args = if self.tcx().features().return_type_notation()
1343-
&& let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
1344-
self.tcx().opt_rpitit_info(def_id)
1342+
let fn_args = if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
1343+
self.tcx().opt_rpitit_info(def_id)
13451344
&& let ty::Alias(_, alias_ty) =
13461345
self.tcx().fn_sig(fn_def_id).skip_binder().output().skip_binder().kind()
13471346
&& alias_ty.def_id == def_id
13481347
&& let generics = self.tcx().generics_of(fn_def_id)
13491348
// FIXME(return_type_notation): We only support lifetime params for now.
1350-
&& generics.own_params.iter().all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
1349+
&& generics
1350+
.own_params
1351+
.iter()
1352+
.all(|param| matches!(param.kind, ty::GenericParamDefKind::Lifetime))
13511353
{
13521354
let num_args = generics.count();
13531355
Some((fn_def_id, &args[..num_args]))

compiler/rustc_parse/src/parser/path.rs

-2
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,6 @@ impl<'a> Parser<'a> {
377377
self.expect(exp!(CloseParen))?;
378378
let span = lo.to(self.prev_token.span);
379379

380-
self.psess.gated_spans.gate(sym::return_type_notation, span);
381-
382380
let prev_lo = self.prev_token.span.shrink_to_hi();
383381
if self.eat_noexpect(&token::RArrow) {
384382
let lo = self.prev_token.span;

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

-1
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
524524
}
525525

526526
self.explain_hrtb_projection(&mut err, leaf_trait_predicate, obligation.param_env, &obligation.cause);
527-
self.suggest_desugaring_async_fn_in_trait(&mut err, main_trait_predicate);
528527

529528
// Return early if the trait is Debug or Display and the invocation
530529
// originates within a standard library macro, because the output

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+1-87
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,7 @@ pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
137137
if hir_generics.where_clause_span.from_expansion()
138138
|| hir_generics.where_clause_span.desugaring_kind().is_some()
139139
|| projection.is_some_and(|projection| {
140-
(tcx.is_impl_trait_in_trait(projection.def_id)
141-
&& !tcx.features().return_type_notation())
142-
|| tcx.lookup_stability(projection.def_id).is_some_and(|stab| stab.is_unstable())
140+
tcx.lookup_stability(projection.def_id).is_some_and(|stab| stab.is_unstable())
143141
})
144142
{
145143
return;
@@ -4565,90 +4563,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
45654563
}
45664564
}
45674565

4568-
pub(super) fn suggest_desugaring_async_fn_in_trait(
4569-
&self,
4570-
err: &mut Diag<'_>,
4571-
trait_pred: ty::PolyTraitPredicate<'tcx>,
4572-
) {
4573-
// Don't suggest if RTN is active -- we should prefer a where-clause bound instead.
4574-
if self.tcx.features().return_type_notation() {
4575-
return;
4576-
}
4577-
4578-
let trait_def_id = trait_pred.def_id();
4579-
4580-
// Only suggest specifying auto traits
4581-
if !self.tcx.trait_is_auto(trait_def_id) {
4582-
return;
4583-
}
4584-
4585-
// Look for an RPITIT
4586-
let ty::Alias(ty::Projection, alias_ty) = trait_pred.self_ty().skip_binder().kind() else {
4587-
return;
4588-
};
4589-
let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
4590-
self.tcx.opt_rpitit_info(alias_ty.def_id)
4591-
else {
4592-
return;
4593-
};
4594-
4595-
let auto_trait = self.tcx.def_path_str(trait_def_id);
4596-
// ... which is a local function
4597-
let Some(fn_def_id) = fn_def_id.as_local() else {
4598-
// If it's not local, we can at least mention that the method is async, if it is.
4599-
if self.tcx.asyncness(fn_def_id).is_async() {
4600-
err.span_note(
4601-
self.tcx.def_span(fn_def_id),
4602-
format!(
4603-
"`{}::{}` is an `async fn` in trait, which does not \
4604-
automatically imply that its future is `{auto_trait}`",
4605-
alias_ty.trait_ref(self.tcx),
4606-
self.tcx.item_name(fn_def_id)
4607-
),
4608-
);
4609-
}
4610-
return;
4611-
};
4612-
let hir::Node::TraitItem(item) = self.tcx.hir_node_by_def_id(fn_def_id) else {
4613-
return;
4614-
};
4615-
4616-
// ... whose signature is `async` (i.e. this is an AFIT)
4617-
let (sig, body) = item.expect_fn();
4618-
let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(opaq_def, ..), .. }) =
4619-
sig.decl.output
4620-
else {
4621-
// This should never happen, but let's not ICE.
4622-
return;
4623-
};
4624-
4625-
// Check that this is *not* a nested `impl Future` RPIT in an async fn
4626-
// (i.e. `async fn foo() -> impl Future`)
4627-
if opaq_def.def_id.to_def_id() != opaque_def_id {
4628-
return;
4629-
}
4630-
4631-
let Some(sugg) = suggest_desugaring_async_fn_to_impl_future_in_trait(
4632-
self.tcx,
4633-
*sig,
4634-
*body,
4635-
opaque_def_id.expect_local(),
4636-
&format!(" + {auto_trait}"),
4637-
) else {
4638-
return;
4639-
};
4640-
4641-
let function_name = self.tcx.def_path_str(fn_def_id);
4642-
err.multipart_suggestion(
4643-
format!(
4644-
"`{auto_trait}` can be made part of the associated future's \
4645-
guarantees for all implementations of `{function_name}`"
4646-
),
4647-
sugg,
4648-
Applicability::MachineApplicable,
4649-
);
4650-
}
4651-
46524566
pub fn ty_kind_suggestion(
46534567
&self,
46544568
param_env: ty::ParamEnv<'tcx>,

tests/ui/associated-type-bounds/all-generics-lookup.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//@ check-pass
22

3-
#![feature(return_type_notation)]
4-
53
trait Trait {
64
fn method(&self) -> impl Sized;
75
}

tests/ui/associated-type-bounds/implied-from-self-where-clause.rs

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
//@ check-pass
55

6-
#![feature(return_type_notation)]
7-
86
trait Foo
97
where
108
Self::method(..): Send,

tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ edition: 2021
22
//@ run-rustfix
3-
#![feature(return_type_notation)]
3+
44
#![allow(dead_code)]
55

66
trait Trait {

tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@ edition: 2021
22
//@ run-rustfix
3-
#![feature(return_type_notation)]
3+
44
#![allow(dead_code)]
55

66
trait Trait {

tests/ui/associated-type-bounds/return-type-notation/bare-path.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(return_type_notation)]
2-
31
trait Tr {
42
const CONST: usize;
53

tests/ui/associated-type-bounds/return-type-notation/bare-path.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: return type notation not allowed in this position yet
2-
--> $DIR/bare-path.rs:14:23
2+
--> $DIR/bare-path.rs:12:23
33
|
44
LL | let _ = T::CONST::(..);
55
| ^^^^
66

77
error: return type notation not allowed in this position yet
8-
--> $DIR/bare-path.rs:16:12
8+
--> $DIR/bare-path.rs:14:12
99
|
1010
LL | let _: T::method(..);
1111
| ^^^^^^^^^^^^^

tests/ui/associated-type-bounds/return-type-notation/basic.rs

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//@ edition: 2021
33
//@ [with] check-pass
44

5-
#![feature(return_type_notation)]
6-
75
trait Foo {
86
async fn method() -> Result<(), ()>;
97
}

tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error: future cannot be sent between threads safely
2-
--> $DIR/basic.rs:22:13
2+
--> $DIR/basic.rs:20:13
33
|
44
LL | is_send(foo::<T>());
55
| ^^^^^^^^^^ future returned by `foo` is not `Send`
66
|
77
= help: within `impl Future<Output = Result<(), ()>>`, the trait `Send` is not implemented for `impl Future<Output = Result<(), ()>> { <T as Foo>::method(..) }`
88
note: future is not `Send` as it awaits another future which is not `Send`
9-
--> $DIR/basic.rs:12:5
9+
--> $DIR/basic.rs:10:5
1010
|
1111
LL | T::method().await?;
1212
| ^^^^^^^^^^^ await occurs here on type `impl Future<Output = Result<(), ()>> { <T as Foo>::method(..) }`, which is not `Send`
1313
note: required by a bound in `is_send`
14-
--> $DIR/basic.rs:16:20
14+
--> $DIR/basic.rs:14:20
1515
|
1616
LL | fn is_send(_: impl Send) {}
1717
| ^^^^ required by this bound in `is_send`

tests/ui/associated-type-bounds/return-type-notation/display.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(return_type_notation)]
2-
31
trait Trait {}
42
fn needs_trait(_: impl Trait) {}
53

0 commit comments

Comments
 (0)