Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove .. from return type notation #110203

Merged
merged 1 commit into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ pub enum GenericArgs {
AngleBracketed(AngleBracketedArgs),
/// The `(A, B)` and `C` in `Foo(A, B) -> C`.
Parenthesized(ParenthesizedArgs),
/// Associated return type bounds, like `T: Trait<method(..): Send>`
/// which applies the `Send` bound to the return-type of `method`.
ReturnTypeNotation(Span),
}

impl GenericArgs {
Expand All @@ -181,7 +178,6 @@ impl GenericArgs {
match self {
AngleBracketed(data) => data.span,
Parenthesized(data) => data.span,
ReturnTypeNotation(span) => *span,
}
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,6 @@ pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vi
match generic_args {
GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
GenericArgs::ReturnTypeNotation(_span) => {}
}
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,6 @@ where
walk_list!(visitor, visit_ty, &data.inputs);
walk_fn_ret_ty(visitor, &data.output);
}
GenericArgs::ReturnTypeNotation(_span) => {}
}
}

Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,7 @@ pub enum BadReturnTypeNotation {
#[diag(ast_lowering_bad_return_type_notation_inputs)]
Inputs {
#[primary_span]
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
span: Span,
},
#[diag(ast_lowering_bad_return_type_notation_needs_dots)]
NeedsDots {
#[primary_span]
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
#[suggestion(code = "()", applicability = "maybe-incorrect")]
span: Span,
},
#[diag(ast_lowering_bad_return_type_notation_output)]
Expand Down
27 changes: 16 additions & 11 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -987,15 +987,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
GenericArgs::AngleBracketed(data) => {
self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
}
&GenericArgs::ReturnTypeNotation(span) => GenericArgsCtor {
args: Default::default(),
bindings: &[],
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
span,
},
GenericArgs::Parenthesized(data) => {
if let Some(start_char) = constraint.ident.as_str().chars().next()
&& start_char.is_ascii_lowercase()
if data.inputs.is_empty() && matches!(data.output, FnRetTy::Default(..)) {
let parenthesized = if self.tcx.features().return_type_notation {
hir::GenericArgsParentheses::ReturnTypeNotation
} else {
self.emit_bad_parenthesized_trait_in_assoc_ty(data);
hir::GenericArgsParentheses::No
};
GenericArgsCtor {
args: Default::default(),
bindings: &[],
parenthesized,
span: data.inputs_span,
}
} else if let Some(first_char) = constraint.ident.as_str().chars().next()
&& first_char.is_ascii_lowercase()
{
let mut err = if !data.inputs.is_empty() {
self.tcx.sess.create_err(errors::BadReturnTypeNotation::Inputs {
Expand All @@ -1006,9 +1013,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: data.inputs_span.shrink_to_hi().to(ty.span),
})
} else {
self.tcx.sess.create_err(errors::BadReturnTypeNotation::NeedsDots {
span: data.inputs_span,
})
unreachable!("inputs are empty and return type is not provided")
};
if !self.tcx.features().return_type_notation
&& self.tcx.sess.is_nightly_build()
Expand Down
13 changes: 0 additions & 13 deletions compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, DUMMY_SP};

use smallvec::{smallvec, SmallVec};
use thin_vec::ThinVec;

impl<'a, 'hir> LoweringContext<'a, 'hir> {
#[instrument(level = "trace", skip(self))]
Expand Down Expand Up @@ -219,18 +218,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}
},
&GenericArgs::ReturnTypeNotation(span) => {
self.tcx.sess.emit_err(GenericTypeWithParentheses { span, sub: None });
(
self.lower_angle_bracketed_parameter_data(
&AngleBracketedArgs { span, args: ThinVec::default() },
param_mode,
itctx,
)
.0,
false,
)
}
}
} else {
(
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.with_impl_trait(None, |this| this.visit_ty(ty));
}
}
GenericArgs::ReturnTypeNotation(_span) => {}
}
}

Expand Down Expand Up @@ -1386,7 +1385,6 @@ fn deny_equality_constraints(
match &mut assoc_path.segments[len].args {
Some(args) => match args.deref_mut() {
GenericArgs::Parenthesized(_) => continue,
GenericArgs::ReturnTypeNotation(_span) => continue,
GenericArgs::AngleBracketed(args) => {
args.args.push(arg);
}
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,20 +485,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {

fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
if let AssocConstraintKind::Bound { .. } = constraint.kind {
if let Some(args) = constraint.gen_args.as_ref()
&& matches!(
args,
ast::GenericArgs::ReturnTypeNotation(..)
)
if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
&& args.inputs.is_empty()
&& matches!(args.output, ast::FnRetTy::Default(..))
{
// RTN is gated below with a `gate_all`.
gate_feature_post!(
&self,
return_type_notation,
constraint.span,
"return type notation is experimental"
);
} else {
gate_feature_post!(
&self,
associated_type_bounds,
constraint.span,
"associated type bounds are unstable"
)
);
}
}
visit::walk_assoc_constraint(self, constraint)
Expand Down Expand Up @@ -589,7 +592,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(yeet_expr, "`do yeet` expression is experimental");
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
gate_all!(const_closures, "const closures are experimental");
gate_all!(return_type_notation, "return type notation is experimental");

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

gate_all!(trait_alias, "trait aliases are experimental");
gate_all!(associated_type_bounds, "associated type bounds are unstable");
gate_all!(return_type_notation, "return type notation is experimental");
gate_all!(decl_macro, "`macro` is experimental");
gate_all!(box_patterns, "box pattern syntax is experimental");
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,10 +936,6 @@ impl<'a> PrintState<'a> for State<'a> {
self.word(")");
self.print_fn_ret_ty(&data.output);
}

ast::GenericArgs::ReturnTypeNotation(_span) => {
self.word("(..)");
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -738,3 +738,7 @@ parse_box_syntax_removed = `box_syntax` has been removed
parse_bad_return_type_notation_output =
return type not allowed with return type notation
.suggestion = remove the return type

parse_bad_return_type_notation_dotdot =
return type notation uses `()` instead of `(..)` for elided arguments
.suggestion = remove the `..`
8 changes: 8 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2324,3 +2324,11 @@ pub(crate) struct BadReturnTypeNotationOutput {
#[suggestion(code = "", applicability = "maybe-incorrect")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(parse_bad_return_type_notation_dotdot)]
pub(crate) struct BadReturnTypeNotationDotDot {
#[primary_span]
#[suggestion(code = "", applicability = "maybe-incorrect")]
pub span: Span,
}
25 changes: 16 additions & 9 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,16 +290,17 @@ impl<'a> Parser<'a> {
})?;
let span = lo.to(self.prev_token.span);
AngleBracketedArgs { args, span }.into()
} else if self.token.kind == token::OpenDelim(Delimiter::Parenthesis)
} else if self.may_recover()
&& self.token.kind == token::OpenDelim(Delimiter::Parenthesis)
// FIXME(return_type_notation): Could also recover `...` here.
&& self.look_ahead(1, |tok| tok.kind == token::DotDot)
{
let lo = self.token.span;
self.bump();
self.sess
.emit_err(errors::BadReturnTypeNotationDotDot { span: self.token.span });
self.bump();
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
let span = lo.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::return_type_notation, span);

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

P(GenericArgs::ReturnTypeNotation(span))
ParenthesizedArgs {
span,
inputs: ThinVec::new(),
inputs_span: span,
output: ast::FnRetTy::Default(self.prev_token.span.shrink_to_hi()),
}
.into()
} else {
// `(T, U) -> R`
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
Expand Down Expand Up @@ -566,13 +573,13 @@ impl<'a> Parser<'a> {
};

let span = lo.to(self.prev_token.span);

// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
if let AssocConstraintKind::Bound { .. } = kind {
if gen_args.as_ref().map_or(false, |args| {
matches!(args, GenericArgs::ReturnTypeNotation(..))
}) {
// This is already gated in `parse_path_segment`
if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
&& args.inputs.is_empty()
&& matches!(args.output, ast::FnRetTy::Default(..))
{
self.sess.gated_spans.gate(sym::return_type_notation, span);
} else {
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/hir_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) {
record_variants!(
(self, g, g, Id::None, ast, GenericArgs, GenericArgs),
[AngleBracketed, Parenthesized, ReturnTypeNotation]
[AngleBracketed, Parenthesized]
);
ast_visit::walk_generic_args(self, g)
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,6 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
}
}
}
GenericArgs::ReturnTypeNotation(_span) => {}
}
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
(args.span, found_lifetimes)
}
GenericArgs::Parenthesized(args) => (args.span, true),
GenericArgs::ReturnTypeNotation(span) => (*span, false),
}
} else {
(DUMMY_SP, false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ fn foo<T: Trait<method(i32): Send>>() {}
//~^ ERROR argument types not allowed with return type notation
//~| ERROR associated type bounds are unstable

fn bar<T: Trait<method(..) -> (): Send>>() {}
fn bar<T: Trait<method() -> (): Send>>() {}
//~^ ERROR return type not allowed with return type notation

fn baz<T: Trait<method(): Send>>() {}
//~^ ERROR return type notation arguments must be elided with `..`
//~| ERROR associated type bounds are unstable

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

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

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

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

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async fn foo<T: Foo>() -> Result<(), ()> {
fn is_send(_: impl Send) {}

fn test<
#[cfg(with)] T: Foo<method(..): Send>,
#[cfg(with)] T: Foo<method(): Send>,
#[cfg(without)] T: Foo,
>() {
is_send(foo::<T>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait Trait {
async fn method() {}
}

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

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

error: aborting due to previous error; 2 warnings emitted

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ trait Trait {
async fn method() {}
}

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

fn main() {}
Loading