Remove .. from return type notation

This commit is contained in:
Michael Goulet 2023-04-10 22:16:17 +00:00
parent 2a198c7f62
commit 24cbf81b85
27 changed files with 126 additions and 109 deletions

View file

@ -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 @@ pub fn span(&self) -> Span {
match self { match self {
AngleBracketed(data) => data.span, AngleBracketed(data) => data.span,
Parenthesized(data) => data.span, Parenthesized(data) => data.span,
ReturnTypeNotation(span) => *span,
} }
} }
} }

View file

@ -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) => {}
} }
} }

View file

@ -482,7 +482,6 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs)
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) => {}
} }
} }

View file

@ -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)]

View file

@ -987,15 +987,22 @@ fn lower_assoc_ty_constraint(
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 {
args: Default::default(),
bindings: &[],
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
span,
},
GenericArgs::Parenthesized(data) => { GenericArgs::Parenthesized(data) => {
if let Some(start_char) = constraint.ident.as_str().chars().next() if data.inputs.is_empty() && matches!(data.output, FnRetTy::Default(..)) {
&& start_char.is_ascii_lowercase() 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() { 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 @@ fn lower_assoc_ty_constraint(
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()

View file

@ -13,7 +13,6 @@
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 @@ pub(crate) fn lower_path_segment(
) )
} }
}, },
&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 {
( (

View file

@ -1075,7 +1075,6 @@ fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) {
self.with_impl_trait(None, |this| this.visit_ty(ty)); self.with_impl_trait(None, |this| this.visit_ty(ty));
} }
} }
GenericArgs::ReturnTypeNotation(_span) => {}
} }
} }
@ -1386,7 +1385,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);
} }

View file

@ -485,20 +485,23 @@ fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
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 @@ macro_rules! gate_all {
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 @@ macro_rules! gate_all {
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");

View file

@ -936,10 +936,6 @@ fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params:
self.word(")"); self.word(")");
self.print_fn_ret_ty(&data.output); self.print_fn_ret_ty(&data.output);
} }
ast::GenericArgs::ReturnTypeNotation(_span) => {
self.word("(..)");
}
} }
} }
} }

View file

@ -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 `..`

View file

@ -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,
}

View file

@ -290,16 +290,17 @@ pub(super) fn parse_path_segment(
})?; })?;
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 @@ pub(super) fn parse_path_segment(
.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 @@ fn parse_angle_arg(
}; };
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);
} }

View file

@ -666,7 +666,7 @@ fn visit_path_segment(&mut self, path_segment: &'v ast::PathSegment) {
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)
} }

View file

@ -1116,7 +1116,6 @@ fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) {
} }
} }
} }
GenericArgs::ReturnTypeNotation(_span) => {}
} }
} }
} }

View file

@ -312,7 +312,6 @@ fn from(seg: &'a ast::PathSegment) -> 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)

View file

@ -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() {}

View file

@ -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

View file

@ -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>());

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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`.

View file

@ -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`.

View file

@ -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() {}