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.
This commit is contained in:
commit
a34bcd70b2
27 changed files with 126 additions and 109 deletions
|
@ -167,9 +167,6 @@ pub enum GenericArgs {
|
||||||
AngleBracketed(AngleBracketedArgs),
|
AngleBracketed(AngleBracketedArgs),
|
||||||
/// The `(A, B)` and `C` in `Foo(A, B) -> C`.
|
/// The `(A, B)` and `C` in `Foo(A, B) -> C`.
|
||||||
Parenthesized(ParenthesizedArgs),
|
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 {
|
impl GenericArgs {
|
||||||
|
@ -181,7 +178,6 @@ impl GenericArgs {
|
||||||
match self {
|
match self {
|
||||||
AngleBracketed(data) => data.span,
|
AngleBracketed(data) => data.span,
|
||||||
Parenthesized(data) => data.span,
|
Parenthesized(data) => data.span,
|
||||||
ReturnTypeNotation(span) => *span,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,7 +561,6 @@ pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vi
|
||||||
match generic_args {
|
match generic_args {
|
||||||
GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
|
GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
|
||||||
GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
|
GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
|
||||||
GenericArgs::ReturnTypeNotation(_span) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -482,7 +482,6 @@ where
|
||||||
walk_list!(visitor, visit_ty, &data.inputs);
|
walk_list!(visitor, visit_ty, &data.inputs);
|
||||||
walk_fn_ret_ty(visitor, &data.output);
|
walk_fn_ret_ty(visitor, &data.output);
|
||||||
}
|
}
|
||||||
GenericArgs::ReturnTypeNotation(_span) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,13 +353,7 @@ pub enum BadReturnTypeNotation {
|
||||||
#[diag(ast_lowering_bad_return_type_notation_inputs)]
|
#[diag(ast_lowering_bad_return_type_notation_inputs)]
|
||||||
Inputs {
|
Inputs {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
|
#[suggestion(code = "()", applicability = "maybe-incorrect")]
|
||||||
span: Span,
|
|
||||||
},
|
|
||||||
#[diag(ast_lowering_bad_return_type_notation_needs_dots)]
|
|
||||||
NeedsDots {
|
|
||||||
#[primary_span]
|
|
||||||
#[suggestion(code = "(..)", applicability = "maybe-incorrect")]
|
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
#[diag(ast_lowering_bad_return_type_notation_output)]
|
#[diag(ast_lowering_bad_return_type_notation_output)]
|
||||||
|
|
|
@ -987,15 +987,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
GenericArgs::AngleBracketed(data) => {
|
GenericArgs::AngleBracketed(data) => {
|
||||||
self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
|
self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
|
||||||
}
|
}
|
||||||
&GenericArgs::ReturnTypeNotation(span) => GenericArgsCtor {
|
GenericArgs::Parenthesized(data) => {
|
||||||
|
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(),
|
args: Default::default(),
|
||||||
bindings: &[],
|
bindings: &[],
|
||||||
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
|
parenthesized,
|
||||||
span,
|
span: data.inputs_span,
|
||||||
},
|
}
|
||||||
GenericArgs::Parenthesized(data) => {
|
} else if let Some(first_char) = constraint.ident.as_str().chars().next()
|
||||||
if let Some(start_char) = constraint.ident.as_str().chars().next()
|
&& first_char.is_ascii_lowercase()
|
||||||
&& start_char.is_ascii_lowercase()
|
|
||||||
{
|
{
|
||||||
let mut err = if !data.inputs.is_empty() {
|
let mut err = if !data.inputs.is_empty() {
|
||||||
self.tcx.sess.create_err(errors::BadReturnTypeNotation::Inputs {
|
self.tcx.sess.create_err(errors::BadReturnTypeNotation::Inputs {
|
||||||
|
@ -1006,9 +1013,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: data.inputs_span.shrink_to_hi().to(ty.span),
|
span: data.inputs_span.shrink_to_hi().to(ty.span),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.tcx.sess.create_err(errors::BadReturnTypeNotation::NeedsDots {
|
unreachable!("inputs are empty and return type is not provided")
|
||||||
span: data.inputs_span,
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
if !self.tcx.features().return_type_notation
|
if !self.tcx.features().return_type_notation
|
||||||
&& self.tcx.sess.is_nightly_build()
|
&& self.tcx.sess.is_nightly_build()
|
||||||
|
|
|
@ -13,7 +13,6 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use thin_vec::ThinVec;
|
|
||||||
|
|
||||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
|
@ -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 {
|
} else {
|
||||||
(
|
(
|
||||||
|
|
|
@ -1080,7 +1080,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.with_impl_trait(None, |this| this.visit_ty(ty));
|
self.with_impl_trait(None, |this| this.visit_ty(ty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericArgs::ReturnTypeNotation(_span) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1391,7 +1390,6 @@ fn deny_equality_constraints(
|
||||||
match &mut assoc_path.segments[len].args {
|
match &mut assoc_path.segments[len].args {
|
||||||
Some(args) => match args.deref_mut() {
|
Some(args) => match args.deref_mut() {
|
||||||
GenericArgs::Parenthesized(_) => continue,
|
GenericArgs::Parenthesized(_) => continue,
|
||||||
GenericArgs::ReturnTypeNotation(_span) => continue,
|
|
||||||
GenericArgs::AngleBracketed(args) => {
|
GenericArgs::AngleBracketed(args) => {
|
||||||
args.args.push(arg);
|
args.args.push(arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,20 +485,23 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
|
|
||||||
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
|
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
|
||||||
if let AssocConstraintKind::Bound { .. } = constraint.kind {
|
if let AssocConstraintKind::Bound { .. } = constraint.kind {
|
||||||
if let Some(args) = constraint.gen_args.as_ref()
|
if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
|
||||||
&& matches!(
|
&& args.inputs.is_empty()
|
||||||
args,
|
&& matches!(args.output, ast::FnRetTy::Default(..))
|
||||||
ast::GenericArgs::ReturnTypeNotation(..)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// RTN is gated below with a `gate_all`.
|
gate_feature_post!(
|
||||||
|
&self,
|
||||||
|
return_type_notation,
|
||||||
|
constraint.span,
|
||||||
|
"return type notation is experimental"
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
gate_feature_post!(
|
gate_feature_post!(
|
||||||
&self,
|
&self,
|
||||||
associated_type_bounds,
|
associated_type_bounds,
|
||||||
constraint.span,
|
constraint.span,
|
||||||
"associated type bounds are unstable"
|
"associated type bounds are unstable"
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visit::walk_assoc_constraint(self, constraint)
|
visit::walk_assoc_constraint(self, constraint)
|
||||||
|
@ -589,7 +592,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
||||||
gate_all!(yeet_expr, "`do yeet` expression is experimental");
|
gate_all!(yeet_expr, "`do yeet` expression is experimental");
|
||||||
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
|
gate_all!(dyn_star, "`dyn*` trait objects are experimental");
|
||||||
gate_all!(const_closures, "const closures 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,
|
// All uses of `gate_all!` below this point were added in #65742,
|
||||||
// and subsequently disabled (with the non-early gating readded).
|
// and subsequently disabled (with the non-early gating readded).
|
||||||
|
@ -605,6 +607,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
||||||
|
|
||||||
gate_all!(trait_alias, "trait aliases are experimental");
|
gate_all!(trait_alias, "trait aliases are experimental");
|
||||||
gate_all!(associated_type_bounds, "associated type bounds are unstable");
|
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!(decl_macro, "`macro` is experimental");
|
||||||
gate_all!(box_patterns, "box pattern syntax is experimental");
|
gate_all!(box_patterns, "box pattern syntax is experimental");
|
||||||
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
|
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
|
||||||
|
|
|
@ -936,10 +936,6 @@ impl<'a> PrintState<'a> for State<'a> {
|
||||||
self.word(")");
|
self.word(")");
|
||||||
self.print_fn_ret_ty(&data.output);
|
self.print_fn_ret_ty(&data.output);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::GenericArgs::ReturnTypeNotation(_span) => {
|
|
||||||
self.word("(..)");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -738,3 +738,7 @@ parse_box_syntax_removed = `box_syntax` has been removed
|
||||||
parse_bad_return_type_notation_output =
|
parse_bad_return_type_notation_output =
|
||||||
return type not allowed with return type notation
|
return type not allowed with return type notation
|
||||||
.suggestion = remove the return type
|
.suggestion = remove the return type
|
||||||
|
|
||||||
|
parse_bad_return_type_notation_dotdot =
|
||||||
|
return type notation uses `()` instead of `(..)` for elided arguments
|
||||||
|
.suggestion = remove the `..`
|
||||||
|
|
|
@ -2324,3 +2324,11 @@ pub(crate) struct BadReturnTypeNotationOutput {
|
||||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||||
pub span: Span,
|
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,
|
||||||
|
}
|
||||||
|
|
|
@ -290,16 +290,17 @@ impl<'a> Parser<'a> {
|
||||||
})?;
|
})?;
|
||||||
let span = lo.to(self.prev_token.span);
|
let span = lo.to(self.prev_token.span);
|
||||||
AngleBracketedArgs { args, span }.into()
|
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.
|
// FIXME(return_type_notation): Could also recover `...` here.
|
||||||
&& self.look_ahead(1, |tok| tok.kind == token::DotDot)
|
&& self.look_ahead(1, |tok| tok.kind == token::DotDot)
|
||||||
{
|
{
|
||||||
let lo = self.token.span;
|
|
||||||
self.bump();
|
self.bump();
|
||||||
|
self.sess
|
||||||
|
.emit_err(errors::BadReturnTypeNotationDotDot { span: self.token.span });
|
||||||
self.bump();
|
self.bump();
|
||||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||||
let span = lo.to(self.prev_token.span);
|
let span = lo.to(self.prev_token.span);
|
||||||
self.sess.gated_spans.gate(sym::return_type_notation, span);
|
|
||||||
|
|
||||||
if self.eat_noexpect(&token::RArrow) {
|
if self.eat_noexpect(&token::RArrow) {
|
||||||
let lo = self.prev_token.span;
|
let lo = self.prev_token.span;
|
||||||
|
@ -308,7 +309,13 @@ impl<'a> Parser<'a> {
|
||||||
.emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) });
|
.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 {
|
} else {
|
||||||
// `(T, U) -> R`
|
// `(T, U) -> R`
|
||||||
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
|
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
|
||||||
|
@ -566,13 +573,13 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = lo.to(self.prev_token.span);
|
let span = lo.to(self.prev_token.span);
|
||||||
|
|
||||||
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
|
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
|
||||||
if let AssocConstraintKind::Bound { .. } = kind {
|
if let AssocConstraintKind::Bound { .. } = kind {
|
||||||
if gen_args.as_ref().map_or(false, |args| {
|
if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
|
||||||
matches!(args, GenericArgs::ReturnTypeNotation(..))
|
&& args.inputs.is_empty()
|
||||||
}) {
|
&& matches!(args.output, ast::FnRetTy::Default(..))
|
||||||
// This is already gated in `parse_path_segment`
|
{
|
||||||
|
self.sess.gated_spans.gate(sym::return_type_notation, span);
|
||||||
} else {
|
} else {
|
||||||
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
|
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -666,7 +666,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) {
|
fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) {
|
||||||
record_variants!(
|
record_variants!(
|
||||||
(self, g, g, Id::None, ast, GenericArgs, GenericArgs),
|
(self, g, g, Id::None, ast, GenericArgs, GenericArgs),
|
||||||
[AngleBracketed, Parenthesized, ReturnTypeNotation]
|
[AngleBracketed, Parenthesized]
|
||||||
);
|
);
|
||||||
ast_visit::walk_generic_args(self, g)
|
ast_visit::walk_generic_args(self, g)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1116,7 +1116,6 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericArgs::ReturnTypeNotation(_span) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,7 +312,6 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
|
||||||
(args.span, found_lifetimes)
|
(args.span, found_lifetimes)
|
||||||
}
|
}
|
||||||
GenericArgs::Parenthesized(args) => (args.span, true),
|
GenericArgs::Parenthesized(args) => (args.span, true),
|
||||||
GenericArgs::ReturnTypeNotation(span) => (*span, false),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(DUMMY_SP, false)
|
(DUMMY_SP, false)
|
||||||
|
|
|
@ -12,11 +12,11 @@ fn foo<T: Trait<method(i32): Send>>() {}
|
||||||
//~^ ERROR argument types not allowed with return type notation
|
//~^ ERROR argument types not allowed with return type notation
|
||||||
//~| ERROR associated type bounds are unstable
|
//~| 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
|
//~^ 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
|
//~| ERROR associated type bounds are unstable
|
||||||
|
|
||||||
|
fn baz<T: Trait<method(..): Send>>() {}
|
||||||
|
//~^ ERROR return type notation uses `()` instead of `(..)` for elided arguments
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: return type not allowed with return type notation
|
error: return type notation uses `()` instead of `(..)` for elided arguments
|
||||||
--> $DIR/bad-inputs-and-output.rs:15:28
|
--> $DIR/bad-inputs-and-output.rs:19:24
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Trait<method(..) -> (): Send>>() {}
|
LL | fn baz<T: Trait<method(..): Send>>() {}
|
||||||
| ^^^^^ help: remove the return type
|
| ^^ help: remove the `..`
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
error[E0658]: associated type bounds are unstable
|
||||||
--> $DIR/bad-inputs-and-output.rs:11:17
|
--> $DIR/bad-inputs-and-output.rs:11:17
|
||||||
|
@ -14,10 +14,10 @@ LL | fn foo<T: Trait<method(i32): Send>>() {}
|
||||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: associated type bounds are unstable
|
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
|
= 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
|
= 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
|
||||||
--> $DIR/bad-inputs-and-output.rs:11:23
|
--> $DIR/bad-inputs-and-output.rs:11:23
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Trait<method(i32): Send>>() {}
|
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 `..`
|
error: return type not allowed with return type notation
|
||||||
--> $DIR/bad-inputs-and-output.rs:18:23
|
--> $DIR/bad-inputs-and-output.rs:15:25
|
||||||
|
|
|
|
||||||
LL | fn baz<T: Trait<method(): Send>>() {}
|
LL | fn bar<T: Trait<method() -> (): Send>>() {}
|
||||||
| ^^ help: add `..`: `(..)`
|
| ^^^^^^ help: remove the return type
|
||||||
|
|
||||||
error: aborting due to 5 previous errors; 2 warnings emitted
|
error: aborting due to 5 previous errors; 2 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ async fn foo<T: Foo>() -> Result<(), ()> {
|
||||||
fn is_send(_: impl Send) {}
|
fn is_send(_: impl Send) {}
|
||||||
|
|
||||||
fn test<
|
fn test<
|
||||||
#[cfg(with)] T: Foo<method(..): Send>,
|
#[cfg(with)] T: Foo<method(): Send>,
|
||||||
#[cfg(without)] T: Foo,
|
#[cfg(without)] T: Foo,
|
||||||
>() {
|
>() {
|
||||||
is_send(foo::<T>());
|
is_send(foo::<T>());
|
||||||
|
|
|
@ -10,7 +10,7 @@ trait Trait {
|
||||||
async fn method() {}
|
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
|
//~^ ERROR return type notation is not allowed to use type equality
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)]
|
||||||
error: return type notation is not allowed to use type equality
|
error: return type notation is not allowed to use type equality
|
||||||
--> $DIR/equality.rs:13:18
|
--> $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
|
error: aborting due to previous error; 2 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ trait Trait {
|
||||||
async fn method() {}
|
async fn method() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar<T: Trait<methid(..): Send>>() {}
|
fn bar<T: Trait<methid(): Send>>() {}
|
||||||
//~^ ERROR cannot find associated function `methid` in trait `Trait`
|
//~^ ERROR cannot find associated function `methid` in trait `Trait`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)]
|
||||||
error: cannot find associated function `methid` in trait `Trait`
|
error: cannot find associated function `methid` in trait `Trait`
|
||||||
--> $DIR/missing.rs:11:17
|
--> $DIR/missing.rs:11:17
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Trait<methid(..): Send>>() {}
|
LL | fn bar<T: Trait<methid(): Send>>() {}
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error; 2 warnings emitted
|
error: aborting due to previous error; 2 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ trait Trait {
|
||||||
fn method() {}
|
fn method() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test<T: Trait<method(..): Send>>() {}
|
fn test<T: Trait<method(): Send>>() {}
|
||||||
//~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait`
|
//~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -13,8 +13,8 @@ error: return type notation used on function that is not `async` and does not re
|
||||||
LL | fn method() {}
|
LL | fn method() {}
|
||||||
| ----------- this function must be `async` or return `impl Trait`
|
| ----------- this function must be `async` or return `impl Trait`
|
||||||
...
|
...
|
||||||
LL | fn test<T: Trait<method(..): Send>>() {}
|
LL | fn test<T: Trait<method(): Send>>() {}
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: function returns `()`, which is not compatible with associated type return bounds
|
= note: function returns `()`, which is not compatible with associated type return bounds
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
error[E0658]: return type notation is experimental
|
error[E0658]: return type notation is experimental
|
||||||
--> $DIR/feature-gate-return_type_notation.rs:12:18
|
--> $DIR/feature-gate-return_type_notation.rs:15:17
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Trait<m(..): Send>>() {}
|
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||||
| ^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
= help: add `#![feature(return_type_notation)]` to the crate attributes to enable
|
= help: add `#![feature(return_type_notation)]` to the crate attributes to enable
|
||||||
|
|
||||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/feature-gate-return_type_notation.rs:4:12
|
--> $DIR/feature-gate-return_type_notation.rs:7:12
|
||||||
|
|
|
|
||||||
LL | #![feature(async_fn_in_trait)]
|
LL | #![feature(async_fn_in_trait)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
@ -16,6 +16,21 @@ LL | #![feature(async_fn_in_trait)]
|
||||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error: aborting due to previous error; 1 warning emitted
|
error: parenthesized generic arguments cannot be used in associated type constraints
|
||||||
|
--> $DIR/feature-gate-return_type_notation.rs:15:17
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||||
|
| ^--
|
||||||
|
| |
|
||||||
|
| help: remove these parentheses
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
error[E0220]: associated type `m` not found for `Trait`
|
||||||
|
--> $DIR/feature-gate-return_type_notation.rs:15:17
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||||
|
| ^ associated type `m` not found
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0220, E0658.
|
||||||
|
For more information about an error, try `rustc --explain E0220`.
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
error[E0658]: return type notation is experimental
|
|
||||||
--> $DIR/feature-gate-return_type_notation.rs:12:18
|
|
||||||
|
|
|
||||||
LL | fn foo<T: Trait<m(..): Send>>() {}
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
|
||||||
= help: add `#![feature(return_type_notation)]` to the crate attributes to enable
|
|
||||||
|
|
||||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/feature-gate-return_type_notation.rs:4:12
|
--> $DIR/feature-gate-return_type_notation.rs:7:12
|
||||||
|
|
|
|
||||||
LL | #![feature(async_fn_in_trait)]
|
LL | #![feature(async_fn_in_trait)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
@ -16,6 +7,16 @@ LL | #![feature(async_fn_in_trait)]
|
||||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error: aborting due to previous error; 1 warning emitted
|
warning: return type notation is experimental
|
||||||
|
--> $DIR/feature-gate-return_type_notation.rs:15:17
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Trait<m(): Send>>() {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
|
= help: add `#![feature(return_type_notation)]` to the crate attributes to enable
|
||||||
|
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
||||||
|
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>
|
||||||
|
|
||||||
|
warning: 2 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// edition: 2021
|
// edition: 2021
|
||||||
// revisions: cfg no
|
// revisions: cfg no
|
||||||
|
|
||||||
|
//[no] check-pass
|
||||||
|
// Since we're not adding new syntax, `cfg`'d out RTN must pass.
|
||||||
|
|
||||||
#![feature(async_fn_in_trait)]
|
#![feature(async_fn_in_trait)]
|
||||||
//~^ WARN the feature `async_fn_in_trait` is incomplete
|
//~^ WARN the feature `async_fn_in_trait` is incomplete
|
||||||
|
|
||||||
|
@ -9,7 +12,11 @@ trait Trait {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(cfg)]
|
#[cfg(cfg)]
|
||||||
fn foo<T: Trait<m(..): Send>>() {}
|
fn foo<T: Trait<m(): Send>>() {}
|
||||||
//~^ ERROR return type notation is experimental
|
//[cfg]~^ ERROR return type notation is experimental
|
||||||
|
//[cfg]~| ERROR parenthesized generic arguments cannot be used in associated type constraints
|
||||||
|
//[cfg]~| ERROR associated type `m` not found for `Trait`
|
||||||
|
//[no]~^^^^ WARN return type notation is experimental
|
||||||
|
//[no]~| WARN unstable syntax can change at any point in the future, causing a hard error!
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue