}
}
+ fn suggest_correct_generic_order(&self, data: &AngleBracketedArgs) -> String {
+ // Lifetimes always come first.
+ let lt_sugg = data.args.iter().filter_map(|arg| match arg {
+ AngleBracketedArg::Arg(lt @ GenericArg::Lifetime(_)) => {
+ Some(pprust::to_string(|s| s.print_generic_arg(lt)))
+ }
+ _ => None,
+ });
+ let args_sugg = data.args.iter().filter_map(|a| match a {
+ AngleBracketedArg::Arg(GenericArg::Lifetime(_)) => None,
+ AngleBracketedArg::Arg(arg) => Some(pprust::to_string(|s| s.print_generic_arg(arg))),
+ AngleBracketedArg::Constraint(_) => None,
+ });
+ // Cosntraints always come last.
+ let constraint_sugg = data.args.iter().filter_map(|a| match a {
+ AngleBracketedArg::Arg(_) => None,
+ AngleBracketedArg::Constraint(c) => {
+ Some(pprust::to_string(|s| s.print_assoc_constraint(c)))
+ }
+ });
+ format!(
+ "<{}>",
+ lt_sugg.chain(args_sugg).chain(constraint_sugg).collect::<Vec<String>>().join(", ")
+ )
+ }
+
/// 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.
_ => None,
})
.collect::<Vec<_>>();
- let snippet_span = match &constraint_spans[..] {
- [single] => *single,
- [first, .., last] => first.to(*last),
- [] => unreachable!(),
- };
- let removal_span = match &arg_spans[..] {
- [first, ..] => snippet_span.until(*first),
- [] => unreachable!(),
- };
- let sugg_span = match &arg_spans[..] {
- [.., last] => last.shrink_to_hi(),
- [] => unreachable!(),
- };
- let snippet = self.session.source_map().span_to_snippet(snippet_span).unwrap();
+ let args_len = arg_spans.len();
let constraint_len = constraint_spans.len();
// ...and then error:
self.err_handler()
),
)
.span_labels(arg_spans, "generic argument")
- .multipart_suggestion(
- "move the constraints after the generic arguments",
- vec![
- (removal_span, String::new()),
- (sugg_span.shrink_to_lo(), ", ".to_string()),
- (sugg_span, snippet),
- ],
+ .span_suggestion_verbose(
+ data.span,
+ &format!(
+ "move the constraint{} after the generic argument{}",
+ pluralize!(constraint_len),
+ pluralize!(args_len)
+ ),
+ self.suggest_correct_generic_order(&data),
Applicability::MachineApplicable,
)
.emit();
| |
| the constraint is provided here
|
-help: move the constraints after the generic arguments
+help: move the constraint after the generic argument
|
-LL | struct A<T, M: One<T, A=()>> {
- | --^^^^
+LL | struct A<T, M: One<T, A = ()>> {
+ | ^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:33:43
| | generic argument
| the constraint is provided here
|
-help: move the constraints after the generic arguments
+help: move the constraint after the generic arguments
|
-LL | struct Al<'a, T, M: OneWithLifetime<T, 'a, A=()>> {
- | -- ^^^^
+LL | struct Al<'a, T, M: OneWithLifetime<'a, T, A = ()>> {
+ | ^^^^^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:40:46
|
help: move the constraints after the generic arguments
|
-LL | struct B<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> {
- | -- ^^^^^^^^^^^^^^^^
+LL | struct B<T, U, V, M: Three<T, U, V, A = (), B = (), C = ()>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:48:71
|
help: move the constraints after the generic arguments
|
-LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, U, V, 'a, 'b, 'c, A=(), B=(), C=()>> {
- | -- ^^^^^^^^^^^^^^^^
+LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A = (), B = (), C = ()>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:57:28
|
help: move the constraints after the generic arguments
|
-LL | struct C<T, U, V, M: Three<A=(), B=(), C=(), U, V, A=(), B=(), C=()>> {
- | -- ^^^^^^^^^^^^^^^^
+LL | struct C<T, U, V, M: Three<T, U, V, A = (), B = (), C = ()>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:65:53
|
help: move the constraints after the generic arguments
|
-LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), U, 'b, V, 'c, A=(), B=(), C=()>> {
- | -- ^^^^^^^^^^^^^^^^
+LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A = (), B = (), C = ()>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:74:28
|
help: move the constraints after the generic arguments
|
-LL | struct D<T, U, V, M: Three<A=(), B=(), U, C=(), V, A=(), B=(), U, C=()>> {
- | -- ^^^^^^^^^^^^^^^^^^^
+LL | struct D<T, U, V, M: Three<T, U, V, A = (), B = (), C = ()>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: generic arguments must come before the first constraint
--> $DIR/suggest-move-types.rs:82:53
|
help: move the constraints after the generic arguments
|
-LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), U, 'b, C=(), V, 'c, A=(), B=(), U, 'b, C=()>> {
- | -- ^^^^^^^^^^^^^^^^^^^^^^^
+LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<'a, 'b, 'c, T, U, V, A = (), B = (), C = ()>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0747]: type provided when a lifetime was expected
--> $DIR/suggest-move-types.rs:33:43