pub struct AngleBracketedArgs {
/// The overall span.
pub span: Span,
- /// The arguments for this path segment.
- pub args: Vec<GenericArg>,
- /// Constraints on associated types, if any.
- /// E.g., `Foo<A = Bar, B: Baz>`.
- pub constraints: Vec<AssocTyConstraint>,
+ /// The comma separated parts in the `<...>`.
+ pub args: Vec<AngleBracketedArg>,
+}
+
+/// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
+/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub enum AngleBracketedArg {
+ /// Argument for a generic parameter.
+ Arg(GenericArg),
+ /// Constraint for an associated item.
+ Constraint(AssocTyConstraint),
}
impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
impl ParenthesizedArgs {
pub fn as_angle_bracketed_args(&self) -> AngleBracketedArgs {
- AngleBracketedArgs {
- span: self.span,
- args: self.inputs.iter().cloned().map(GenericArg::Type).collect(),
- constraints: vec![],
- }
+ let args = self
+ .inputs
+ .iter()
+ .cloned()
+ .map(|input| AngleBracketedArg::Arg(GenericArg::Type(input)))
+ .collect();
+ AngleBracketedArgs { span: self.span, args }
}
}
data: &mut AngleBracketedArgs,
vis: &mut T,
) {
- let AngleBracketedArgs { args, constraints, span } = data;
- visit_vec(args, |arg| vis.visit_generic_arg(arg));
- visit_vec(constraints, |constraint| vis.visit_ty_constraint(constraint));
+ let AngleBracketedArgs { args, span } = data;
+ visit_vec(args, |arg| match arg {
+ AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
+ AngleBracketedArg::Constraint(constraint) => vis.visit_ty_constraint(constraint),
+ });
vis.visit_span(span);
}
{
match *generic_args {
GenericArgs::AngleBracketed(ref data) => {
- walk_list!(visitor, visit_generic_arg, &data.args);
- walk_list!(visitor, visit_assoc_ty_constraint, &data.constraints);
+ for arg in &data.args {
+ match arg {
+ AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a),
+ AngleBracketedArg::Constraint(c) => visitor.visit_assoc_ty_constraint(c),
+ }
+ }
}
GenericArgs::Parenthesized(ref data) => {
walk_list!(visitor, visit_ty, &data.inputs);
#![feature(crate_visibility_modifier)]
#![feature(marker_trait_attr)]
#![feature(specialization)]
+#![feature(or_patterns)]
#![recursion_limit = "256"]
use rustc_ast::ast;
param_mode: ParamMode,
mut itctx: ImplTraitContext<'_, 'hir>,
) -> (GenericArgsCtor<'hir>, bool) {
- let &AngleBracketedArgs { ref args, ref constraints, .. } = data;
- let has_non_lt_args = args.iter().any(|arg| match arg {
- ast::GenericArg::Lifetime(_) => false,
- ast::GenericArg::Type(_) => true,
- ast::GenericArg::Const(_) => true,
+ let has_non_lt_args = data.args.iter().any(|arg| match arg {
+ AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_)) => false,
+ AngleBracketedArg::Arg(ast::GenericArg::Type(_) | ast::GenericArg::Const(_))
+ | AngleBracketedArg::Constraint(_) => true,
});
- (
- GenericArgsCtor {
- args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
- bindings: self.arena.alloc_from_iter(
- constraints.iter().map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())),
- ),
- parenthesized: false,
- },
- !has_non_lt_args && param_mode == ParamMode::Optional,
- )
+ let args = data
+ .args
+ .iter()
+ .filter_map(|arg| match arg {
+ AngleBracketedArg::Arg(arg) => Some(self.lower_generic_arg(arg, itctx.reborrow())),
+ AngleBracketedArg::Constraint(_) => None,
+ })
+ .collect();
+ let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
+ AngleBracketedArg::Constraint(c) => {
+ Some(self.lower_assoc_ty_constraint(c, itctx.reborrow()))
+ }
+ AngleBracketedArg::Arg(_) => None,
+ }));
+ let ctor = GenericArgsCtor { args, bindings, parenthesized: false };
+ (ctor, !has_non_lt_args && param_mode == ParamMode::Optional)
}
fn lower_parenthesized_parameter_data(
.emit();
}
}
+
+ /// Enforce generic args coming before constraints in `<...>` of a path segment.
+ fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
+ // Early exit in case it's partitioned as it should be.
+ if data.args.iter().is_partitioned(|arg| matches!(arg, AngleBracketedArg::Arg(_))) {
+ return;
+ }
+ // Find all generic argument coming after the first constraint...
+ let mut misplaced_args = Vec::new();
+ let mut first = None;
+ for arg in &data.args {
+ match (arg, first) {
+ (AngleBracketedArg::Arg(a), Some(_)) => misplaced_args.push(a.span()),
+ (AngleBracketedArg::Constraint(c), None) => first = Some(c.span),
+ (AngleBracketedArg::Arg(_), None) | (AngleBracketedArg::Constraint(_), Some(_)) => {
+ }
+ }
+ }
+ // ...and then error:
+ self.err_handler()
+ .struct_span_err(
+ data.span,
+ "constraints in a path segment must come after generic arguments",
+ )
+ .span_labels(
+ misplaced_args,
+ "this generic argument must come before the first constraint",
+ )
+ .span_label(first.unwrap(), "the first constraint is provided here")
+ .emit();
+ }
}
/// Checks that generic parameters are in the correct order,
fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
match *generic_args {
GenericArgs::AngleBracketed(ref data) => {
- walk_list!(self, visit_generic_arg, &data.args);
-
- // Type bindings such as `Item = impl Debug` in `Iterator<Item = Debug>`
- // are allowed to contain nested `impl Trait`.
- self.with_impl_trait(None, |this| {
- walk_list!(
- this,
- visit_assoc_ty_constraint_from_generic_args,
- &data.constraints
- );
- });
+ self.check_generic_args_before_constraints(data);
+
+ for arg in &data.args {
+ match arg {
+ AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg),
+ // Type bindings such as `Item = impl Debug` in `Iterator<Item = Debug>`
+ // are allowed to contain nested `impl Trait`.
+ AngleBracketedArg::Constraint(constraint) => {
+ self.with_impl_trait(None, |this| {
+ this.visit_assoc_ty_constraint_from_generic_args(constraint);
+ });
+ }
+ }
+ }
}
GenericArgs::Parenthesized(ref data) => {
walk_list!(self, visit_ty, &data.inputs);
-#![feature(bindings_after_at)]
//! The `rustc_ast_passes` crate contains passes which validate the AST in `syntax`
//! parsed by `rustc_parse` and then lowered, after the passes in this crate,
//! by `rustc_ast_lowering`.
//!
//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`.
+#![feature(bindings_after_at)]
+#![feature(iter_is_partitioned)]
+
pub mod ast_validation;
pub mod feature_gate;
pub mod node_count;
match *args {
ast::GenericArgs::AngleBracketed(ref data) => {
self.s.word("<");
-
- self.commasep(Inconsistent, &data.args, |s, generic_arg| {
- s.print_generic_arg(generic_arg)
+ self.commasep(Inconsistent, &data.args, |s, arg| match arg {
+ ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
+ ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c),
});
-
- let mut comma = !data.args.is_empty();
-
- for constraint in data.constraints.iter() {
- if comma {
- self.word_space(",")
- }
- self.print_ident(constraint.ident);
- self.s.space();
- match constraint.kind {
- ast::AssocTyConstraintKind::Equality { ref ty } => {
- self.word_space("=");
- self.print_type(ty);
- }
- ast::AssocTyConstraintKind::Bound { ref bounds } => {
- self.print_type_bounds(":", &*bounds);
- }
- }
- comma = true;
- }
-
self.s.word(">")
}
}
}
+ fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
+ self.print_ident(constraint.ident);
+ self.s.space();
+ match &constraint.kind {
+ ast::AssocTyConstraintKind::Equality { ty } => {
+ self.word_space("=");
+ self.print_type(ty);
+ }
+ ast::AssocTyConstraintKind::Bound { bounds } => {
+ self.print_type_bounds(":", &*bounds);
+ }
+ }
+ }
+
crate fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
match generic_arg {
GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))),
);
let args = if !args.is_empty() {
- ast::AngleBracketedArgs { args, constraints: Vec::new(), span }.into()
+ let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect();
+ ast::AngleBracketedArgs { args, span }.into()
} else {
None
};
match seg.args.as_ref().map(|generic_arg| &**generic_arg) {
None => false,
Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
- let types = data.args.iter().filter_map(|arg| match arg {
- ast::GenericArg::Type(ty) => Some(ty),
- _ => None,
- });
- any_involves_impl_trait(types)
- || data.constraints.iter().any(|c| match c.kind {
+ data.args.iter().any(|arg| match arg {
+ ast::AngleBracketedArg::Arg(arg) => match arg {
+ ast::GenericArg::Type(ty) => involves_impl_trait(ty),
+ ast::GenericArg::Lifetime(_)
+ | ast::GenericArg::Const(_) => false,
+ },
+ ast::AngleBracketedArg::Constraint(c) => match c.kind {
ast::AssocTyConstraintKind::Bound { .. } => true,
ast::AssocTyConstraintKind::Equality { ref ty } => {
involves_impl_trait(ty)
}
- })
+ },
+ })
}
Some(&ast::GenericArgs::Parenthesized(ref data)) => {
any_involves_impl_trait(data.inputs.iter())
use super::ty::{AllowPlus, RecoverQPath};
use super::{Parser, TokenType};
use crate::maybe_whole;
-use rustc_ast::ast::{
- self, AngleBracketedArgs, Ident, ParenthesizedArgs, Path, PathSegment, QSelf,
-};
-use rustc_ast::ast::{
- AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode, GenericArg,
-};
+use rustc_ast::ast::{self, AngleBracketedArg, AngleBracketedArgs, GenericArg, ParenthesizedArgs};
+use rustc_ast::ast::{AnonConst, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
+use rustc_ast::ast::{Ident, Path, PathSegment, QSelf};
use rustc_ast::token::{self, Token};
use rustc_errors::{pluralize, Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
let lo = self.token.span;
let args = if self.eat_lt() {
// `<'a, T, A = U>`
- let (args, constraints) =
- self.parse_generic_args_with_leading_angle_bracket_recovery(style, lo)?;
+ let args =
+ self.parse_angle_args_with_leading_angle_bracket_recovery(style, lo)?;
self.expect_gt()?;
let span = lo.to(self.prev_token.span);
- AngleBracketedArgs { args, constraints, span }.into()
+ AngleBracketedArgs { args, span }.into()
} else {
// `(T, U) -> R`
let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
/// Parses generic args (within a path segment) with recovery for extra leading angle brackets.
/// For the purposes of understanding the parsing logic of generic arguments, this function
- /// can be thought of being the same as just calling `self.parse_generic_args()` if the source
+ /// can be thought of being the same as just calling `self.parse_angle_args()` if the source
/// had the correct amount of leading angle brackets.
///
/// ```ignore (diagnostics)
/// bar::<<<<T as Foo>::Output>();
/// ^^ help: remove extra angle brackets
/// ```
- fn parse_generic_args_with_leading_angle_bracket_recovery(
+ fn parse_angle_args_with_leading_angle_bracket_recovery(
&mut self,
style: PathStyle,
lo: Span,
- ) -> PResult<'a, (Vec<GenericArg>, Vec<AssocTyConstraint>)> {
+ ) -> PResult<'a, Vec<AngleBracketedArg>> {
// We need to detect whether there are extra leading left angle brackets and produce an
// appropriate error and suggestion. This cannot be implemented by looking ahead at
// upcoming tokens for a matching `>` character - if there are unmatched `<` tokens
let snapshot = if is_first_invocation { Some(self.clone()) } else { None };
debug!("parse_generic_args_with_leading_angle_bracket_recovery: (snapshotting)");
- match self.parse_generic_args() {
- Ok(value) => Ok(value),
+ match self.parse_angle_args() {
+ Ok(args) => Ok(args),
Err(ref mut e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => {
// Cancel error from being unable to find `>`. We know the error
// must have been this due to a non-zero unmatched angle bracket
.emit();
// Try again without unmatched angle bracket characters.
- self.parse_generic_args()
+ self.parse_angle_args()
}
Err(e) => Err(e),
}
}
- /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
+ /// Parses (possibly empty) list of generic arguments / associated item constraints,
/// possibly including trailing comma.
- fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<AssocTyConstraint>)> {
+ fn parse_angle_args(&mut self) -> PResult<'a, Vec<AngleBracketedArg>> {
let mut args = Vec::new();
- let mut constraints = Vec::new();
- let mut misplaced_assoc_ty_constraints: Vec<Span> = Vec::new();
- let mut assoc_ty_constraints: Vec<Span> = Vec::new();
-
- let args_lo = self.token.span;
-
loop {
if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
// Parse lifetime argument.
- args.push(GenericArg::Lifetime(self.expect_lifetime()));
- misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
+ args.push(AngleBracketedArg::Arg(GenericArg::Lifetime(self.expect_lifetime())));
} else if self.check_ident()
- && self.look_ahead(1, |t| t == &token::Eq || t == &token::Colon)
+ && self.look_ahead(1, |t| matches!(t.kind, token::Eq | token::Colon))
{
// Parse associated type constraint.
let lo = self.token.span;
let kind = if self.eat(&token::Eq) {
AssocTyConstraintKind::Equality { ty: self.parse_ty()? }
} else if self.eat(&token::Colon) {
- AssocTyConstraintKind::Bound {
- bounds: self.parse_generic_bounds(Some(self.prev_token.span))?,
- }
+ let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
+ AssocTyConstraintKind::Bound { bounds }
} else {
unreachable!();
};
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
}
- constraints.push(AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, kind, span });
- assoc_ty_constraints.push(span);
+ let constraint = AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, kind, span };
+ args.push(AngleBracketedArg::Constraint(constraint));
} else if self.check_const_arg() {
// Parse const argument.
let expr = if let token::OpenDelim(token::Brace) = self.token.kind {
self.parse_literal_maybe_minus()?
};
let value = AnonConst { id: ast::DUMMY_NODE_ID, value: expr };
- args.push(GenericArg::Const(value));
- misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
+ args.push(AngleBracketedArg::Arg(GenericArg::Const(value)));
} else if self.check_type() {
// Parse type argument.
- args.push(GenericArg::Type(self.parse_ty()?));
- misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
+ args.push(AngleBracketedArg::Arg(GenericArg::Type(self.parse_ty()?)));
} else {
break;
}
}
}
- // FIXME: we would like to report this in ast_validation instead, but we currently do not
- // preserve ordering of generic parameters with respect to associated type binding, so we
- // lose that information after parsing.
- if !misplaced_assoc_ty_constraints.is_empty() {
- let mut err = self.struct_span_err(
- args_lo.to(self.prev_token.span),
- "associated type bindings must be declared after generic parameters",
- );
- for span in misplaced_assoc_ty_constraints {
- err.span_label(
- span,
- "this associated type binding should be moved after the generic parameters",
- );
- }
- err.emit();
- }
-
- Ok((args, constraints))
+ Ok(args)
}
}
match **generic_args {
ast::GenericArgs::AngleBracketed(ref data) => {
for arg in &data.args {
- if let ast::GenericArg::Type(ty) = arg {
+ if let ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) = arg {
self.visit_ty(ty);
}
}
if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
for arg in &data.args {
match arg {
- ast::GenericArg::Type(ty) => self.visit_ty(ty),
+ ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) => self.visit_ty(ty),
_ => {}
}
}
--- /dev/null
+// check-pass
+
+#[cfg(FALSE)]
+fn syntax() {
+ foo::<T = u8, T: Ord, String>();
+ foo::<T = u8, 'a, T: Ord>();
+}
+
+fn main() {}
trait Trait<T> { type Item; }
pub fn test<W, I: Trait<Item=(), W> >() {}
-//~^ ERROR associated type bindings must be declared after generic parameters
+//~^ ERROR constraints in a path segment must come after generic arguments
fn main() { }
-error: associated type bindings must be declared after generic parameters
- --> $DIR/issue-32214.rs:3:25
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/issue-32214.rs:3:24
|
LL | pub fn test<W, I: Trait<Item=(), W> >() {}
- | -------^^^
- | |
- | this associated type binding should be moved after the generic parameters
+ | ^-------^^-^
+ | | |
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
error: aborting due to previous error
-// ignore-tidy-linelength
-
#![allow(warnings)]
// This test verifies that the suggestion to move types before associated type bindings
type C;
}
-struct A<T, M: One<A=(), T>> { //~ ERROR associated type bindings must be declared after generic parameters
+struct A<T, M: One<A=(), T>> {
+//~^ ERROR constraints in a path segment must come after generic arguments
m: M,
t: T,
}
struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
-//~^ ERROR associated type bindings must be declared after generic parameters
+//~^ ERROR constraints in a path segment must come after generic arguments
//~^^ ERROR type provided when a lifetime was expected
m: M,
t: &'a T,
}
-struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> { //~ ERROR associated type bindings must be declared after generic parameters
+struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> {
+//~^ ERROR constraints in a path segment must come after generic arguments
m: M,
t: T,
u: U,
}
struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
-//~^ ERROR associated type bindings must be declared after generic parameters
+//~^ ERROR constraints in a path segment must come after generic arguments
//~^^ ERROR type provided when a lifetime was expected
m: M,
t: &'a T,
v: &'c V,
}
-struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> { //~ ERROR associated type bindings must be declared after generic parameters
+struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> {
+//~^ ERROR constraints in a path segment must come after generic arguments
m: M,
t: T,
u: U,
}
struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
-//~^ ERROR associated type bindings must be declared after generic parameters
+//~^ ERROR constraints in a path segment must come after generic arguments
//~^^ ERROR lifetime provided when a type was expected
m: M,
t: &'a T,
v: &'c V,
}
-struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> { //~ ERROR associated type bindings must be declared after generic parameters
+struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> {
+//~^ ERROR constraints in a path segment must come after generic arguments
m: M,
t: T,
u: U,
}
struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
-//~^ ERROR associated type bindings must be declared after generic parameters
+//~^ ERROR constraints in a path segment must come after generic arguments
//~^^ ERROR lifetime provided when a type was expected
m: M,
t: &'a T,
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:28:20
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:26:19
|
LL | struct A<T, M: One<A=(), T>> {
- | ----^^^
- | |
- | this associated type binding should be moved after the generic parameters
+ | ^----^^-^
+ | | |
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:34:37
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:33:36
|
LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
- | ----^^^^^^^
- | |
- | this associated type binding should be moved after the generic parameters
+ | ^----^^-^^--^
+ | | | |
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:41:28
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:40:27
|
LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> {
- | ----^^----^^----^^^^^^^^^
- | | | |
- | | | this associated type binding should be moved after the generic parameters
- | | this associated type binding should be moved after the generic parameters
- | this associated type binding should be moved after the generic parameters
+ | ^----^^^^^^^^^^^^^^-^^-^^-^
+ | | | | |
+ | | | | this generic argument must come before the first constraint
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:48:53
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:48:52
|
LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U, V, 'a, 'b, 'c>> {
- | ----^^----^^----^^^^^^^^^^^^^^^^^^^^^
- | | | |
- | | | this associated type binding should be moved after the generic parameters
- | | this associated type binding should be moved after the generic parameters
- | this associated type binding should be moved after the generic parameters
+ | ^----^^^^^^^^^^^^^^-^^-^^-^^--^^--^^--^
+ | | | | | | | |
+ | | | | | | | this generic argument must come before the first constraint
+ | | | | | | this generic argument must come before the first constraint
+ | | | | | this generic argument must come before the first constraint
+ | | | | this generic argument must come before the first constraint
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:57:28
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:57:27
|
LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> {
- | ^^^----^^----^^----^^^^^^
- | | | |
- | | | this associated type binding should be moved after the generic parameters
- | | this associated type binding should be moved after the generic parameters
- | this associated type binding should be moved after the generic parameters
+ | ^^^^----^^^^^^^^^^^^^^-^^-^
+ | | | |
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:64:53
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:65:52
|
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
- | ^^^^^^^----^^----^^----^^^^^^^^^^^^^^
- | | | |
- | | | this associated type binding should be moved after the generic parameters
- | | this associated type binding should be moved after the generic parameters
- | this associated type binding should be moved after the generic parameters
+ | ^^^^^^^^----^^^^^^^^^^^^^^-^^--^^-^^--^
+ | | | | | |
+ | | | | | this generic argument must come before the first constraint
+ | | | | this generic argument must come before the first constraint
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:73:28
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:74:27
|
LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> {
- | ^^^----^^----^^^^^----^^^
- | | | |
- | | | this associated type binding should be moved after the generic parameters
- | | this associated type binding should be moved after the generic parameters
- | this associated type binding should be moved after the generic parameters
+ | ^^^^----^^^^^^^^-^^^^^^^^-^
+ | | | |
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
-error: associated type bindings must be declared after generic parameters
- --> $DIR/suggest-move-types.rs:80:53
+error: constraints in a path segment must come after generic arguments
+ --> $DIR/suggest-move-types.rs:82:52
|
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
- | ^^^^^^^----^^----^^^^^^^^^----^^^^^^^
- | | | |
- | | | this associated type binding should be moved after the generic parameters
- | | this associated type binding should be moved after the generic parameters
- | this associated type binding should be moved after the generic parameters
+ | ^^^^^^^^----^^^^^^^^-^^--^^^^^^^^-^^--^
+ | | | | | |
+ | | | | | this generic argument must come before the first constraint
+ | | | | this generic argument must come before the first constraint
+ | | | this generic argument must come before the first constraint
+ | | this generic argument must come before the first constraint
+ | the first constraint is provided here
error[E0747]: type provided when a lifetime was expected
- --> $DIR/suggest-move-types.rs:34:43
+ --> $DIR/suggest-move-types.rs:33:43
|
LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
| ^
= note: lifetime arguments must be provided before type arguments
error[E0747]: lifetime provided when a type was expected
- --> $DIR/suggest-move-types.rs:64:56
+ --> $DIR/suggest-move-types.rs:65:56
|
LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=(), U, 'b, V, 'c>> {
| ^^
= note: type arguments must be provided before lifetime arguments
error[E0747]: lifetime provided when a type was expected
- --> $DIR/suggest-move-types.rs:80:56
+ --> $DIR/suggest-move-types.rs:82:56
|
LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, 'b, C=(), V, 'c>> {
| ^^