Skip to content

Commit a34bcd7

Browse files
authored
Rollup merge of #110203 - compiler-errors:rtn-dots, r=eholk
Remove `..` from return type notation `@nikomatsakis` and I decided that using `..` in the return-type notation syntax is probably overkill. r? `@eholk` since you reviewed the last one Since this is piggybacking now totally off of a pre-existing syntax (parenthesized generics), let me know if you need any explanation of the logic here, since it's a bit more complicated now.
2 parents b4734f0 + 24cbf81 commit a34bcd7

27 files changed

+126
-109
lines changed

compiler/rustc_ast/src/ast.rs

-4
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ pub enum GenericArgs {
167167
AngleBracketed(AngleBracketedArgs),
168168
/// The `(A, B)` and `C` in `Foo(A, B) -> C`.
169169
Parenthesized(ParenthesizedArgs),
170-
/// Associated return type bounds, like `T: Trait<method(..): Send>`
171-
/// which applies the `Send` bound to the return-type of `method`.
172-
ReturnTypeNotation(Span),
173170
}
174171

175172
impl GenericArgs {
@@ -181,7 +178,6 @@ impl GenericArgs {
181178
match self {
182179
AngleBracketed(data) => data.span,
183180
Parenthesized(data) => data.span,
184-
ReturnTypeNotation(span) => *span,
185181
}
186182
}
187183
}

compiler/rustc_ast/src/mut_visit.rs

-1
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,6 @@ pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vi
561561
match generic_args {
562562
GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
563563
GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
564-
GenericArgs::ReturnTypeNotation(_span) => {}
565564
}
566565
}
567566

compiler/rustc_ast/src/visit.rs

-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,6 @@ where
482482
walk_list!(visitor, visit_ty, &data.inputs);
483483
walk_fn_ret_ty(visitor, &data.output);
484484
}
485-
GenericArgs::ReturnTypeNotation(_span) => {}
486485
}
487486
}
488487

compiler/rustc_ast_lowering/src/errors.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -353,13 +353,7 @@ pub enum BadReturnTypeNotation {
353353
#[diag(ast_lowering_bad_return_type_notation_inputs)]
354354
Inputs {
355355
#[primary_span]
356-
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
357-
span: Span,
358-
},
359-
#[diag(ast_lowering_bad_return_type_notation_needs_dots)]
360-
NeedsDots {
361-
#[primary_span]
362-
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
356+
#[suggestion(code = "()", applicability = "maybe-incorrect")]
363357
span: Span,
364358
},
365359
#[diag(ast_lowering_bad_return_type_notation_output)]

compiler/rustc_ast_lowering/src/lib.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -987,15 +987,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
987987
GenericArgs::AngleBracketed(data) => {
988988
self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
989989
}
990-
&GenericArgs::ReturnTypeNotation(span) => GenericArgsCtor {
991-
args: Default::default(),
992-
bindings: &[],
993-
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
994-
span,
995-
},
996990
GenericArgs::Parenthesized(data) => {
997-
if let Some(start_char) = constraint.ident.as_str().chars().next()
998-
&& start_char.is_ascii_lowercase()
991+
if data.inputs.is_empty() && matches!(data.output, FnRetTy::Default(..)) {
992+
let parenthesized = if self.tcx.features().return_type_notation {
993+
hir::GenericArgsParentheses::ReturnTypeNotation
994+
} else {
995+
self.emit_bad_parenthesized_trait_in_assoc_ty(data);
996+
hir::GenericArgsParentheses::No
997+
};
998+
GenericArgsCtor {
999+
args: Default::default(),
1000+
bindings: &[],
1001+
parenthesized,
1002+
span: data.inputs_span,
1003+
}
1004+
} else if let Some(first_char) = constraint.ident.as_str().chars().next()
1005+
&& first_char.is_ascii_lowercase()
9991006
{
10001007
let mut err = if !data.inputs.is_empty() {
10011008
self.tcx.sess.create_err(errors::BadReturnTypeNotation::Inputs {
@@ -1006,9 +1013,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10061013
span: data.inputs_span.shrink_to_hi().to(ty.span),
10071014
})
10081015
} else {
1009-
self.tcx.sess.create_err(errors::BadReturnTypeNotation::NeedsDots {
1010-
span: data.inputs_span,
1011-
})
1016+
unreachable!("inputs are empty and return type is not provided")
10121017
};
10131018
if !self.tcx.features().return_type_notation
10141019
&& self.tcx.sess.is_nightly_build()

compiler/rustc_ast_lowering/src/path.rs

-13
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use rustc_span::symbol::{kw, sym, Ident};
1313
use rustc_span::{BytePos, Span, DUMMY_SP};
1414

1515
use smallvec::{smallvec, SmallVec};
16-
use thin_vec::ThinVec;
1716

1817
impl<'a, 'hir> LoweringContext<'a, 'hir> {
1918
#[instrument(level = "trace", skip(self))]
@@ -219,18 +218,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
219218
)
220219
}
221220
},
222-
&GenericArgs::ReturnTypeNotation(span) => {
223-
self.tcx.sess.emit_err(GenericTypeWithParentheses { span, sub: None });
224-
(
225-
self.lower_angle_bracketed_parameter_data(
226-
&AngleBracketedArgs { span, args: ThinVec::default() },
227-
param_mode,
228-
itctx,
229-
)
230-
.0,
231-
false,
232-
)
233-
}
234221
}
235222
} else {
236223
(

compiler/rustc_ast_passes/src/ast_validation.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10801080
self.with_impl_trait(None, |this| this.visit_ty(ty));
10811081
}
10821082
}
1083-
GenericArgs::ReturnTypeNotation(_span) => {}
10841083
}
10851084
}
10861085

@@ -1391,7 +1390,6 @@ fn deny_equality_constraints(
13911390
match &mut assoc_path.segments[len].args {
13921391
Some(args) => match args.deref_mut() {
13931392
GenericArgs::Parenthesized(_) => continue,
1394-
GenericArgs::ReturnTypeNotation(_span) => continue,
13951393
GenericArgs::AngleBracketed(args) => {
13961394
args.args.push(arg);
13971395
}

compiler/rustc_ast_passes/src/feature_gate.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -485,20 +485,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
485485

486486
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
487487
if let AssocConstraintKind::Bound { .. } = constraint.kind {
488-
if let Some(args) = constraint.gen_args.as_ref()
489-
&& matches!(
490-
args,
491-
ast::GenericArgs::ReturnTypeNotation(..)
492-
)
488+
if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
489+
&& args.inputs.is_empty()
490+
&& matches!(args.output, ast::FnRetTy::Default(..))
493491
{
494-
// RTN is gated below with a `gate_all`.
492+
gate_feature_post!(
493+
&self,
494+
return_type_notation,
495+
constraint.span,
496+
"return type notation is experimental"
497+
);
495498
} else {
496499
gate_feature_post!(
497500
&self,
498501
associated_type_bounds,
499502
constraint.span,
500503
"associated type bounds are unstable"
501-
)
504+
);
502505
}
503506
}
504507
visit::walk_assoc_constraint(self, constraint)
@@ -589,7 +592,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
589592
gate_all!(yeet_expr, "`do yeet` expression is experimental");
590593
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
591594
gate_all!(const_closures, "const closures are experimental");
592-
gate_all!(return_type_notation, "return type notation is experimental");
593595

594596
// All uses of `gate_all!` below this point were added in #65742,
595597
// and subsequently disabled (with the non-early gating readded).
@@ -605,6 +607,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
605607

606608
gate_all!(trait_alias, "trait aliases are experimental");
607609
gate_all!(associated_type_bounds, "associated type bounds are unstable");
610+
gate_all!(return_type_notation, "return type notation is experimental");
608611
gate_all!(decl_macro, "`macro` is experimental");
609612
gate_all!(box_patterns, "box pattern syntax is experimental");
610613
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");

compiler/rustc_ast_pretty/src/pprust/state.rs

-4
Original file line numberDiff line numberDiff line change
@@ -936,10 +936,6 @@ impl<'a> PrintState<'a> for State<'a> {
936936
self.word(")");
937937
self.print_fn_ret_ty(&data.output);
938938
}
939-
940-
ast::GenericArgs::ReturnTypeNotation(_span) => {
941-
self.word("(..)");
942-
}
943939
}
944940
}
945941
}

compiler/rustc_parse/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -738,3 +738,7 @@ parse_box_syntax_removed = `box_syntax` has been removed
738738
parse_bad_return_type_notation_output =
739739
return type not allowed with return type notation
740740
.suggestion = remove the return type
741+
742+
parse_bad_return_type_notation_dotdot =
743+
return type notation uses `()` instead of `(..)` for elided arguments
744+
.suggestion = remove the `..`

compiler/rustc_parse/src/errors.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2324,3 +2324,11 @@ pub(crate) struct BadReturnTypeNotationOutput {
23242324
#[suggestion(code = "", applicability = "maybe-incorrect")]
23252325
pub span: Span,
23262326
}
2327+
2328+
#[derive(Diagnostic)]
2329+
#[diag(parse_bad_return_type_notation_dotdot)]
2330+
pub(crate) struct BadReturnTypeNotationDotDot {
2331+
#[primary_span]
2332+
#[suggestion(code = "", applicability = "maybe-incorrect")]
2333+
pub span: Span,
2334+
}

compiler/rustc_parse/src/parser/path.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -290,16 +290,17 @@ impl<'a> Parser<'a> {
290290
})?;
291291
let span = lo.to(self.prev_token.span);
292292
AngleBracketedArgs { args, span }.into()
293-
} else if self.token.kind == token::OpenDelim(Delimiter::Parenthesis)
293+
} else if self.may_recover()
294+
&& self.token.kind == token::OpenDelim(Delimiter::Parenthesis)
294295
// FIXME(return_type_notation): Could also recover `...` here.
295296
&& self.look_ahead(1, |tok| tok.kind == token::DotDot)
296297
{
297-
let lo = self.token.span;
298298
self.bump();
299+
self.sess
300+
.emit_err(errors::BadReturnTypeNotationDotDot { span: self.token.span });
299301
self.bump();
300302
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
301303
let span = lo.to(self.prev_token.span);
302-
self.sess.gated_spans.gate(sym::return_type_notation, span);
303304

304305
if self.eat_noexpect(&token::RArrow) {
305306
let lo = self.prev_token.span;
@@ -308,7 +309,13 @@ impl<'a> Parser<'a> {
308309
.emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) });
309310
}
310311

311-
P(GenericArgs::ReturnTypeNotation(span))
312+
ParenthesizedArgs {
313+
span,
314+
inputs: ThinVec::new(),
315+
inputs_span: span,
316+
output: ast::FnRetTy::Default(self.prev_token.span.shrink_to_hi()),
317+
}
318+
.into()
312319
} else {
313320
// `(T, U) -> R`
314321
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
@@ -566,13 +573,13 @@ impl<'a> Parser<'a> {
566573
};
567574

568575
let span = lo.to(self.prev_token.span);
569-
570576
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
571577
if let AssocConstraintKind::Bound { .. } = kind {
572-
if gen_args.as_ref().map_or(false, |args| {
573-
matches!(args, GenericArgs::ReturnTypeNotation(..))
574-
}) {
575-
// This is already gated in `parse_path_segment`
578+
if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
579+
&& args.inputs.is_empty()
580+
&& matches!(args.output, ast::FnRetTy::Default(..))
581+
{
582+
self.sess.gated_spans.gate(sym::return_type_notation, span);
576583
} else {
577584
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
578585
}

compiler/rustc_passes/src/hir_stats.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -666,7 +666,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
666666
fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) {
667667
record_variants!(
668668
(self, g, g, Id::None, ast, GenericArgs, GenericArgs),
669-
[AngleBracketed, Parenthesized, ReturnTypeNotation]
669+
[AngleBracketed, Parenthesized]
670670
);
671671
ast_visit::walk_generic_args(self, g)
672672
}

compiler/rustc_resolve/src/late.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,6 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
11161116
}
11171117
}
11181118
}
1119-
GenericArgs::ReturnTypeNotation(_span) => {}
11201119
}
11211120
}
11221121
}

compiler/rustc_resolve/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
312312
(args.span, found_lifetimes)
313313
}
314314
GenericArgs::Parenthesized(args) => (args.span, true),
315-
GenericArgs::ReturnTypeNotation(span) => (*span, false),
316315
}
317316
} else {
318317
(DUMMY_SP, false)

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ fn foo<T: Trait<method(i32): Send>>() {}
1212
//~^ ERROR argument types not allowed with return type notation
1313
//~| ERROR associated type bounds are unstable
1414

15-
fn bar<T: Trait<method(..) -> (): Send>>() {}
15+
fn bar<T: Trait<method() -> (): Send>>() {}
1616
//~^ ERROR return type not allowed with return type notation
17-
18-
fn baz<T: Trait<method(): Send>>() {}
19-
//~^ ERROR return type notation arguments must be elided with `..`
2017
//~| ERROR associated type bounds are unstable
2118

19+
fn baz<T: Trait<method(..): Send>>() {}
20+
//~^ ERROR return type notation uses `()` instead of `(..)` for elided arguments
21+
2222
fn main() {}

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: return type not allowed with return type notation
2-
--> $DIR/bad-inputs-and-output.rs:15:28
1+
error: return type notation uses `()` instead of `(..)` for elided arguments
2+
--> $DIR/bad-inputs-and-output.rs:19:24
33
|
4-
LL | fn bar<T: Trait<method(..) -> (): Send>>() {}
5-
| ^^^^^ help: remove the return type
4+
LL | fn baz<T: Trait<method(..): Send>>() {}
5+
| ^^ help: remove the `..`
66

77
error[E0658]: associated type bounds are unstable
88
--> $DIR/bad-inputs-and-output.rs:11:17
@@ -14,10 +14,10 @@ LL | fn foo<T: Trait<method(i32): Send>>() {}
1414
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
1515

1616
error[E0658]: associated type bounds are unstable
17-
--> $DIR/bad-inputs-and-output.rs:18:17
17+
--> $DIR/bad-inputs-and-output.rs:15:17
1818
|
19-
LL | fn baz<T: Trait<method(): Send>>() {}
20-
| ^^^^^^^^^^^^^^
19+
LL | fn bar<T: Trait<method() -> (): Send>>() {}
20+
| ^^^^^^^^^^^^^^^^^^^^
2121
|
2222
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
2323
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
@@ -43,13 +43,13 @@ error: argument types not allowed with return type notation
4343
--> $DIR/bad-inputs-and-output.rs:11:23
4444
|
4545
LL | fn foo<T: Trait<method(i32): Send>>() {}
46-
| ^^^^^ help: remove the input types: `(..)`
46+
| ^^^^^ help: remove the input types: `()`
4747

48-
error: return type notation arguments must be elided with `..`
49-
--> $DIR/bad-inputs-and-output.rs:18:23
48+
error: return type not allowed with return type notation
49+
--> $DIR/bad-inputs-and-output.rs:15:25
5050
|
51-
LL | fn baz<T: Trait<method(): Send>>() {}
52-
| ^^ help: add `..`: `(..)`
51+
LL | fn bar<T: Trait<method() -> (): Send>>() {}
52+
| ^^^^^^ help: remove the return type
5353

5454
error: aborting due to 5 previous errors; 2 warnings emitted
5555

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ async fn foo<T: Foo>() -> Result<(), ()> {
1818
fn is_send(_: impl Send) {}
1919

2020
fn test<
21-
#[cfg(with)] T: Foo<method(..): Send>,
21+
#[cfg(with)] T: Foo<method(): Send>,
2222
#[cfg(without)] T: Foo,
2323
>() {
2424
is_send(foo::<T>());

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ trait Trait {
1010
async fn method() {}
1111
}
1212

13-
fn test<T: Trait<method(..) = Box<dyn Future<Output = ()>>>>() {}
13+
fn test<T: Trait<method() = Box<dyn Future<Output = ()>>>>() {}
1414
//~^ ERROR return type notation is not allowed to use type equality
1515

1616
fn main() {}

tests/ui/associated-type-bounds/return-type-notation/equality.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)]
1818
error: return type notation is not allowed to use type equality
1919
--> $DIR/equality.rs:13:18
2020
|
21-
LL | fn test<T: Trait<method(..) = Box<dyn Future<Output = ()>>>>() {}
22-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
LL | fn test<T: Trait<method() = Box<dyn Future<Output = ()>>>>() {}
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2323

2424
error: aborting due to previous error; 2 warnings emitted
2525

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ trait Trait {
88
async fn method() {}
99
}
1010

11-
fn bar<T: Trait<methid(..): Send>>() {}
11+
fn bar<T: Trait<methid(): Send>>() {}
1212
//~^ ERROR cannot find associated function `methid` in trait `Trait`
1313

1414
fn main() {}

0 commit comments

Comments
 (0)