diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index aa5a696b09c3b..e7068bcaf2b90 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -826,6 +826,8 @@ pub struct GenericParamCount {
     pub lifetimes: usize,
     pub types: usize,
     pub consts: usize,
+
+    pub type_defaults: usize,
 }
 
 /// Information about the formal type/lifetime parameters associated
@@ -861,7 +863,10 @@ impl<'tcx> Generics {
         for param in &self.params {
             match param.kind {
                 GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
-                GenericParamDefKind::Type { .. } => own_counts.types += 1,
+                GenericParamDefKind::Type { has_default, .. } => {
+                    own_counts.types += 1;
+                    own_counts.type_defaults += has_default as usize;
+                }
                 GenericParamDefKind::Const => own_counts.consts += 1,
             };
         }
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index 3bfb2d3f1b0f9..d8e51782cd35a 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -354,19 +354,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let arg_counts = args.own_counts();
         let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
 
-        let mut defaults: ty::GenericParamCount = Default::default();
-        for param in &def.params {
-            match param.kind {
-                GenericParamDefKind::Lifetime => {}
-                GenericParamDefKind::Type { has_default, .. } => {
-                    defaults.types += has_default as usize
-                }
-                GenericParamDefKind::Const => {
-                    // FIXME(const_generics:defaults)
-                }
-            };
-        }
-
         if position != GenericArgPosition::Type && !args.bindings.is_empty() {
             AstConv::prohibit_assoc_ty_binding(tcx, args.bindings[0].span);
         }
@@ -374,163 +361,280 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let explicit_late_bound =
             Self::prohibit_explicit_late_bound_lifetimes(tcx, def, args, position);
 
-        let check_kind_count = |kind,
-                                required,
-                                permitted,
-                                provided,
-                                offset,
-                                unexpected_spans: &mut Vec<Span>,
-                                silent| {
-            debug!(
-                "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}",
-                kind, required, permitted, provided, offset
-            );
-            // We enforce the following: `required` <= `provided` <= `permitted`.
-            // For kinds without defaults (e.g.., lifetimes), `required == permitted`.
-            // For other kinds (i.e., types), `permitted` may be greater than `required`.
-            if required <= provided && provided <= permitted {
-                return Ok(());
-            }
-
-            if silent {
-                return Err((0i32, None));
-            }
+        let check_lifetime_count =
+            |required, provided, unexpected_spans: &mut Vec<Span>, silent| {
+                if required == provided {
+                    return Ok(());
+                } else if silent {
+                    return Err(());
+                }
 
-            // Unfortunately lifetime and type parameter mismatches are typically styled
-            // differently in diagnostics, which means we have a few cases to consider here.
-            let (bound, quantifier) = if required != permitted {
-                if provided < required {
-                    (required, "at least ")
+                let (spans, label) = if provided > required {
+                    // In the case when the user has provided too many arguments,
+                    // we want to point to the unexpected arguments.
+                    let spans: Vec<Span> = args
+                        .args
+                        .iter()
+                        .skip(required)
+                        .filter_map(|arg| match arg {
+                            GenericArg::Lifetime(_) => Some(arg.span()),
+                            _ => None,
+                        })
+                        .take(provided - required)
+                        .collect();
+                    unexpected_spans.extend(spans.clone());
+                    (spans, format!("unexpected lifetime argument"))
                 } else {
-                    // provided > permitted
-                    (permitted, "at most ")
+                    (
+                        vec![span],
+                        format!("expected {} lifetime argument{}", required, pluralize!(required)),
+                    )
+                };
+
+                let mut err = tcx.sess.struct_span_err_with_code(
+                    spans.clone(),
+                    &format!(
+                        "wrong number of lifetime arguments: expected {}, found {}",
+                        required, provided,
+                    ),
+                    DiagnosticId::Error("E0107".into()),
+                );
+                for span in spans {
+                    err.span_label(span, label.as_str());
                 }
-            } else {
-                (required, "")
+                err.emit();
+
+                Err(())
             };
 
-            let (spans, label) = if required == permitted && provided > permitted {
-                // In the case when the user has provided too many arguments,
-                // we want to point to the unexpected arguments.
-                let spans: Vec<Span> = args.args[offset + permitted..offset + provided]
-                    .iter()
-                    .map(|arg| arg.span())
-                    .collect();
-                unexpected_spans.extend(spans.clone());
-                (spans, format!("unexpected {} argument", kind))
-            } else {
-                (
-                    vec![span],
-                    format!(
-                        "expected {}{} {} argument{}",
-                        quantifier,
-                        bound,
-                        kind,
-                        pluralize!(bound),
-                    ),
+        let mut unexpected_spans = vec![];
+
+        let lifetime_count_correct =
+            if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes {
+                check_lifetime_count(
+                    param_counts.lifetimes,
+                    arg_counts.lifetimes,
+                    &mut unexpected_spans,
+                    explicit_late_bound == ExplicitLateBound::Yes,
                 )
+            } else {
+                Ok(())
+            };
+
+        // Emit a help message if it's possible that a type could be surrounded in braces
+        let add_suggestion_type_const_mismatch = move |arg: &hir::GenericArg<'_>| {
+            if !matches!(arg, &GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })) {
+                return None;
+            }
+            let span = arg.span();
+            Some(move |err: &mut rustc_errors::DiagnosticBuilder<'_>| {
+                let suggestions = vec![
+                    (span.shrink_to_lo(), String::from("{ ")),
+                    (span.shrink_to_hi(), String::from(" }")),
+                ];
+                err.multipart_suggestion(
+                    "If this generic argument was intended as a const parameter, \
+                  try surrounding it with braces:",
+                    suggestions,
+                    Applicability::MaybeIncorrect,
+                );
+            })
+        };
+
+        // FIXME(const_generics:defaults)
+        let has_self = has_self as usize;
+        let permitted_types = param_counts.types - has_self;
+        let required_types = permitted_types - param_counts.type_defaults;
+        let requires_type_check =
+            arg_counts.types > permitted_types || arg_counts.types < required_types;
+        let requires_const_check = arg_counts.consts != param_counts.consts;
+        let mut arg_count_correct = Ok(());
+
+        let handle_mismatch = |param: &ty::GenericParamDef,
+                               arg: &hir::GenericArg<'_>,
+                               const_mismatches: &mut Vec<(Span, String)>,
+                               type_mismatches: &mut Vec<(Span, String)>,
+                               type_notes: &mut Vec<Box<_>>| {
+            let (mismatches, label) = match (&param.kind, arg) {
+                // No error if the types line up
+                (GenericParamDefKind::Lifetime, GenericArg::Lifetime(_))
+                | (GenericParamDefKind::Const, GenericArg::Const(_))
+                | (GenericParamDefKind::Type { .. }, GenericArg::Type(_)) => return,
+
+                (GenericParamDefKind::Lifetime, GenericArg::Const(_)) => {
+                    let label = format!("expected lifetime, found {}", arg.descr());
+                    (const_mismatches, label)
+                }
+                (GenericParamDefKind::Lifetime, GenericArg::Type(_)) => {
+                    let label = format!("expected lifetime, found {}", arg.descr());
+                    (type_mismatches, label)
+                }
+
+                (GenericParamDefKind::Const, GenericArg::Type(_)) => {
+                    if let Some(note) = add_suggestion_type_const_mismatch(arg) {
+                        type_notes.push(Box::new(note));
+                    }
+                    let label = format!("expected const, found {}", arg.descr());
+                    (type_mismatches, label)
+                }
+                (GenericParamDefKind::Const, GenericArg::Lifetime(_)) => {
+                    let label = format!("expected const, found {}", arg.descr());
+                    (const_mismatches, label)
+                }
+                (GenericParamDefKind::Type { .. }, GenericArg::Const(_)) => {
+                    (const_mismatches, format!("expected type, found const"))
+                }
+                (GenericParamDefKind::Type { .. }, GenericArg::Lifetime(_)) => {
+                    (type_mismatches, format!("expected type, found lifetime"))
+                }
+            };
+            mismatches.push((arg.span(), label));
+        };
+
+        let handle_extra_arg =
+            |arg: &hir::GenericArg<'_>,
+             const_mismatches: &mut Vec<(Span, String)>,
+             type_mismatches: &mut Vec<(Span, String)>| match arg {
+                GenericArg::Const(_) => {
+                    let label = String::from("unexpected const argument");
+                    const_mismatches.push((arg.span(), label));
+                }
+                GenericArg::Type(_) => {
+                    let label = String::from("unexpected type argument");
+                    type_mismatches.push((arg.span(), label));
+                }
+                _ => {}
             };
 
+        let misplaced_err = |mismatches: Vec<_>, unexpected_spans: &mut Vec<_>, kind| {
+            let (spans, labels): (Vec<Span>, Vec<String>) = mismatches.into_iter().unzip();
             let mut err = tcx.sess.struct_span_err_with_code(
                 spans.clone(),
-                &format!(
-                    "wrong number of {} arguments: expected {}{}, found {}",
-                    kind, quantifier, bound, provided,
-                ),
+                &format!("misplaced {} arguments", kind),
                 DiagnosticId::Error("E0107".into()),
             );
-            for span in spans {
+            for (span, label) in spans.iter().cloned().zip(labels.iter()) {
                 err.span_label(span, label.as_str());
             }
-
-            assert_ne!(bound, provided);
-            Err((bound as i32 - provided as i32, Some(err)))
+            unexpected_spans.extend(spans.into_iter());
+            err
         };
 
-        let mut unexpected_spans = vec![];
-
-        let mut lifetime_count_correct = Ok(());
-        if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes {
-            lifetime_count_correct = check_kind_count(
-                "lifetime",
-                param_counts.lifetimes,
-                param_counts.lifetimes,
-                arg_counts.lifetimes,
-                0,
-                &mut unexpected_spans,
-                explicit_late_bound == ExplicitLateBound::Yes,
-            );
-        }
-
-        // FIXME(const_generics:defaults)
-        let mut const_count_correct = Ok(());
-        if !infer_args || arg_counts.consts > param_counts.consts {
-            const_count_correct = check_kind_count(
-                "const",
-                param_counts.consts,
-                param_counts.consts,
-                arg_counts.consts,
-                arg_counts.lifetimes + arg_counts.types,
-                &mut unexpected_spans,
-                false,
+        let unexpected_err = |mismatches: Vec<(Span, String)>,
+                              unexpected_spans: &mut Vec<_>,
+                              kind,
+                              quantifier,
+                              expected,
+                              given| {
+            let spans: Vec<_> = mismatches.iter().map(|(span, _)| *span).collect();
+            let mut err = tcx.sess.struct_span_err_with_code(
+                spans.clone(),
+                &format!(
+                    "wrong number of {} arguments: expected {}{}, found {}",
+                    kind, quantifier, expected, given,
+                ),
+                DiagnosticId::Error("E0107".into()),
             );
-        }
+            for (span, label) in mismatches.iter() {
+                err.span_label(*span, label.as_str());
+            }
+            unexpected_spans.extend(spans.into_iter());
+            err
+        };
 
-        // Note that type errors are currently be emitted *after* const errors.
-        let mut type_count_correct = Ok(());
-        if !infer_args || arg_counts.types > param_counts.types - defaults.types - has_self as usize
+        if !infer_args
+            || arg_counts.consts > param_counts.consts
+            || arg_counts.types > permitted_types
         {
-            type_count_correct = check_kind_count(
-                "type",
-                param_counts.types - defaults.types - has_self as usize,
-                param_counts.types - has_self as usize,
-                arg_counts.types,
-                arg_counts.lifetimes,
-                &mut unexpected_spans,
-                false,
-            );
-        }
+            if requires_const_check || requires_type_check {
+                arg_count_correct = Err(());
+
+                let mut const_mismatches = vec![];
+                let mut type_mismatches = vec![];
+                let mut type_notes = vec![];
+
+                let lifetimes = arg_counts.lifetimes.min(param_counts.lifetimes);
+                let max_len = args.args.len().max(def.params.len());
+                for i in lifetimes..max_len {
+                    match (def.params.get(i + has_self), args.args.get(i)) {
+                        (Some(param), Some(arg)) => {
+                            handle_mismatch(
+                                param,
+                                arg,
+                                &mut const_mismatches,
+                                &mut type_mismatches,
+                                &mut type_notes,
+                            );
+                        }
+                        (None, Some(arg)) => {
+                            handle_extra_arg(arg, &mut const_mismatches, &mut type_mismatches);
+                        }
+                        (Some(_param), None) => {}
+                        (None, None) => {}
+                    }
+                }
 
-        // Emit a help message if it's possible that a type could be surrounded in braces
-        if let Err((c_mismatch, Some(ref mut _const_err))) = const_count_correct {
-            if let Err((_, Some(ref mut type_err))) = type_count_correct {
-                let possible_matches = args.args[arg_counts.lifetimes..]
-                    .iter()
-                    .filter(|arg| {
-                        matches!(
-                            arg,
-                            GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })
+                if requires_const_check {
+                    if arg_counts.consts < param_counts.consts {
+                        let label = format!(
+                            "expected {} const argument{}",
+                            param_counts.consts,
+                            pluralize!(param_counts.consts)
+                        );
+                        const_mismatches.push((span, label));
+                    };
+                    let mut err = if requires_const_check {
+                        unexpected_err(
+                            const_mismatches,
+                            &mut unexpected_spans,
+                            "const",
+                            "",
+                            param_counts.consts,
+                            arg_counts.consts,
                         )
-                    })
-                    .take(c_mismatch.max(0) as usize);
-                for arg in possible_matches {
-                    let suggestions = vec![
-                        (arg.span().shrink_to_lo(), String::from("{ ")),
-                        (arg.span().shrink_to_hi(), String::from(" }")),
-                    ];
-                    type_err.multipart_suggestion(
-                        "If this generic argument was intended as a const parameter, \
-                        try surrounding it with braces:",
-                        suggestions,
-                        Applicability::MaybeIncorrect,
-                    );
+                    } else {
+                        misplaced_err(const_mismatches, &mut unexpected_spans, "const")
+                    };
+                    err.emit();
                 }
-            }
-        }
 
-        let emit_correct =
-            |correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
-                Ok(()) => Ok(()),
-                Err((_, None)) => Err(()),
-                Err((_, Some(mut err))) => {
+                if requires_type_check || !type_mismatches.is_empty() {
+                    let (bound, quantifier) = if required_types == permitted_types {
+                        (required_types, "")
+                    } else if arg_counts.types < required_types {
+                        (required_types, "at least ")
+                    } else {
+                        (permitted_types, "at most ")
+                    };
+                    if !(arg_counts.types > permitted_types && permitted_types == required_types) {
+                        let label = format!(
+                            "expected {}{} type argument{}",
+                            quantifier,
+                            bound,
+                            pluralize!(bound)
+                        );
+                        type_mismatches.push((span, label));
+                    };
+                    let mut err = if requires_type_check {
+                        unexpected_err(
+                            type_mismatches,
+                            &mut unexpected_spans,
+                            "type",
+                            quantifier,
+                            bound,
+                            arg_counts.types,
+                        )
+                    } else {
+                        misplaced_err(type_mismatches, &mut unexpected_spans, "type")
+                    };
+                    for note in type_notes {
+                        note(&mut err);
+                    }
                     err.emit();
-                    Err(())
                 }
-            };
-
-        let arg_count_correct = emit_correct(lifetime_count_correct)
-            .and(emit_correct(const_count_correct))
-            .and(emit_correct(type_count_correct));
+            }
+        }
+        arg_count_correct = lifetime_count_correct.and(arg_count_correct);
 
         GenericArgCountResult {
             explicit_late_bound,
diff --git a/src/test/ui/const-generics/defaults/intermixed-correct-error.rs b/src/test/ui/const-generics/defaults/intermixed-correct-error.rs
new file mode 100644
index 0000000000000..16ee6fc213be6
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/intermixed-correct-error.rs
@@ -0,0 +1,88 @@
+// Check that ordering of errors is correctly reported even with consts preceding types.
+
+#![feature(const_generics)]
+#![allow(incomplete_features)]
+
+struct Example<'a, const N: usize, T=f32> {
+  s: &'a T,
+}
+
+type Consts = Example<3, 3, 3>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of const arguments
+type Types = Example<f32, f32, f32>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of const arguments
+//~| ERROR wrong number of type arguments
+type Lifetimes = Example<'static, 'static, 'static>;
+//~^ ERROR wrong number of const arguments
+//~| ERROR misplaced type arguments
+//~| wrong number of lifetime
+
+type LtConst1 = Example<'static, 3, 3>;
+//~^ ERROR wrong number of const arguments
+type LtConst2 = Example<3, 'static, 3>;
+//~^ ERROR wrong number of const arguments
+type LtConst3 = Example<3, 3, 'static>;
+//~^ ERROR misplaced type arguments
+
+type LtTy1 = Example<'static, f32, f32>;
+//~^ ERROR wrong number of const arguments
+//~| ERROR wrong number of type arguments
+type LtTy2 = Example<f32, 'static, f32>;
+//~^ ERROR wrong number of const arguments
+//~| ERROR wrong number of type arguments
+type LtTy3 = Example<f32, f32, 'static>;
+//~^ ERROR wrong number of const arguments
+//~| ERROR wrong number of type arguments
+
+type ConstTy1 = Example<3, f32, f32>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of type arguments
+type ConstTy2 = Example<f32, 3, f32>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of type arguments
+type ConstTy3 = Example<f32, f32, 3>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of type arguments
+
+type ConstLt1 = Example<3, 'static, 'static>;
+//~^ ERROR wrong number of lifetime
+type ConstLt2 = Example<'static, 3, 'static>;
+//~^ ERROR wrong number of lifetime
+type ConstLt3 = Example<'static, 'static, 3>;
+//~^ ERROR wrong number of lifetime
+
+type TyLt1 = Example<f32, 'static, 'static>;
+//~^ ERROR wrong number of lifetime
+//~| ERROR wrong number of const
+//~| ERROR misplaced type arguments
+type TyLt2 = Example<'static, f32, 'static>;
+//~^ ERROR wrong number of lifetime
+//~| ERROR wrong number of const
+//~| ERROR misplaced type arguments
+type TyLt3 = Example<'static, 'static, f32>;
+//~^ ERROR wrong number of const
+//~| ERROR wrong number of lifetime
+
+type TyConst1 = Example<f32, 3, 3>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of const
+//~| ERROR misplaced type arguments
+type TyConst2 = Example<3, f32, 3>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of const
+type TyConst3 = Example<3, 3, f32>;
+//~^ ERROR missing lifetime specifier
+//~| ERROR wrong number of const
+//~| ERROR misplaced type arguments
+
+type Intermixed1 = Example<'static, 3, f32>; // ok
+
+
+type Intermixed2 = Example<f32, 'static, 3>;
+//~^ ERROR type provided when a constant was expected
+type Intermixed3 = Example<3, f32, 'static>;
+//~^ ERROR constant provided when a lifetime
+
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/intermixed-correct-error.stderr b/src/test/ui/const-generics/defaults/intermixed-correct-error.stderr
new file mode 100644
index 0000000000000..0d9c55b58419d
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/intermixed-correct-error.stderr
@@ -0,0 +1,407 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:10:23
+   |
+LL | type Consts = Example<3, 3, 3>;
+   |                       ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type Consts<'a> = Example<'a, 3, 3, 3>;
+   |            ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:13:22
+   |
+LL | type Types = Example<f32, f32, f32>;
+   |                      ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type Types<'a> = Example<'a, f32, f32, f32>;
+   |           ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:39:25
+   |
+LL | type ConstTy1 = Example<3, f32, f32>;
+   |                         ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type ConstTy1<'a> = Example<'a, 3, f32, f32>;
+   |              ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:42:25
+   |
+LL | type ConstTy2 = Example<f32, 3, f32>;
+   |                         ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type ConstTy2<'a> = Example<'a, f32, 3, f32>;
+   |              ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:45:25
+   |
+LL | type ConstTy3 = Example<f32, f32, 3>;
+   |                         ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type ConstTy3<'a> = Example<'a, f32, f32, 3>;
+   |              ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:68:25
+   |
+LL | type TyConst1 = Example<f32, 3, 3>;
+   |                         ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type TyConst1<'a> = Example<'a, f32, 3, 3>;
+   |              ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:72:25
+   |
+LL | type TyConst2 = Example<3, f32, 3>;
+   |                         ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type TyConst2<'a> = Example<'a, 3, f32, 3>;
+   |              ^^^^           ^^^
+
+error[E0106]: missing lifetime specifier
+  --> $DIR/intermixed-correct-error.rs:75:25
+   |
+LL | type TyConst3 = Example<3, 3, f32>;
+   |                         ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | type TyConst3<'a> = Example<'a, 3, 3, f32>;
+   |              ^^^^           ^^^
+
+error[E0107]: wrong number of const arguments: expected 1, found 3
+  --> $DIR/intermixed-correct-error.rs:10:26
+   |
+LL | type Consts = Example<3, 3, 3>;
+   |                          ^  ^ unexpected const argument
+   |                          |
+   |                          expected type, found const
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:13:14
+   |
+LL | type Types = Example<f32, f32, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 3
+  --> $DIR/intermixed-correct-error.rs:13:14
+   |
+LL | type Types = Example<f32, f32, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |              |       |         |
+   |              |       |         unexpected type argument
+   |              |       expected const, found type
+   |              expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type Types = Example<{ f32 }, f32, f32>;
+   |                      ^     ^
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 3
+  --> $DIR/intermixed-correct-error.rs:17:35
+   |
+LL | type Lifetimes = Example<'static, 'static, 'static>;
+   |                                   ^^^^^^^  ^^^^^^^ unexpected lifetime argument
+   |                                   |
+   |                                   unexpected lifetime argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:17:18
+   |
+LL | type Lifetimes = Example<'static, 'static, 'static>;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  |                |
+   |                  |                expected const, found lifetime
+   |                  expected 1 const argument
+
+error[E0107]: misplaced type arguments
+  --> $DIR/intermixed-correct-error.rs:17:18
+   |
+LL | type Lifetimes = Example<'static, 'static, 'static>;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  |                         |
+   |                  |                         expected type, found lifetime
+   |                  expected at most 1 type argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:22:37
+   |
+LL | type LtConst1 = Example<'static, 3, 3>;
+   |                                     ^ expected type, found const
+
+error[E0107]: wrong number of const arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:24:28
+   |
+LL | type LtConst2 = Example<3, 'static, 3>;
+   |                            ^^^^^^^  ^ expected type, found const
+   |                            |
+   |                            expected const, found lifetime
+
+error[E0107]: wrong number of const arguments: expected 1, found 2
+
+error[E0107]: misplaced type arguments
+  --> $DIR/intermixed-correct-error.rs:26:17
+   |
+LL | type LtConst3 = Example<3, 3, 'static>;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+   |                 |             |
+   |                 |             expected type, found lifetime
+   |                 expected at most 1 type argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:29:14
+   |
+LL | type LtTy1 = Example<'static, f32, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/intermixed-correct-error.rs:29:14
+   |
+LL | type LtTy1 = Example<'static, f32, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |                |
+   |              |                expected const, found type
+   |              expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type LtTy1 = Example<'static, { f32 }, f32>;
+   |                               ^     ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:32:14
+   |
+LL | type LtTy2 = Example<f32, 'static, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |            |
+   |              |            expected const, found lifetime
+   |              expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/intermixed-correct-error.rs:32:14
+   |
+LL | type LtTy2 = Example<f32, 'static, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:35:14
+   |
+LL | type LtTy3 = Example<f32, f32, 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/intermixed-correct-error.rs:35:14
+   |
+LL | type LtTy3 = Example<f32, f32, 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |            |    |
+   |              |            |    expected type, found lifetime
+   |              |            expected const, found type
+   |              expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type LtTy3 = Example<f32, { f32 }, 'static>;
+   |                           ^     ^
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/intermixed-correct-error.rs:39:17
+   |
+LL | type ConstTy1 = Example<3, f32, f32>;
+   |                 ^^^^^^^^^^^^^^^^^^^^
+   |                 |               |
+   |                 |               unexpected type argument
+   |                 expected at most 1 type argument
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/intermixed-correct-error.rs:42:17
+   |
+LL | type ConstTy2 = Example<f32, 3, f32>;
+   |                 ^^^^^^^^^^^^^^^^^^^^
+   |                 |       |       |
+   |                 |       |       unexpected type argument
+   |                 |       expected const, found type
+   |                 expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type ConstTy2 = Example<{ f32 }, 3, f32>;
+   |                         ^     ^
+
+error[E0107]: wrong number of type arguments: expected at most 1, found 2
+  --> $DIR/intermixed-correct-error.rs:45:17
+   |
+LL | type ConstTy3 = Example<f32, f32, 3>;
+   |                 ^^^^^^^^^^^^^^^^^^^^
+   |                 |       |
+   |                 |       expected const, found type
+   |                 expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type ConstTy3 = Example<{ f32 }, f32, 3>;
+   |                         ^     ^
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:49:28
+   |
+LL | type ConstLt1 = Example<3, 'static, 'static>;
+   |                            ^^^^^^^ unexpected lifetime argument
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:51:37
+   |
+LL | type ConstLt2 = Example<'static, 3, 'static>;
+   |                                     ^^^^^^^ unexpected lifetime argument
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:53:34
+   |
+LL | type ConstLt3 = Example<'static, 'static, 3>;
+   |                                  ^^^^^^^ unexpected lifetime argument
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:56:27
+   |
+LL | type TyLt1 = Example<f32, 'static, 'static>;
+   |                           ^^^^^^^ unexpected lifetime argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:56:14
+   |
+LL | type TyLt1 = Example<f32, 'static, 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |            |
+   |              |            expected const, found lifetime
+   |              expected 1 const argument
+
+error[E0107]: misplaced type arguments
+  --> $DIR/intermixed-correct-error.rs:56:14
+   |
+LL | type TyLt1 = Example<f32, 'static, 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |                     |
+   |              |                     expected type, found lifetime
+   |              expected at most 1 type argument
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:60:36
+   |
+LL | type TyLt2 = Example<'static, f32, 'static>;
+   |                                    ^^^^^^^ unexpected lifetime argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:60:14
+   |
+LL | type TyLt2 = Example<'static, f32, 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
+
+error[E0107]: misplaced type arguments
+  --> $DIR/intermixed-correct-error.rs:60:14
+   |
+LL | type TyLt2 = Example<'static, f32, 'static>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |                |    |
+   |              |                |    expected type, found lifetime
+   |              |                expected const, found type
+   |              expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type TyLt2 = Example<'static, { f32 }, 'static>;
+   |                               ^     ^
+
+error[E0107]: wrong number of lifetime arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:64:31
+   |
+LL | type TyLt3 = Example<'static, 'static, f32>;
+   |                               ^^^^^^^ unexpected lifetime argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 0
+  --> $DIR/intermixed-correct-error.rs:64:14
+   |
+LL | type TyLt3 = Example<'static, 'static, f32>;
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              |                |
+   |              |                expected const, found lifetime
+   |              expected 1 const argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:68:30
+   |
+LL | type TyConst1 = Example<f32, 3, 3>;
+   |                              ^  ^ unexpected const argument
+   |                              |
+   |                              expected type, found const
+
+error[E0107]: misplaced type arguments
+  --> $DIR/intermixed-correct-error.rs:68:17
+   |
+LL | type TyConst1 = Example<f32, 3, 3>;
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |       |
+   |                 |       expected const, found type
+   |                 expected at most 1 type argument
+   |
+help: If this generic argument was intended as a const parameter, try surrounding it with braces:
+   |
+LL | type TyConst1 = Example<{ f32 }, 3, 3>;
+   |                         ^     ^
+
+error[E0107]: wrong number of const arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:72:33
+   |
+LL | type TyConst2 = Example<3, f32, 3>;
+   |                                 ^ unexpected const argument
+
+error[E0107]: wrong number of const arguments: expected 1, found 2
+  --> $DIR/intermixed-correct-error.rs:75:28
+   |
+LL | type TyConst3 = Example<3, 3, f32>;
+   |                            ^ expected type, found const
+
+error[E0107]: misplaced type arguments
+  --> $DIR/intermixed-correct-error.rs:75:17
+   |
+LL | type TyConst3 = Example<3, 3, f32>;
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |             |
+   |                 |             unexpected type argument
+   |                 expected at most 1 type argument
+
+error[E0747]: type provided when a constant was expected
+  --> $DIR/intermixed-correct-error.rs:83:28
+   |
+LL | type Intermixed2 = Example<f32, 'static, 3>;
+   |                            ^^^
+
+error[E0747]: constant provided when a lifetime was expected
+  --> $DIR/intermixed-correct-error.rs:85:28
+   |
+LL | type Intermixed3 = Example<3, f32, 'static>;
+   |                            ^
+   |
+   = note: lifetime arguments must be provided before constant arguments
+
+error: aborting due to 45 previous errors
+
+Some errors have detailed explanations: E0106, E0107, E0747.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/const-generics/invalid-enum.stderr b/src/test/ui/const-generics/invalid-enum.stderr
index 965abbc9cb7b8..0375b4ea5ae9b 100644
--- a/src/test/ui/const-generics/invalid-enum.stderr
+++ b/src/test/ui/const-generics/invalid-enum.stderr
@@ -35,7 +35,10 @@ error[E0107]: wrong number of type arguments: expected at most 1, found 2
   --> $DIR/invalid-enum.rs:31:10
    |
 LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |          |       |
+   |          |       expected const, found type
+   |          expected at most 1 type argument
    |
 help: If this generic argument was intended as a const parameter, try surrounding it with braces:
    |
@@ -52,7 +55,10 @@ error[E0107]: wrong number of type arguments: expected at most 1, found 2
   --> $DIR/invalid-enum.rs:36:10
    |
 LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |          |       |
+   |          |       expected const, found type
+   |          expected at most 1 type argument
    |
 help: If this generic argument was intended as a const parameter, try surrounding it with braces:
    |
@@ -69,7 +75,7 @@ error[E0107]: wrong number of type arguments: expected 0, found 1
   --> $DIR/invalid-enum.rs:21:12
    |
 LL |   test_1::<CompileFlag::A>();
-   |            ^^^^^^^^^^^^^^ unexpected type argument
+   |            ^^^^^^^^^^^^^^ expected const, found type
    |
 help: If this generic argument was intended as a const parameter, try surrounding it with braces:
    |
@@ -86,7 +92,7 @@ error[E0107]: wrong number of type arguments: expected 1, found 2
   --> $DIR/invalid-enum.rs:26:15
    |
 LL |   test_2::<_, CompileFlag::A>(0);
-   |               ^^^^^^^^^^^^^^ unexpected type argument
+   |               ^^^^^^^^^^^^^^ expected const, found type
    |
 help: If this generic argument was intended as a const parameter, try surrounding it with braces:
    |
diff --git a/src/test/ui/const-generics/issues/issue-62878.full.stderr b/src/test/ui/const-generics/issues/issue-62878.full.stderr
index c8b9db8941098..a24c8a55917a3 100644
--- a/src/test/ui/const-generics/issues/issue-62878.full.stderr
+++ b/src/test/ui/const-generics/issues/issue-62878.full.stderr
@@ -14,7 +14,7 @@ error[E0107]: wrong number of type arguments: expected 0, found 1
   --> $DIR/issue-62878.rs:11:11
    |
 LL |     foo::<_, {[1]}>();
-   |           ^ unexpected type argument
+   |           ^ expected const, found type
 
 error[E0308]: mismatched types
   --> $DIR/issue-62878.rs:11:15
diff --git a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
index 47e9dc034efff..d81d7cde6d7bb 100644
--- a/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
+++ b/src/test/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.stderr
@@ -149,7 +149,7 @@ error[E0107]: wrong number of type arguments: expected 0, found 1
   --> $DIR/const-expression-suggest-missing-braces.rs:13:11
    |
 LL |     foo::<BAR + BAR>();
-   |           ^^^^^^^^^ unexpected type argument
+   |           ^^^^^^^^^ expected const, found type
 
 error: aborting due to 15 previous errors; 1 warning emitted
 
diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
index ed090e302cefa..699f8b3bc994b 100644
--- a/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
+++ b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr
@@ -8,7 +8,10 @@ error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/parameter_number_and_kind.rs:13:18
    |
 LL |     type FErr1 = Self::E<'static, 'static>;
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 type argument
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  |                |
+   |                  |                expected type, found lifetime
+   |                  expected 1 type argument
 
 error[E0107]: wrong number of type arguments: expected 1, found 2
   --> $DIR/parameter_number_and_kind.rs:16:41
diff --git a/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr b/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr
index 66950d450a111..df4554579bee8 100644
--- a/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr
+++ b/src/test/ui/generics/generic-impl-more-params-with-defaults.stderr
@@ -2,7 +2,10 @@ error[E0107]: wrong number of type arguments: expected at most 2, found 3
   --> $DIR/generic-impl-more-params-with-defaults.rs:13:5
    |
 LL |     Vec::<isize, Heap, bool>::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 2 type arguments
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |                  |
+   |     |                  unexpected type argument
+   |     expected at most 2 type arguments
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generics/generic-type-more-params-with-defaults.stderr b/src/test/ui/generics/generic-type-more-params-with-defaults.stderr
index 5031930b1bb0a..c7c02e5c8b1ac 100644
--- a/src/test/ui/generics/generic-type-more-params-with-defaults.stderr
+++ b/src/test/ui/generics/generic-type-more-params-with-defaults.stderr
@@ -2,7 +2,10 @@ error[E0107]: wrong number of type arguments: expected at most 2, found 3
   --> $DIR/generic-type-more-params-with-defaults.rs:9:12
    |
 LL |     let _: Vec<isize, Heap, bool>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^ expected at most 2 type arguments
+   |            ^^^^^^^^^^^^^^^^^^^^^^
+   |            |                |
+   |            |                unexpected type argument
+   |            expected at most 2 type arguments
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr
index fdb68ff7126a0..ef72c2af58f85 100644
--- a/src/test/ui/issues/issue-23024.stderr
+++ b/src/test/ui/issues/issue-23024.stderr
@@ -17,7 +17,7 @@ error[E0191]: the value of the associated type `Output` (from trait `FnOnce`) mu
   --> $DIR/issue-23024.rs:9:39
    |
 LL |     println!("{:?}",(vfnfer[0] as dyn Fn)(3));
-   |                                       ^^ help: specify the associated type: `Fn<Output = Type>`
+   |                                       ^^ help: specify the associated type: `Output = Fn`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/privacy/privacy-ns1.stderr b/src/test/ui/privacy/privacy-ns1.stderr
index ccbb5d5c90ff5..acf55c572a5a3 100644
--- a/src/test/ui/privacy/privacy-ns1.stderr
+++ b/src/test/ui/privacy/privacy-ns1.stderr
@@ -56,7 +56,7 @@ error[E0107]: wrong number of const arguments: expected 0, found 1
   --> $DIR/privacy-ns1.rs:35:17
    |
 LL |     let _x: Box<Bar>;
-   |                 ^^^ unexpected const argument
+   |                 ^^^ expected type, found const
 
 error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/privacy-ns1.rs:35:13
diff --git a/src/test/ui/privacy/privacy-ns2.stderr b/src/test/ui/privacy/privacy-ns2.stderr
index dbb269c0ba697..a3364e94e879e 100644
--- a/src/test/ui/privacy/privacy-ns2.stderr
+++ b/src/test/ui/privacy/privacy-ns2.stderr
@@ -82,7 +82,7 @@ error[E0107]: wrong number of const arguments: expected 0, found 1
   --> $DIR/privacy-ns2.rs:41:18
    |
 LL |     let _x : Box<Bar>;
-   |                  ^^^ unexpected const argument
+   |                  ^^^ expected type, found const
 
 error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/privacy-ns2.rs:41:14
@@ -94,7 +94,7 @@ error[E0107]: wrong number of const arguments: expected 0, found 1
   --> $DIR/privacy-ns2.rs:49:17
    |
 LL |     let _x: Box<Bar>;
-   |                 ^^^ unexpected const argument
+   |                 ^^^ expected type, found const
 
 error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/privacy-ns2.rs:49:13
diff --git a/src/test/ui/traits/trait-object-vs-lifetime.stderr b/src/test/ui/traits/trait-object-vs-lifetime.stderr
index ff3fc2a197c66..2c6a8ca76f622 100644
--- a/src/test/ui/traits/trait-object-vs-lifetime.stderr
+++ b/src/test/ui/traits/trait-object-vs-lifetime.stderr
@@ -14,7 +14,10 @@ error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/trait-object-vs-lifetime.rs:11:12
    |
 LL |     let _: S<'static, 'static>;
-   |            ^^^^^^^^^^^^^^^^^^^ expected 1 type argument
+   |            ^^^^^^^^^^^^^^^^^^^
+   |            |          |
+   |            |          expected type, found lifetime
+   |            expected 1 type argument
 
 error[E0224]: at least one trait is required for an object type
   --> $DIR/trait-object-vs-lifetime.rs:14:14