From 12872b6807dbfca49e903ba13e375b960e0bdd4d Mon Sep 17 00:00:00 2001
From: Nick Cameron <nrc@ncameron.org>
Date: Mon, 9 May 2022 12:27:54 +0100
Subject: [PATCH 01/16] Remove explicit-generic-args-with-impl-trait docs from
 unstable book

Signed-off-by: Nick Cameron <nrc@ncameron.org>
---
 .../explicit-generic-args-with-impl-trait.md  | 53 -------------------
 1 file changed, 53 deletions(-)
 delete mode 100644 src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md

diff --git a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md b/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md
deleted file mode 100644
index 479571d85fe05..0000000000000
--- a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# `explicit_generic_args_with_impl_trait`
-
-The tracking issue for this feature is: [#83701]
-
-[#83701]: https://github.com/rust-lang/rust/issues/83701
-
-------------------------
-
-The `explicit_generic_args_with_impl_trait` feature gate lets you specify generic arguments even
-when `impl Trait` is used in argument position.
-
-A simple example is:
-
-```rust
-#![feature(explicit_generic_args_with_impl_trait)]
-
-fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
-
-fn main() {
-    foo::<str>("".to_string());
-}
-```
-
-This is currently rejected:
-
-```text
-error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
- --> src/main.rs:6:11
-  |
-6 |     foo::<str>("".to_string());
-  |           ^^^ explicit generic argument not allowed
-
-```
-
-However it would compile if `explicit_generic_args_with_impl_trait` is enabled.
-
-Note that the synthetic type parameters from `impl Trait` are still implicit and you
-cannot explicitly specify these:
-
-```rust,compile_fail
-#![feature(explicit_generic_args_with_impl_trait)]
-
-fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
-fn bar<T: ?Sized, F: AsRef<T>>(_f: F) {}
-
-fn main() {
-    bar::<str, _>("".to_string()); // Okay
-    bar::<str, String>("".to_string()); // Okay
-
-    foo::<str>("".to_string()); // Okay
-    foo::<str, String>("".to_string()); // Error, you cannot specify `impl Trait` explicitly
-}
-```

From 640a46138839dbb5d9bf8df0e8b9cbec1d8e5ded Mon Sep 17 00:00:00 2001
From: Nick Cameron <nrc@ncameron.org>
Date: Mon, 9 May 2022 15:14:43 +0100
Subject: [PATCH 02/16] Deactivate feature gate
 explicit_generic_args_with_impl_trait

Signed-off-by: Nick Cameron <nrc@ncameron.org>
---
 .../src/error_codes/E0632.md                  |  4 +-
 .../locales/en-US/typeck.ftl                  |  6 --
 compiler/rustc_feature/src/accepted.rs        |  2 +
 compiler/rustc_feature/src/active.rs          |  2 -
 compiler/rustc_typeck/src/astconv/generics.rs | 70 +++++--------------
 compiler/rustc_typeck/src/errors.rs           | 11 ---
 .../impl-trait-with-const-arguments.stderr    | 12 ----
 .../const-args.rs}                            |  3 +-
 .../explicit-generic-args-for-impl.rs         |  2 -
 .../explicit-generic-args-for-impl.stderr     |  4 +-
 .../explicit-generic-args.rs                  |  2 -
 .../feature-gate.rs                           |  7 --
 .../feature-gate.stderr                       | 12 ----
 .../issue-87718.rs                            |  2 -
 .../not-enough-args.rs                        |  2 -
 .../not-enough-args.stderr                    |  4 +-
 .../issues/universal-issue-48703.rs           |  7 --
 .../issues/universal-issue-48703.stderr       | 12 ----
 ...iversal-turbofish-in-method-issue-50950.rs | 17 -----
 ...sal-turbofish-in-method-issue-50950.stderr | 14 ----
 src/test/ui/inference/issue-83606.rs          |  2 +-
 src/test/ui/inference/issue-83606.stderr      |  4 +-
 22 files changed, 32 insertions(+), 169 deletions(-)
 delete mode 100644 src/test/ui/const-generics/impl-trait-with-const-arguments.stderr
 rename src/test/ui/{const-generics/impl-trait-with-const-arguments.rs => impl-trait/explicit-generic-args-with-impl-trait/const-args.rs} (72%)
 delete mode 100644 src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs
 delete mode 100644 src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr
 delete mode 100644 src/test/ui/impl-trait/issues/universal-issue-48703.rs
 delete mode 100644 src/test/ui/impl-trait/issues/universal-issue-48703.stderr
 delete mode 100644 src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs
 delete mode 100644 src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr

diff --git a/compiler/rustc_error_codes/src/error_codes/E0632.md b/compiler/rustc_error_codes/src/error_codes/E0632.md
index 40840e894d623..7e0a5c71f5f6f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0632.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0632.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 An explicit generic argument was provided when calling a function that
 uses `impl Trait` in argument position.
 
 Erroneous code example:
 
-```compile_fail,E0632
+```ignore (no longer an error)
 fn foo<T: Copy>(a: T, b: impl Clone) {}
 
 foo::<i32>(0i32, "abc".to_string());
diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
index 95b348ec61353..c61735a57e163 100644
--- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
@@ -95,12 +95,6 @@ typeck-expected-return-type = expected `{$expected}` because of return type
 typeck-unconstrained-opaque-type = unconstrained opaque type
     .note = `{$name}` must be used in combination with a concrete type within the same module
 
-typeck-explicit-generic-args-with-impl-trait =
-    cannot provide explicit generic arguments when `impl Trait` is used in argument position
-    .label = explicit generic argument not allowed
-    .note = see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
-    .help = add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
-
 typeck-missing-type-params =
     the type {$parameterCount ->
         [one] parameter
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 048039343a7a2..6bff2a1365b6b 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -142,6 +142,8 @@ declare_features! (
     (accepted, dyn_trait, "1.27.0", Some(44662), None),
     /// Allows integer match exhaustiveness checking (RFC 2591).
     (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
+    /// Allows explicit generic arguments specification with `impl Trait` present.
+    (accepted, explicit_generic_args_with_impl_trait, "1.63.0", Some(83701), None),
     /// Allows arbitrary expressions in key-value attributes at parse time.
     (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None),
     /// Allows resolving absolute paths as paths from other crates.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 1466e8dfc92e4..ad15d4bb8421d 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -383,8 +383,6 @@ declare_features! (
     (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
     /// Allows exhaustive pattern matching on types that contain uninhabited types.
     (active, exhaustive_patterns, "1.13.0", Some(51085), None),
-    /// Allows explicit generic arguments specification with `impl Trait` present.
-    (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None),
     /// Allows defining `extern type`s.
     (active, extern_types, "1.23.0", Some(43467), None),
     /// Allows the use of `#[ffi_const]` on foreign functions.
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index dc4bc8fb55a17..3fe4b5b46e012 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -3,7 +3,7 @@ use crate::astconv::{
     AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
     GenericArgCountResult, GenericArgPosition,
 };
-use crate::errors::{AssocTypeBindingNotAllowed, ExplicitGenericArgsWithImplTrait};
+use crate::errors::AssocTypeBindingNotAllowed;
 use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
 use rustc_ast::ast::ParamKindOrd;
 use rustc_errors::{struct_span_err, Applicability, Diagnostic, MultiSpan};
@@ -397,8 +397,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         is_method_call: IsMethodCall,
     ) -> GenericArgCountResult {
         let empty_args = hir::GenericArgs::none();
-        let suppress_mismatch = Self::check_impl_trait(tcx, seg, generics);
-
         let gen_args = seg.args.unwrap_or(&empty_args);
         let gen_pos = if is_method_call == IsMethodCall::Yes {
             GenericArgPosition::MethodCall
@@ -406,10 +404,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             GenericArgPosition::Value
         };
         let has_self = generics.parent.is_none() && generics.has_self;
-        let infer_args = seg.infer_args || suppress_mismatch;
 
         Self::check_generic_arg_count(
-            tcx, span, def_id, seg, generics, gen_args, gen_pos, has_self, infer_args,
+            tcx,
+            span,
+            def_id,
+            seg,
+            generics,
+            gen_args,
+            gen_pos,
+            has_self,
+            seg.infer_args,
         )
     }
 
@@ -431,19 +436,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let param_counts = gen_params.own_counts();
 
         // Subtracting from param count to ensure type params synthesized from `impl Trait`
-        // cannot be explicitly specified even with `explicit_generic_args_with_impl_trait`
-        // feature enabled.
-        let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait {
-            gen_params
-                .params
-                .iter()
-                .filter(|param| {
-                    matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
-                })
-                .count()
-        } else {
-            0
-        };
+        // cannot be explicitly specified.
+        let synth_type_param_count = gen_params
+            .params
+            .iter()
+            .filter(|param| {
+                matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. })
+            })
+            .count();
         let named_type_param_count =
             param_counts.types - has_self as usize - synth_type_param_count;
         let infer_lifetimes =
@@ -611,40 +611,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         }
     }
 
-    /// Report error if there is an explicit type parameter when using `impl Trait`.
-    pub(crate) fn check_impl_trait(
-        tcx: TyCtxt<'_>,
-        seg: &hir::PathSegment<'_>,
-        generics: &ty::Generics,
-    ) -> bool {
-        if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait {
-            return false;
-        }
-
-        let impl_trait = generics.has_impl_trait();
-
-        if impl_trait {
-            let spans = seg
-                .args()
-                .args
-                .iter()
-                .filter_map(|arg| match arg {
-                    GenericArg::Infer(_) | GenericArg::Type(_) | GenericArg::Const(_) => {
-                        Some(arg.span())
-                    }
-                    _ => None,
-                })
-                .collect::<Vec<_>>();
-
-            tcx.sess.emit_err(ExplicitGenericArgsWithImplTrait {
-                spans,
-                is_nightly_build: tcx.sess.is_nightly_build().then_some(()),
-            });
-        }
-
-        impl_trait
-    }
-
     /// Emits an error regarding forbidden type binding associations
     pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) {
         tcx.sess.emit_err(AssocTypeBindingNotAllowed { span });
diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs
index a7f736fed14a3..67a3d4a4d020c 100644
--- a/compiler/rustc_typeck/src/errors.rs
+++ b/compiler/rustc_typeck/src/errors.rs
@@ -241,17 +241,6 @@ pub struct UnconstrainedOpaqueType {
     pub name: Symbol,
 }
 
-#[derive(SessionDiagnostic)]
-#[error(code = "E0632", slug = "typeck-explicit-generic-args-with-impl-trait")]
-#[note]
-pub struct ExplicitGenericArgsWithImplTrait {
-    #[primary_span]
-    #[label]
-    pub spans: Vec<Span>,
-    #[help]
-    pub is_nightly_build: Option<()>,
-}
-
 pub struct MissingTypeParams {
     pub span: Span,
     pub def_span: Span,
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.stderr b/src/test/ui/const-generics/impl-trait-with-const-arguments.stderr
deleted file mode 100644
index 87e4ad5004044..0000000000000
--- a/src/test/ui/const-generics/impl-trait-with-const-arguments.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
-  --> $DIR/impl-trait-with-const-arguments.rs:18:20
-   |
-LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
-   |                    ^^^^^^ explicit generic argument not allowed
-   |
-   = note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
-   = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/const-args.rs
similarity index 72%
rename from src/test/ui/const-generics/impl-trait-with-const-arguments.rs
rename to src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/const-args.rs
index 24ba393c17f2a..1aa23c6082348 100644
--- a/src/test/ui/const-generics/impl-trait-with-const-arguments.rs
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/const-args.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 trait Usizer {
     fn m(self) -> usize;
 }
@@ -16,5 +18,4 @@ impl Usizer for Usizable {
 
 fn main() {
     assert_eq!(f::<4usize>(Usizable), 20usize);
-//~^ ERROR cannot provide explicit generic arguments when `impl Trait` is used in argument position
 }
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs
index 832a3e3b7b10d..3b1024d612650 100644
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs
@@ -1,5 +1,3 @@
-#![feature(explicit_generic_args_with_impl_trait)]
-
 fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
 
 fn main() {
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
index 2ae7745c725c1..c8b82783ea841 100644
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
@@ -1,5 +1,5 @@
 error[E0107]: this function takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/explicit-generic-args-for-impl.rs:6:5
+  --> $DIR/explicit-generic-args-for-impl.rs:4:5
    |
 LL |     foo::<str, String>("".to_string());
    |     ^^^        ------ help: remove this generic argument
@@ -7,7 +7,7 @@ LL |     foo::<str, String>("".to_string());
    |     expected 1 generic argument
    |
 note: function defined here, with 1 generic parameter: `T`
-  --> $DIR/explicit-generic-args-for-impl.rs:3:4
+  --> $DIR/explicit-generic-args-for-impl.rs:1:4
    |
 LL | fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
    |    ^^^ -
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs
index a6585bcf84862..99e0931ab950d 100644
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs
@@ -1,7 +1,5 @@
 // check-pass
 
-#![feature(explicit_generic_args_with_impl_trait)]
-
 fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
 
 fn main() {
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs
deleted file mode 100644
index 0e4d6986d46ec..0000000000000
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-// gate-test-explicit_generic_args_with_impl_trait
-
-fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
-
-fn main() {
-    foo::<str>("".to_string()); //~ ERROR E0632
-}
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr
deleted file mode 100644
index a25c85faf4e35..0000000000000
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
-  --> $DIR/feature-gate.rs:6:11
-   |
-LL |     foo::<str>("".to_string());
-   |           ^^^ explicit generic argument not allowed
-   |
-   = note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
-   = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs
index e2ee63821ae74..987df4997342f 100644
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/issue-87718.rs
@@ -1,7 +1,5 @@
 // check-pass
 
-#![feature(explicit_generic_args_with_impl_trait)]
-
 fn f<T: ?Sized>(_: impl AsRef<T>, _: impl AsRef<T>) {}
 
 fn main() {
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs
index ffb0582fe8df4..7249a36f5fe7b 100644
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.rs
@@ -1,5 +1,3 @@
-#![feature(explicit_generic_args_with_impl_trait)]
-
 fn f<T: ?Sized, U: ?Sized>(_: impl AsRef<T>, _: impl AsRef<U>) {}
 
 fn main() {
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
index b6701b68fd6c1..9d6db88d36433 100644
--- a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr
@@ -1,5 +1,5 @@
 error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied
-  --> $DIR/not-enough-args.rs:6:5
+  --> $DIR/not-enough-args.rs:4:5
    |
 LL |     f::<[u8]>("a", b"a");
    |     ^   ---- supplied 1 generic argument
@@ -7,7 +7,7 @@ LL |     f::<[u8]>("a", b"a");
    |     expected 2 generic arguments
    |
 note: function defined here, with 2 generic parameters: `T`, `U`
-  --> $DIR/not-enough-args.rs:3:4
+  --> $DIR/not-enough-args.rs:1:4
    |
 LL | fn f<T: ?Sized, U: ?Sized>(_: impl AsRef<T>, _: impl AsRef<U>) {}
    |    ^ -          -
diff --git a/src/test/ui/impl-trait/issues/universal-issue-48703.rs b/src/test/ui/impl-trait/issues/universal-issue-48703.rs
deleted file mode 100644
index d1e5aa6c6b916..0000000000000
--- a/src/test/ui/impl-trait/issues/universal-issue-48703.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use std::fmt::Debug;
-
-fn foo<T>(x: impl Debug) { }
-
-fn main() {
-    foo::<String>('a'); //~ ERROR cannot provide explicit generic arguments
-}
diff --git a/src/test/ui/impl-trait/issues/universal-issue-48703.stderr b/src/test/ui/impl-trait/issues/universal-issue-48703.stderr
deleted file mode 100644
index 02c7fe8ff2c41..0000000000000
--- a/src/test/ui/impl-trait/issues/universal-issue-48703.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
-  --> $DIR/universal-issue-48703.rs:6:11
-   |
-LL |     foo::<String>('a');
-   |           ^^^^^^ explicit generic argument not allowed
-   |
-   = note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
-   = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs b/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs
deleted file mode 100644
index 4ac0a694cb148..0000000000000
--- a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-use std::any::Any;
-pub struct EventHandler {
-}
-
-impl EventHandler
-{
-    pub fn handle_event<T: Any>(&mut self, _efunc: impl FnMut(T)) {}
-}
-
-struct TestEvent(i32);
-
-fn main() {
-    let mut evt = EventHandler {};
-    evt.handle_event::<TestEvent, fn(TestEvent)>(|_evt| {
-        //~^ ERROR cannot provide explicit generic arguments
-    });
-}
diff --git a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr b/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr
deleted file mode 100644
index 84b98f71f4f0c..0000000000000
--- a/src/test/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
-  --> $DIR/universal-turbofish-in-method-issue-50950.rs:14:24
-   |
-LL |     evt.handle_event::<TestEvent, fn(TestEvent)>(|_evt| {
-   |                        ^^^^^^^^^  ^^^^^^^^^^^^^ explicit generic argument not allowed
-   |                        |
-   |                        explicit generic argument not allowed
-   |
-   = note: see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information
-   = help: add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/inference/issue-83606.rs b/src/test/ui/inference/issue-83606.rs
index be56a3020cc33..eaaef3463ddc9 100644
--- a/src/test/ui/inference/issue-83606.rs
+++ b/src/test/ui/inference/issue-83606.rs
@@ -5,6 +5,6 @@ fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] {
 }
 
 fn main() {
-    let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
+    let _ = foo("foo");
     //~^ ERROR: type annotations needed for `[usize; _]`
 }
diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr
index 4ffaf820b8267..f5c84f960641a 100644
--- a/src/test/ui/inference/issue-83606.stderr
+++ b/src/test/ui/inference/issue-83606.stderr
@@ -1,12 +1,12 @@
 error[E0282]: type annotations needed for `[usize; _]`
   --> $DIR/issue-83606.rs:8:9
    |
-LL |     let _ = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
+LL |     let _ = foo("foo");
    |         ^
    |
 help: consider giving this pattern a type, where the the value of const parameter `N` is specified
    |
-LL |     let _: [usize; _] = foo("foo"); //<- Do not suggest `foo::<N>("foo");`!
+LL |     let _: [usize; _] = foo("foo");
    |          ++++++++++++
 
 error: aborting due to previous error

From 9db03b9bc8bdbc9cb0df8f022e61b97c1a6fc2ec Mon Sep 17 00:00:00 2001
From: Takayuki Maeda <takoyaki0316@gmail.com>
Date: Tue, 7 Jun 2022 02:33:23 +0900
Subject: [PATCH 03/16] suggest swapping a struct and a trait

fmt
---
 compiler/rustc_resolve/src/late.rs            |  9 +++++-
 .../rustc_resolve/src/late/diagnostics.rs     | 21 ++++++++++++++
 compiler/rustc_span/src/lib.rs                |  2 +-
 ...swapping-self-ty-and-trait-edition-2021.rs | 11 +++++++
 ...ping-self-ty-and-trait-edition-2021.stderr | 27 +++++++++++++++++
 .../suggest-swapping-self-ty-and-trait.rs     | 10 +++++++
 .../suggest-swapping-self-ty-and-trait.stderr | 29 +++++++++++++++++++
 7 files changed, 107 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
 create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
 create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
 create mode 100644 src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr

diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 73d6566e3cd97..688ba89c689c8 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -496,6 +496,9 @@ struct DiagnosticMetadata<'ast> {
 
     /// The current impl items (used to suggest).
     current_impl_items: Option<&'ast [P<AssocItem>]>,
+
+    /// When processing impl trait
+    currently_processing_impl_trait: Option<(TraitRef, Ty)>,
 }
 
 struct LateResolutionVisitor<'a, 'b, 'ast> {
@@ -2066,18 +2069,22 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     fn with_optional_trait_ref<T>(
         &mut self,
         opt_trait_ref: Option<&TraitRef>,
+        self_type: &'ast Ty,
         f: impl FnOnce(&mut Self, Option<DefId>) -> T,
     ) -> T {
         let mut new_val = None;
         let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
             let path: Vec<_> = Segment::from_path(&trait_ref.path);
+            self.diagnostic_metadata.currently_processing_impl_trait =
+                Some((trait_ref.clone(), self_type.clone()));
             let res = self.smart_resolve_path_fragment(
                 None,
                 &path,
                 PathSource::Trait(AliasPossibility::No),
                 Finalize::new(trait_ref.ref_id, trait_ref.path.span),
             );
+            self.diagnostic_metadata.currently_processing_impl_trait = None;
             if let Some(def_id) = res.base_res().opt_def_id() {
                 new_id = Some(def_id);
                 new_val = Some((self.r.expect_module(def_id), trait_ref.clone()));
@@ -2118,7 +2125,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             this.with_self_rib(Res::SelfTy { trait_: None, alias_to: None }, |this| {
                 this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter(item_id), |this| {
                     // Resolve the trait reference, if necessary.
-                    this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
+                    this.with_optional_trait_ref(opt_trait_reference.as_ref(), self_type, |this, trait_id| {
                         let item_def_id = this.r.local_def_id(item_id);
 
                         // Register the trait definitions from here.
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index a6a04ac9ea6fc..2266b4a1ecbe5 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -145,6 +145,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         let is_expected = &|res| source.is_expected(res);
         let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _));
 
+        debug!(?res, ?source);
+
         // Make the base error.
         struct BaseError<'a> {
             msg: String,
@@ -248,6 +250,25 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         let code = source.error_code(res.is_some());
         let mut err =
             self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code);
+        if let Some((trait_ref, self_ty)) =
+            self.diagnostic_metadata.currently_processing_impl_trait.clone()
+            && let TyKind::Path(_, self_ty_path) = &self_ty.kind
+            && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None)
+            && let ModuleKind::Def(DefKind::Trait, ..) = module.kind
+            && trait_ref.path.span == span
+            && let PathSource::Trait(_) = source
+            && let Some(Res::Def(DefKind::Struct, _)) = res
+            && let Ok(self_ty_str) =
+                self.r.session.source_map().span_to_snippet(self_ty.span)
+            && let Ok(trait_ref_str) =
+                self.r.session.source_map().span_to_snippet(trait_ref.path.span)
+        {
+                err.multipart_suggestion(
+                    "consider swapping the struct and the trait",
+                    vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)],
+                    Applicability::MaybeIncorrect,
+                );
+        }
 
         if let Some(sugg) = base_error.suggestion {
             err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index adf5a74404808..456cf6dbe270d 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -338,7 +338,7 @@ impl<'a> FileNameDisplay<'a> {
     pub fn to_string_lossy(&self) -> Cow<'a, str> {
         match self.inner {
             FileName::Real(ref inner) => inner.to_string_lossy(self.display_pref),
-            _ => Cow::from(format!("{}", self)),
+            _ => Cow::from(self.to_string()),
         }
     }
 }
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
new file mode 100644
index 0000000000000..a32e943daf892
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
@@ -0,0 +1,11 @@
+// edition:2021
+
+pub trait Trait<'a, T> {}
+
+pub struct Struct<T> {}
+
+impl<'a, T> Struct<T> for Trait<'a, T> {}
+//~^ ERROR expected trait, found struct `Struct`
+//~| ERROR trait objects must include the `dyn` keyword
+
+fn main() {}
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
new file mode 100644
index 0000000000000..aa9d09a797b7e
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
@@ -0,0 +1,27 @@
+error[E0404]: expected trait, found struct `Struct`
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:13
+   |
+LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
+   |             ^^^^^^^^^ not a trait
+   |
+help: consider swapping the struct and the trait
+   |
+LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
+   |             ~~~~~~~~~~~~     ~~~~~~~~~
+
+error[E0782]: trait objects must include the `dyn` keyword
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:27
+   |
+LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
+   |                           ^^^^^^^^^^^^
+   |
+help: add `dyn` keyword before this trait
+   |
+LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
+LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
+   | 
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0404, E0782.
+For more information about an error, try `rustc --explain E0404`.
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
new file mode 100644
index 0000000000000..d74cc86f7eac0
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
@@ -0,0 +1,10 @@
+pub trait Trait<'a, T> {}
+
+pub struct Struct<T> {}
+
+impl<'a, T> Struct<T> for Trait<'a, T> {}
+//~^ ERROR expected trait, found struct `Struct`
+//~| WARNING trait objects without an explicit `dyn` are deprecated
+//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+
+fn main() {}
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
new file mode 100644
index 0000000000000..f5f22f03cd9ac
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -0,0 +1,29 @@
+error[E0404]: expected trait, found struct `Struct`
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:13
+   |
+LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
+   |             ^^^^^^^^^ not a trait
+   |
+help: consider swapping the struct and the trait
+   |
+LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
+   |             ~~~~~~~~~~~~     ~~~~~~~~~
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:27
+   |
+LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
+   |                           ^^^^^^^^^^^^
+   |
+   = note: `#[warn(bare_trait_objects)]` on by default
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: use `dyn`
+   |
+LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
+LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
+   | 
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0404`.

From 154eba64b9e845f58ab4214cfcb6f202dfa5c210 Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Fri, 3 Jun 2022 19:34:24 +0200
Subject: [PATCH 04/16] publicly export `ty::subst` in `ty`

it feels arbitrary to have `Ty` and `Const` directly
in that module and to not have `GenericArg` and
`GenericArgKind` there. Writing `ty::GenericArg`
can also feel clearer than importing it. Using
`ty::subst::GenericArg` however is ugly.
---
 compiler/rustc_middle/src/ty/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 48ac7ecdf050f..7f0f3755c4b33 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -22,7 +22,6 @@ use crate::mir::{Body, GeneratorLayout};
 use crate::traits::{self, Reveal};
 use crate::ty;
 use crate::ty::fast_reject::SimplifiedType;
-use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
 use crate::ty::util::Discr;
 pub use adt::*;
 pub use assoc::*;
@@ -44,6 +43,7 @@ use rustc_session::cstore::CrateStoreDyn;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use rustc_target::abi::Align;
+pub use subst::*;
 pub use vtable::*;
 
 use std::fmt::Debug;

From 2ea468e386230375229c68a09affcba23cd79487 Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Fri, 3 Jun 2022 20:00:39 +0200
Subject: [PATCH 05/16] dedup diagnostics default params handling

---
 .../src/infer/error_reporting/mod.rs          | 56 ++++---------------
 .../infer/error_reporting/need_type_info.rs   | 24 +-------
 compiler/rustc_middle/src/ty/generics.rs      | 37 +++++++++++-
 compiler/rustc_middle/src/ty/print/mod.rs     | 39 +------------
 compiler/rustc_middle/src/ty/print/pretty.rs  | 27 ++++-----
 .../defaults/rp_impl_trait_fail.rs            |  4 +-
 .../defaults/rp_impl_trait_fail.stderr        |  8 +--
 .../defaults/trait_objects_fail.rs            |  2 +-
 .../defaults/trait_objects_fail.stderr        |  6 +-
 9 files changed, 72 insertions(+), 131 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 18fc1158b042d..1181925dd9672 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -67,10 +67,8 @@ use rustc_hir::{Item, ItemKind, Node};
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
-    self,
-    error::TypeError,
-    subst::{GenericArgKind, Subst, SubstsRef},
-    Binder, EarlyBinder, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
+    self, error::TypeError, Binder, List, Region, Subst, Ty, TyCtxt, TypeFoldable,
+    TypeSuperFoldable,
 };
 use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span};
 use rustc_target::spec::abi;
@@ -926,10 +924,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         mut t1_out: &mut DiagnosticStyledString,
         mut t2_out: &mut DiagnosticStyledString,
         path: String,
-        sub: ty::subst::SubstsRef<'tcx>,
+        sub: &'tcx [ty::GenericArg<'tcx>],
         other_path: String,
         other_ty: Ty<'tcx>,
     ) -> Option<()> {
+        // FIXME/HACK: Go back to `SubstsRef` to use its inherent methods,
+        // ideally that shouldn't be necessary.
+        let sub = self.tcx.intern_substs(sub);
         for (i, ta) in sub.types().enumerate() {
             if ta == other_ty {
                 self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty);
@@ -960,45 +961,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
     }
 
-    /// For generic types with parameters with defaults, remove the parameters corresponding to
-    /// the defaults. This repeats a lot of the logic found in `ty::print::pretty`.
-    fn strip_generic_default_params(
-        &self,
-        def_id: DefId,
-        substs: ty::subst::SubstsRef<'tcx>,
-    ) -> SubstsRef<'tcx> {
-        let generics = self.tcx.generics_of(def_id);
-        let mut num_supplied_defaults = 0;
-
-        let default_params = generics.params.iter().rev().filter_map(|param| match param.kind {
-            ty::GenericParamDefKind::Type { has_default: true, .. } => Some(param.def_id),
-            ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id),
-            _ => None,
-        });
-        for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) {
-            match actual.unpack() {
-                GenericArgKind::Const(c) => {
-                    if EarlyBinder(self.tcx.const_param_default(def_id)).subst(self.tcx, substs)
-                        != c
-                    {
-                        break;
-                    }
-                }
-                GenericArgKind::Type(ty) => {
-                    if self.tcx.bound_type_of(def_id).subst(self.tcx, substs) != ty {
-                        break;
-                    }
-                }
-                _ => break,
-            }
-            num_supplied_defaults += 1;
-        }
-        let len = generics.params.len();
-        let mut generics = generics.clone();
-        generics.params.truncate(len - num_supplied_defaults);
-        substs.truncate_to(self.tcx, &generics)
-    }
-
     /// Given two `fn` signatures highlight only sub-parts that are different.
     fn cmp_fn_sig(
         &self,
@@ -1156,8 +1118,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
                 let did1 = def1.did();
                 let did2 = def2.did();
-                let sub_no_defaults_1 = self.strip_generic_default_params(did1, sub1);
-                let sub_no_defaults_2 = self.strip_generic_default_params(did2, sub2);
+                let sub_no_defaults_1 =
+                    self.tcx.generics_of(did1).own_substs_no_defaults(self.tcx, sub1);
+                let sub_no_defaults_2 =
+                    self.tcx.generics_of(did2).own_substs_no_defaults(self.tcx, sub2);
                 let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
                 let path1 = self.tcx.def_path_str(did1);
                 let path2 = self.tcx.def_path_str(did2);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 7b5c377f7b4ca..7c4477b617289 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -11,7 +11,7 @@ use rustc_middle::infer::unify_key::ConstVariableOriginKind;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef};
-use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, InferConst};
+use rustc_middle::ty::{self, DefIdTree, InferConst};
 use rustc_middle::ty::{Ty, TyCtxt, TypeckResults};
 use rustc_span::symbol::{kw, Ident};
 use rustc_span::{BytePos, Span};
@@ -958,26 +958,8 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
                 generics.own_substs(substs).iter().position(|&arg| self.generic_arg_is_target(arg))
             {
                 let substs = self.infcx.resolve_vars_if_possible(substs);
-                let num_args = generics
-                    .params
-                    .iter()
-                    .rev()
-                    .filter(|&p| !matches!(p.kind, GenericParamDefKind::Lifetime))
-                    .skip_while(|&param| {
-                        if let Some(default) = param.default_value(tcx) {
-                            // FIXME: Using structural comparisions has a bunch of false negatives.
-                            //
-                            // We should instead try to replace inference variables with placeholders and
-                            // then use `infcx.can_eq`. That probably should be a separate method
-                            // generally used during error reporting.
-                            default.subst(tcx, substs) == substs[param.index as usize]
-                        } else {
-                            false
-                        }
-                    })
-                    .count();
-                let generic_args =
-                    &generics.own_substs(substs)[generics.own_counts().lifetimes..][..num_args];
+                let generic_args = &generics.own_substs_no_defaults(tcx, substs)
+                    [generics.own_counts().lifetimes..];
                 let span = match expr.kind {
                     ExprKind::MethodCall(path, _, _) => path.ident.span,
                     _ => expr.span,
diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 1feabb2d6b122..5b0b56933ec03 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -228,8 +228,43 @@ impl<'tcx> Generics {
         })
     }
 
+    /// Returns the substs corresponding to the generic parameters
+    /// of this item, excluding `Self`.
+    pub fn own_substs_no_defaults(
+        &'tcx self,
+        tcx: TyCtxt<'tcx>,
+        substs: &'tcx [ty::GenericArg<'tcx>],
+    ) -> &'tcx [ty::GenericArg<'tcx>] {
+        let mut own_params = self.parent_count..self.count();
+        if self.has_self && self.parent.is_none() {
+            own_params.start = 1;
+        }
+
+        // Filter the default arguments.
+        //
+        // This currently uses structural equality instead
+        // of semantic equivalance. While not ideal, that's
+        // good enough for now as this should only be used
+        // for diagnostics anyways.
+        own_params.end -= self
+            .params
+            .iter()
+            .rev()
+            .take_while(|param| {
+                param.default_value(tcx).map_or(false, |default| {
+                    default.subst(tcx, substs) == substs[param.index as usize]
+                })
+            })
+            .count();
+
+        &substs[own_params]
+    }
+
     /// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
-    pub fn own_substs(&'tcx self, substs: SubstsRef<'tcx>) -> &'tcx [ty::GenericArg<'tcx>] {
+    pub fn own_substs(
+        &'tcx self,
+        substs: &'tcx [ty::GenericArg<'tcx>],
+    ) -> &'tcx [ty::GenericArg<'tcx>] {
         let own = &substs[self.parent_count..][..self.params.len()];
         if self.has_self && self.parent.is_none() { &own[1..] } else { &own }
     }
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 9d8124eb25db1..5ad93d778208d 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -149,7 +149,7 @@ pub trait Printer<'tcx>: Sized {
                         // on top of the same path, but without its own generics.
                         _ => {
                             if !generics.params.is_empty() && substs.len() >= generics.count() {
-                                let args = self.generic_args_to_print(generics, substs);
+                                let args = generics.own_substs_no_defaults(self.tcx(), substs);
                                 return self.path_generic_args(
                                     |cx| cx.print_def_path(def_id, parent_substs),
                                     args,
@@ -184,43 +184,6 @@ pub trait Printer<'tcx>: Sized {
         }
     }
 
-    fn generic_args_to_print(
-        &self,
-        generics: &'tcx ty::Generics,
-        substs: &'tcx [GenericArg<'tcx>],
-    ) -> &'tcx [GenericArg<'tcx>] {
-        let mut own_params = generics.parent_count..generics.count();
-
-        // Don't print args for `Self` parameters (of traits).
-        if generics.has_self && own_params.start == 0 {
-            own_params.start = 1;
-        }
-
-        // Don't print args that are the defaults of their respective parameters.
-        own_params.end -= generics
-            .params
-            .iter()
-            .rev()
-            .take_while(|param| match param.kind {
-                ty::GenericParamDefKind::Lifetime => false,
-                ty::GenericParamDefKind::Type { has_default, .. } => {
-                    has_default
-                        && substs[param.index as usize]
-                            == GenericArg::from(
-                                self.tcx().bound_type_of(param.def_id).subst(self.tcx(), substs),
-                            )
-                }
-                ty::GenericParamDefKind::Const { has_default } => {
-                    has_default
-                        && substs[param.index as usize]
-                            == GenericArg::from(self.tcx().const_param_default(param.def_id))
-                }
-            })
-            .count();
-
-        &substs[own_params]
-    }
-
     fn default_print_impl_path(
         self,
         impl_def_id: DefId,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 7328b18a3283a..53a97a46b2d26 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -825,12 +825,11 @@ pub trait PrettyPrinter<'tcx>:
 
         for (fn_once_trait_ref, entry) in fn_traits {
             // Get the (single) generic ty (the args) of this FnOnce trait ref.
-            let generics = self.generic_args_to_print(
-                self.tcx().generics_of(fn_once_trait_ref.def_id()),
-                fn_once_trait_ref.skip_binder().substs,
-            );
+            let generics = self.tcx().generics_of(fn_once_trait_ref.def_id());
+            let args =
+                generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs);
 
-            match (entry.return_ty, generics[0].expect_ty()) {
+            match (entry.return_ty, args[0].expect_ty()) {
                 // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
                 // a return type.
                 (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
@@ -892,15 +891,13 @@ pub trait PrettyPrinter<'tcx>:
                 print(trait_ref.skip_binder().print_only_trait_name())
             );
 
-            let generics = self.generic_args_to_print(
-                self.tcx().generics_of(trait_ref.def_id()),
-                trait_ref.skip_binder().substs,
-            );
+            let generics = self.tcx().generics_of(trait_ref.def_id());
+            let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs);
 
-            if !generics.is_empty() || !assoc_items.is_empty() {
+            if !args.is_empty() || !assoc_items.is_empty() {
                 let mut first = true;
 
-                for ty in generics {
+                for ty in args {
                     if first {
                         p!("<");
                         first = false;
@@ -1071,10 +1068,10 @@ pub trait PrettyPrinter<'tcx>:
                     let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0));
                     let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
 
-                    let args = cx.generic_args_to_print(
-                        cx.tcx().generics_of(principal.def_id),
-                        principal.substs,
-                    );
+                    let args = cx
+                        .tcx()
+                        .generics_of(principal.def_id)
+                        .own_substs_no_defaults(cx.tcx(), principal.substs);
 
                     // Don't print `'_` if there's no unerased regions.
                     let print_regions = args.iter().any(|arg| match arg.unpack() {
diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
index 308c121a94111..f633e56b0ec1d 100644
--- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
+++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs
@@ -15,12 +15,12 @@ impl Traitor<1, 2> for u64 {}
 
 
 fn uwu<const N: u8>() -> impl Traitor<N> {
-    //~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied
+    //~^ error: the trait bound `u32: Traitor<N>` is not satisfied
     1_u32
 }
 
 fn owo() -> impl Traitor {
-    //~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
+    //~^ error: the trait bound `u64: Traitor` is not satisfied
     1_u64
 }
 
diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
index 8031da28ca1ff..cbe4a4ac0d659 100644
--- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
+++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
@@ -6,21 +6,21 @@ LL | fn rawr() -> impl Trait {
    |
    = help: the trait `Trait` is implemented for `Uwu<N>`
 
-error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied
+error[E0277]: the trait bound `u32: Traitor<N>` is not satisfied
   --> $DIR/rp_impl_trait_fail.rs:17:26
    |
 LL | fn uwu<const N: u8>() -> impl Traitor<N> {
-   |                          ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32`
+   |                          ^^^^^^^^^^^^^^^ the trait `Traitor<N>` is not implemented for `u32`
    |
    = help: the following other types implement trait `Traitor<N, M>`:
              <u32 as Traitor<N, 2_u8>>
              <u64 as Traitor<1_u8, 2_u8>>
 
-error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied
+error[E0277]: the trait bound `u64: Traitor` is not satisfied
   --> $DIR/rp_impl_trait_fail.rs:22:13
    |
 LL | fn owo() -> impl Traitor {
-   |             ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64`
+   |             ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64`
    |
    = help: the following other types implement trait `Traitor<N, M>`:
              <u32 as Traitor<N, 2_u8>>
diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.rs b/src/test/ui/const-generics/defaults/trait_objects_fail.rs
index 7ba12d02b6e77..5e779d2e8de59 100644
--- a/src/test/ui/const-generics/defaults/trait_objects_fail.rs
+++ b/src/test/ui/const-generics/defaults/trait_objects_fail.rs
@@ -26,5 +26,5 @@ fn main() {
     foo(&10_u32);
     //~^ error: the trait bound `u32: Trait` is not satisfied
     bar(&true);
-    //~^ error: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
+    //~^ error: the trait bound `bool: Traitor<{_: u8}>` is not satisfied
 }
diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
index 7f8a1f742d840..60dc96f675a8b 100644
--- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
+++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr
@@ -9,16 +9,16 @@ LL |     foo(&10_u32);
    = help: the trait `Trait<2_u8>` is implemented for `u32`
    = note: required for the cast to the object type `dyn Trait`
 
-error[E0277]: the trait bound `bool: Traitor<{_: u8}, {_: u8}>` is not satisfied
+error[E0277]: the trait bound `bool: Traitor<{_: u8}>` is not satisfied
   --> $DIR/trait_objects_fail.rs:28:9
    |
 LL |     bar(&true);
-   |     --- ^^^^^ the trait `Traitor<{_: u8}, {_: u8}>` is not implemented for `bool`
+   |     --- ^^^^^ the trait `Traitor<{_: u8}>` is not implemented for `bool`
    |     |
    |     required by a bound introduced by this call
    |
    = help: the trait `Traitor<2_u8, 3_u8>` is implemented for `bool`
-   = note: required for the cast to the object type `dyn Traitor<{_: u8}, {_: u8}>`
+   = note: required for the cast to the object type `dyn Traitor<{_: u8}>`
 
 error: aborting due to 2 previous errors
 

From f8e73ede831727ed1808d245b381703c0142b9ba Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Fri, 3 Jun 2022 20:26:20 +0200
Subject: [PATCH 06/16] need_type_info: don't ICE when detected ty alias

fixes #97698
---
 .../infer/error_reporting/need_type_info.rs   | 21 +++++++----
 .../need_type_info/type-alias-indirect.rs     | 18 ++++++++++
 .../need_type_info/type-alias-indirect.stderr |  9 +++++
 .../ui/inference/need_type_info/type-alias.rs | 36 +++++++++++++++++++
 .../need_type_info/type-alias.stderr          | 15 ++++++++
 5 files changed, 93 insertions(+), 6 deletions(-)
 create mode 100644 src/test/ui/inference/need_type_info/type-alias-indirect.rs
 create mode 100644 src/test/ui/inference/need_type_info/type-alias-indirect.stderr
 create mode 100644 src/test/ui/inference/need_type_info/type-alias.rs
 create mode 100644 src/test/ui/inference/need_type_info/type-alias.stderr

diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 7c4477b617289..40b73eb670cf8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -2,6 +2,7 @@ use crate::infer::type_variable::TypeVariableOriginKind;
 use crate::infer::InferCtxt;
 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
+use rustc_hir::def::Res;
 use rustc_hir::def::{CtorOf, DefKind, Namespace};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
@@ -853,12 +854,20 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                             hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
                         ) => {
                             if tcx.res_generics_def_id(path.res) != Some(def.did()) {
-                                bug!(
-                                    "unexpected path: def={:?} substs={:?} path={:?}",
-                                    def,
-                                    substs,
-                                    path,
-                                );
+                                match path.res {
+                                    Res::Def(DefKind::TyAlias, _) => {
+                                        // FIXME: Ideally we should support this. For that
+                                        // we have to map back from the self type to the
+                                        // type alias though. That's difficult.
+                                        //
+                                        // See the `need_type_info/type-alias.rs` test for
+                                        // some examples.
+                                    }
+                                    _ => warn!(
+                                        "unexpected path: def={:?} substs={:?} path={:?}",
+                                        def, substs, path,
+                                    ),
+                                }
                             } else {
                                 return Box::new(
                                     self.resolved_path_inferred_subst_iter(path, substs)
diff --git a/src/test/ui/inference/need_type_info/type-alias-indirect.rs b/src/test/ui/inference/need_type_info/type-alias-indirect.rs
new file mode 100644
index 0000000000000..0ed02ddc5f390
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/type-alias-indirect.rs
@@ -0,0 +1,18 @@
+// An addition to the `type-alias.rs` test,
+// see the FIXME in that file for why this test
+// exists.
+//
+// If there is none, feel free to remove this test
+// again.
+struct Ty<T>(T);
+impl<T> Ty<T> {
+    fn new() {}
+}
+
+type IndirectAlias<T> = Ty<Box<T>>;
+fn indirect_alias() {
+    IndirectAlias::new();
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/type-alias-indirect.stderr b/src/test/ui/inference/need_type_info/type-alias-indirect.stderr
new file mode 100644
index 0000000000000..6161690df5050
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/type-alias-indirect.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/type-alias-indirect.rs:14:5
+   |
+LL |     IndirectAlias::new();
+   |     ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/need_type_info/type-alias.rs b/src/test/ui/inference/need_type_info/type-alias.rs
new file mode 100644
index 0000000000000..f921b046b6cac
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/type-alias.rs
@@ -0,0 +1,36 @@
+// Test the inference errors in case the relevant path
+// uses a type alias.
+//
+// Regression test for #97698.
+struct Ty<T>(T);
+impl<T> Ty<T> {
+    fn new() {}
+}
+
+type DirectAlias<T> = Ty<T>;
+fn direct_alias() {
+    DirectAlias::new()
+    //~^ ERROR type annotations needed
+}
+
+type IndirectAlias<T> = Ty<Box<T>>;
+fn indirect_alias() {
+    IndirectAlias::new();
+    // FIXME: This should also emit an error.
+    //
+    // Added it separately as `type-alias-indirect.rs`
+    // where it does error.
+}
+
+struct TyDefault<T, U = u32>(T, U);
+impl<T> TyDefault<T> {
+    fn new() {}
+}
+
+type DirectButWithDefaultAlias<T> = TyDefault<T>;
+fn direct_but_with_default_alias() {
+    DirectButWithDefaultAlias::new();
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/type-alias.stderr b/src/test/ui/inference/need_type_info/type-alias.stderr
new file mode 100644
index 0000000000000..a33f49baf549f
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/type-alias.stderr
@@ -0,0 +1,15 @@
+error[E0282]: type annotations needed
+  --> $DIR/type-alias.rs:12:5
+   |
+LL |     DirectAlias::new()
+   |     ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+  --> $DIR/type-alias.rs:32:5
+   |
+LL |     DirectButWithDefaultAlias::new();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0282`.

From b7ab4777b2b09d50fa1c1d9c735e2f31ec5f8960 Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Wed, 8 Jun 2022 10:01:35 +0200
Subject: [PATCH 07/16] note that methods should only be used for diags

---
 compiler/rustc_middle/src/ty/generics.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs
index 5b0b56933ec03..5fff840c39ec7 100644
--- a/compiler/rustc_middle/src/ty/generics.rs
+++ b/compiler/rustc_middle/src/ty/generics.rs
@@ -230,6 +230,8 @@ impl<'tcx> Generics {
 
     /// Returns the substs corresponding to the generic parameters
     /// of this item, excluding `Self`.
+    ///
+    /// **This should only be used for diagnostics purposes.**
     pub fn own_substs_no_defaults(
         &'tcx self,
         tcx: TyCtxt<'tcx>,
@@ -261,6 +263,8 @@ impl<'tcx> Generics {
     }
 
     /// Returns the substs corresponding to the generic parameters of this item, excluding `Self`.
+    ///
+    /// **This should only be used for diagnostics purposes.**
     pub fn own_substs(
         &'tcx self,
         substs: &'tcx [ty::GenericArg<'tcx>],

From d6b28f377cedada86c67cedc28fee4c925841a6d Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Wed, 8 Jun 2022 17:49:34 +0200
Subject: [PATCH 08/16] add test +  don't warn on `Res::SelfTy`

---
 .../infer/error_reporting/need_type_info.rs   |  3 ++
 .../inference/need_type_info/concrete-impl.rs | 16 +++++++++
 .../need_type_info/concrete-impl.stderr       | 33 +++++++++++++++++++
 .../need_type_info/self-ty-in-path.rs         | 13 ++++++++
 .../need_type_info/self-ty-in-path.stderr     | 14 ++++++++
 5 files changed, 79 insertions(+)
 create mode 100644 src/test/ui/inference/need_type_info/concrete-impl.rs
 create mode 100644 src/test/ui/inference/need_type_info/concrete-impl.stderr
 create mode 100644 src/test/ui/inference/need_type_info/self-ty-in-path.rs
 create mode 100644 src/test/ui/inference/need_type_info/self-ty-in-path.stderr

diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 40b73eb670cf8..207d2870c5c79 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -863,6 +863,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                                         // See the `need_type_info/type-alias.rs` test for
                                         // some examples.
                                     }
+                                    // There cannot be inference variables in the self type,
+                                    // so there's nothing for us to do here.
+                                    Res::SelfTy { .. } => {}
                                     _ => warn!(
                                         "unexpected path: def={:?} substs={:?} path={:?}",
                                         def, substs, path,
diff --git a/src/test/ui/inference/need_type_info/concrete-impl.rs b/src/test/ui/inference/need_type_info/concrete-impl.rs
new file mode 100644
index 0000000000000..72e0e74f32342
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/concrete-impl.rs
@@ -0,0 +1,16 @@
+trait Ambiguous<A> {
+    fn method() {}
+}
+
+struct One;
+struct Two;
+struct Struct;
+
+impl Ambiguous<One> for Struct {}
+impl Ambiguous<Two> for Struct {}
+
+fn main() {
+    <Struct as Ambiguous<_>>::method();
+    //~^ ERROR type annotations needed
+    //~| ERROR type annotations needed
+}
diff --git a/src/test/ui/inference/need_type_info/concrete-impl.stderr b/src/test/ui/inference/need_type_info/concrete-impl.stderr
new file mode 100644
index 0000000000000..b79d34affa249
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/concrete-impl.stderr
@@ -0,0 +1,33 @@
+error[E0282]: type annotations needed
+  --> $DIR/concrete-impl.rs:13:5
+   |
+LL |     <Struct as Ambiguous<_>>::method();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
+   |
+help: consider specifying the generic argument
+   |
+LL |     <Struct as Ambiguous::<_>>::method();
+   |                         ~~~~~
+
+error[E0283]: type annotations needed
+  --> $DIR/concrete-impl.rs:13:5
+   |
+LL |     <Struct as Ambiguous<_>>::method();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous`
+   |
+note: multiple `impl`s satisfying `Struct: Ambiguous<_>` found
+  --> $DIR/concrete-impl.rs:9:1
+   |
+LL | impl Ambiguous<One> for Struct {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl Ambiguous<Two> for Struct {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying the generic argument
+   |
+LL |     <Struct as Ambiguous::<_>>::method();
+   |                         ~~~~~
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0283.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/inference/need_type_info/self-ty-in-path.rs b/src/test/ui/inference/need_type_info/self-ty-in-path.rs
new file mode 100644
index 0000000000000..768a8cc377823
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/self-ty-in-path.rs
@@ -0,0 +1,13 @@
+// Test that we don't ICE when encountering a `Self` in a path.
+struct TestErr<T>(T);
+
+impl<T> TestErr<T> {
+    fn func_a<U>() {}
+
+    fn func_b() {
+        Self::func_a();
+        //~^ ERROR type annotations needed
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/need_type_info/self-ty-in-path.stderr b/src/test/ui/inference/need_type_info/self-ty-in-path.stderr
new file mode 100644
index 0000000000000..04b521dbdb360
--- /dev/null
+++ b/src/test/ui/inference/need_type_info/self-ty-in-path.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+  --> $DIR/self-ty-in-path.rs:8:9
+   |
+LL |         Self::func_a();
+   |         ^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the associated function `func_a`
+   |
+help: consider specifying the generic argument
+   |
+LL |         Self::func_a::<U>();
+   |                     +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.

From 5639e52ae1aa91a5d2fef12509410d2997886d49 Mon Sep 17 00:00:00 2001
From: Takayuki Maeda <takoyaki0316@gmail.com>
Date: Thu, 9 Jun 2022 17:52:10 +0900
Subject: [PATCH 09/16] move suggestions to its own method

---
 .../rustc_resolve/src/late/diagnostics.rs     | 50 ++++++++++++-------
 ...swapping-self-ty-and-trait-edition-2021.rs | 13 ++++-
 ...ping-self-ty-and-trait-edition-2021.stderr | 30 +++++++++--
 .../suggest-swapping-self-ty-and-trait.rs     | 13 ++++-
 .../suggest-swapping-self-ty-and-trait.stderr | 30 +++++++++--
 5 files changed, 107 insertions(+), 29 deletions(-)

diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 2266b4a1ecbe5..6f9c6592ad7cf 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -250,25 +250,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         let code = source.error_code(res.is_some());
         let mut err =
             self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code);
-        if let Some((trait_ref, self_ty)) =
-            self.diagnostic_metadata.currently_processing_impl_trait.clone()
-            && let TyKind::Path(_, self_ty_path) = &self_ty.kind
-            && let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None)
-            && let ModuleKind::Def(DefKind::Trait, ..) = module.kind
-            && trait_ref.path.span == span
-            && let PathSource::Trait(_) = source
-            && let Some(Res::Def(DefKind::Struct, _)) = res
-            && let Ok(self_ty_str) =
-                self.r.session.source_map().span_to_snippet(self_ty.span)
-            && let Ok(trait_ref_str) =
-                self.r.session.source_map().span_to_snippet(trait_ref.path.span)
-        {
-                err.multipart_suggestion(
-                    "consider swapping the struct and the trait",
-                    vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)],
-                    Applicability::MaybeIncorrect,
-                );
-        }
+
+        self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
 
         if let Some(sugg) = base_error.suggestion {
             err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect);
@@ -704,6 +687,35 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
         }
     }
 
+    fn suggest_swapping_misplaced_self_ty_and_trait(
+        &mut self,
+        err: &mut Diagnostic,
+        source: PathSource<'_>,
+        res: Option<Res>,
+        span: Span,
+    ) {
+        if let Some((trait_ref, self_ty)) =
+            self.diagnostic_metadata.currently_processing_impl_trait.clone()
+            && let TyKind::Path(_, self_ty_path) = &self_ty.kind
+            && let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
+                self.resolve_path(&Segment::from_path(self_ty_path), Some(TypeNS), None)
+            && let ModuleKind::Def(DefKind::Trait, ..) = module.kind
+            && trait_ref.path.span == span
+            && let PathSource::Trait(_) = source
+            && let Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) = res
+            && let Ok(self_ty_str) =
+                self.r.session.source_map().span_to_snippet(self_ty.span)
+            && let Ok(trait_ref_str) =
+                self.r.session.source_map().span_to_snippet(trait_ref.path.span)
+        {
+                err.multipart_suggestion(
+                    "`impl` items mention the trait being implemented first and the type it is being implemented for second",
+                    vec![(trait_ref.path.span, self_ty_str), (self_ty.span, trait_ref_str)],
+                    Applicability::MaybeIncorrect,
+                );
+        }
+    }
+
     fn get_single_associated_item(
         &mut self,
         path: &[Segment],
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
index a32e943daf892..03c7ed347bddf 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs
@@ -2,10 +2,21 @@
 
 pub trait Trait<'a, T> {}
 
-pub struct Struct<T> {}
+pub struct Struct<T>;
+pub enum Enum<T> {}
+
+pub union Union<T> {
+    f1: usize,
+}
 
 impl<'a, T> Struct<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found struct `Struct`
 //~| ERROR trait objects must include the `dyn` keyword
 
+impl<'a, T> Enum<T> for Trait<'a, T> {}
+//~^ ERROR expected trait, found enum `Enum`
+
+impl<'a, T> Union<T> for Trait<'a, T> {}
+//~^ ERROR expected trait, found union `Union`
+
 fn main() {}
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
index aa9d09a797b7e..dd6951e047410 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr
@@ -1,16 +1,38 @@
 error[E0404]: expected trait, found struct `Struct`
-  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:13
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:13
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |             ^^^^^^^^^ not a trait
    |
-help: consider swapping the struct and the trait
+help: `impl` items mention the trait being implemented first and the type it is being implemented for second
    |
 LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~~~
 
+error[E0404]: expected trait, found enum `Enum`
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:16:13
+   |
+LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
+   |             ^^^^^^^ not a trait
+   |
+help: `impl` items mention the trait being implemented first and the type it is being implemented for second
+   |
+LL | impl<'a, T> Trait<'a, T> for Enum<T> {}
+   |             ~~~~~~~~~~~~     ~~~~~~~
+
+error[E0404]: expected trait, found union `Union`
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13
+   |
+LL | impl<'a, T> Union<T> for Trait<'a, T> {}
+   |             ^^^^^^^^ not a trait
+   |
+help: `impl` items mention the trait being implemented first and the type it is being implemented for second
+   |
+LL | impl<'a, T> Trait<'a, T> for Union<T> {}
+   |             ~~~~~~~~~~~~     ~~~~~~~~
+
 error[E0782]: trait objects must include the `dyn` keyword
-  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:7:27
+  --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:12:27
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |                           ^^^^^^^^^^^^
@@ -21,7 +43,7 @@ LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
 LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    | 
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0404, E0782.
 For more information about an error, try `rustc --explain E0404`.
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
index d74cc86f7eac0..947bc2c79654b 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.rs
@@ -1,10 +1,21 @@
 pub trait Trait<'a, T> {}
 
-pub struct Struct<T> {}
+pub struct Struct<T>;
+pub enum Enum<T> {}
+
+pub union Union<T> {
+    f1: usize,
+}
 
 impl<'a, T> Struct<T> for Trait<'a, T> {}
 //~^ ERROR expected trait, found struct `Struct`
 //~| WARNING trait objects without an explicit `dyn` are deprecated
 //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
 
+impl<'a, T> Enum<T> for Trait<'a, T> {}
+//~^ ERROR expected trait, found enum `Enum`
+
+impl<'a, T> Union<T> for Trait<'a, T> {}
+//~^ ERROR expected trait, found union `Union`
+
 fn main() {}
diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index f5f22f03cd9ac..86ab8474c4299 100644
--- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -1,16 +1,38 @@
 error[E0404]: expected trait, found struct `Struct`
-  --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:13
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:13
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |             ^^^^^^^^^ not a trait
    |
-help: consider swapping the struct and the trait
+help: `impl` items mention the trait being implemented first and the type it is being implemented for second
    |
 LL | impl<'a, T> Trait<'a, T> for Struct<T> {}
    |             ~~~~~~~~~~~~     ~~~~~~~~~
 
+error[E0404]: expected trait, found enum `Enum`
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:15:13
+   |
+LL | impl<'a, T> Enum<T> for Trait<'a, T> {}
+   |             ^^^^^^^ not a trait
+   |
+help: `impl` items mention the trait being implemented first and the type it is being implemented for second
+   |
+LL | impl<'a, T> Trait<'a, T> for Enum<T> {}
+   |             ~~~~~~~~~~~~     ~~~~~~~
+
+error[E0404]: expected trait, found union `Union`
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13
+   |
+LL | impl<'a, T> Union<T> for Trait<'a, T> {}
+   |             ^^^^^^^^ not a trait
+   |
+help: `impl` items mention the trait being implemented first and the type it is being implemented for second
+   |
+LL | impl<'a, T> Trait<'a, T> for Union<T> {}
+   |             ~~~~~~~~~~~~     ~~~~~~~~
+
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/suggest-swapping-self-ty-and-trait.rs:5:27
+  --> $DIR/suggest-swapping-self-ty-and-trait.rs:10:27
    |
 LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    |                           ^^^^^^^^^^^^
@@ -24,6 +46,6 @@ LL - impl<'a, T> Struct<T> for Trait<'a, T> {}
 LL + impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    | 
 
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to 3 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0404`.

From 30c882521c235bbf5c278e884a83a996d5f20e47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= <mkroening@posteo.net>
Date: Fri, 10 Jun 2022 20:24:45 +0200
Subject: [PATCH 10/16] docs: Fix typo in ExitStatus

---
 library/std/src/process.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 1def9fe097202..873a87e4b2d76 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1417,7 +1417,7 @@ impl From<fs::File> for Stdio {
 /// For proper error reporting of failed processes, print the value of `ExitStatus` or
 /// `ExitStatusError` using their implementations of [`Display`](crate::fmt::Display).
 ///
-/// # Differences from `ExitStatus`
+/// # Differences from `ExitCode`
 ///
 /// `ExitCode` is intended for terminating the currently running process, via
 /// the `Termination` trait, in contrast to [`ExitStatus`], which represents the

From 3b45521acf2af899a94792aa1e888422c7447168 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= <mkroening@posteo.net>
Date: Fri, 10 Jun 2022 20:25:36 +0200
Subject: [PATCH 11/16] docs: Link to ExitCode instead of ExitStatus in
 ExitStatus

---
 library/std/src/process.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 873a87e4b2d76..e13520ed89e8c 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1419,8 +1419,8 @@ impl From<fs::File> for Stdio {
 ///
 /// # Differences from `ExitCode`
 ///
-/// `ExitCode` is intended for terminating the currently running process, via
-/// the `Termination` trait, in contrast to [`ExitStatus`], which represents the
+/// [`ExitCode`] is intended for terminating the currently running process, via
+/// the `Termination` trait, in contrast to `ExitStatus`, which represents the
 /// termination of a child process. These APIs are separate due to platform
 /// compatibility differences and their expected usage; it is not generally
 /// possible to exactly reproduce an ExitStatus from a child for the current

From 8537a1fd501abd9d03668eb41267ac0575b84f3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= <mkroening@posteo.net>
Date: Fri, 10 Jun 2022 20:26:41 +0200
Subject: [PATCH 12/16] docs: Consistently mark ExitStatus as code

---
 library/std/src/process.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index e13520ed89e8c..82cd3647040a2 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1423,7 +1423,7 @@ impl From<fs::File> for Stdio {
 /// the `Termination` trait, in contrast to `ExitStatus`, which represents the
 /// termination of a child process. These APIs are separate due to platform
 /// compatibility differences and their expected usage; it is not generally
-/// possible to exactly reproduce an ExitStatus from a child for the current
+/// possible to exactly reproduce an `ExitStatus` from a child for the current
 /// process after the fact.
 ///
 /// [`status`]: Command::status
@@ -1684,7 +1684,7 @@ impl crate::error::Error for ExitStatusError {}
 /// the `Termination` trait, in contrast to [`ExitStatus`], which represents the
 /// termination of a child process. These APIs are separate due to platform
 /// compatibility differences and their expected usage; it is not generally
-/// possible to exactly reproduce an ExitStatus from a child for the current
+/// possible to exactly reproduce an `ExitStatus` from a child for the current
 /// process after the fact.
 ///
 /// # Examples

From 5d91e9e941a069cc715d630b9b9826de6275f0a9 Mon Sep 17 00:00:00 2001
From: Ellen <supbscripter@gmail.com>
Date: Fri, 10 Jun 2022 21:26:53 +0100
Subject: [PATCH 13/16] a

---
 compiler/rustc_infer/src/infer/at.rs | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 39f7d30e81aca..b901cc443a0d8 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -111,6 +111,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `a <: b`, where `a` may or may not be expected.
+    /// 
+    /// See [`At::trace_exp`] and [`Trace::sub`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn sub_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()>
     where
         T: ToTrace<'tcx>,
@@ -122,6 +125,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     /// call like `foo(x)`, where `foo: fn(i32)`, you might have
     /// `sup(i32, x)`, since the "expected" type is the type that
     /// appears in the signature.
+    /// 
+    /// See [`At::trace`] and [`Trace::sub`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn sup<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
     where
         T: ToTrace<'tcx>,
@@ -130,6 +136,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `expected <: actual`.
+    /// 
+    /// See [`At::trace`] and [`Trace::sub`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn sub<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
     where
         T: ToTrace<'tcx>,
@@ -138,6 +147,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `expected <: actual`.
+    /// 
+    /// See [`At::trace_exp`] and [`Trace::eq`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn eq_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()>
     where
         T: ToTrace<'tcx>,
@@ -146,6 +158,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `expected <: actual`.
+    /// 
+    /// See [`At::trace`] and [`Trace::eq`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn eq<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
     where
         T: ToTrace<'tcx>,
@@ -176,6 +191,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     /// this can result in an error (e.g., if asked to compute LUB of
     /// u32 and i32), it is meaningful to call one of them the
     /// "expected type".
+    /// 
+    /// See [`At::trace`] and [`Trace::lub`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
     where
         T: ToTrace<'tcx>,
@@ -186,6 +204,9 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     /// Computes the greatest-lower-bound, or mutual subtype, of two
     /// values. As with `lub` order doesn't matter, except for error
     /// cases.
+    /// 
+    /// See [`At::trace`] and [`Trace::glb`] for a version of
+    /// this method that only requires `T: Relate<'tcx>`
     pub fn glb<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
     where
         T: ToTrace<'tcx>,

From 9f1d3702a4b994100f6aa01178bfb0530d31cb26 Mon Sep 17 00:00:00 2001
From: Ellen <supbscripter@gmail.com>
Date: Fri, 10 Jun 2022 21:47:00 +0100
Subject: [PATCH 14/16] the day that i make a PR without a tidy error..

---
 compiler/rustc_infer/src/infer/at.rs | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index b901cc443a0d8..ce2698ef44cd4 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -111,7 +111,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `a <: b`, where `a` may or may not be expected.
-    /// 
+    ///
     /// See [`At::trace_exp`] and [`Trace::sub`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn sub_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()>
@@ -125,7 +125,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     /// call like `foo(x)`, where `foo: fn(i32)`, you might have
     /// `sup(i32, x)`, since the "expected" type is the type that
     /// appears in the signature.
-    /// 
+    ///
     /// See [`At::trace`] and [`Trace::sub`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn sup<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
@@ -136,7 +136,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `expected <: actual`.
-    /// 
+    ///
     /// See [`At::trace`] and [`Trace::sub`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn sub<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
@@ -147,7 +147,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `expected <: actual`.
-    /// 
+    ///
     /// See [`At::trace_exp`] and [`Trace::eq`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn eq_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()>
@@ -158,7 +158,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     }
 
     /// Makes `expected <: actual`.
-    /// 
+    ///
     /// See [`At::trace`] and [`Trace::eq`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn eq<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
@@ -191,7 +191,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     /// this can result in an error (e.g., if asked to compute LUB of
     /// u32 and i32), it is meaningful to call one of them the
     /// "expected type".
-    /// 
+    ///
     /// See [`At::trace`] and [`Trace::lub`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
@@ -204,7 +204,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
     /// Computes the greatest-lower-bound, or mutual subtype, of two
     /// values. As with `lub` order doesn't matter, except for error
     /// cases.
-    /// 
+    ///
     /// See [`At::trace`] and [`Trace::glb`] for a version of
     /// this method that only requires `T: Relate<'tcx>`
     pub fn glb<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>

From 2147a069fffa320c0148c7671044ebd6f7af9528 Mon Sep 17 00:00:00 2001
From: Muhammad Hamza <muhammadhamza1311@gmail.com>
Date: Sat, 11 Jun 2022 02:03:33 +0500
Subject: [PATCH 15/16] Update the-doc-attribute.md

---
 src/doc/rustdoc/src/write-documentation/the-doc-attribute.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
index 25ef8b5bb9141..de604ff0fde73 100644
--- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
+++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
@@ -87,7 +87,9 @@ on your documentation examples make requests to.
 #![doc(html_playground_url = "https://playground.example.com/")]
 ```
 
-Now, when you press "run", the button will make a request to this domain.
+Now, when you press "run", the button will make a request to this domain. The request 
+URL will contain 2 query parameters: `code` and `edition` for the code in the documentation
+and the Rust edition respectively. 
 
 If you don't use this attribute, there will be no run buttons.
 

From 74d210e32c1cd7074656e3c0214feb5f6bc6f1d3 Mon Sep 17 00:00:00 2001
From: Muhammad Hamza <muhammadhamza1311@gmail.com>
Date: Sat, 11 Jun 2022 03:10:29 +0500
Subject: [PATCH 16/16] Update the-doc-attribute.md

---
 src/doc/rustdoc/src/write-documentation/the-doc-attribute.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
index de604ff0fde73..e3b0864899980 100644
--- a/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
+++ b/src/doc/rustdoc/src/write-documentation/the-doc-attribute.md
@@ -87,9 +87,9 @@ on your documentation examples make requests to.
 #![doc(html_playground_url = "https://playground.example.com/")]
 ```
 
-Now, when you press "run", the button will make a request to this domain. The request 
+Now, when you press "run", the button will make a request to this domain. The request
 URL will contain 2 query parameters: `code` and `edition` for the code in the documentation
-and the Rust edition respectively. 
+and the Rust edition respectively.
 
 If you don't use this attribute, there will be no run buttons.