about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_passes/src/dead.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs18
-rw-r--r--compiler/rustc_typeck/src/coherence/mod.rs6
-rw-r--r--library/alloc/src/boxed.rs32
-rw-r--r--src/test/rustdoc/nested-modules.rs42
-rw-r--r--src/test/ui/coherence/coherence-impls-sized.stderr12
-rw-r--r--src/test/ui/derive-uninhabited-enum-38885.stderr7
-rw-r--r--src/test/ui/derives/clone-debug-dead-code.stderr21
-rw-r--r--src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr2
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.stderr7
-rw-r--r--src/test/ui/traits/issue-97576.rs13
-rw-r--r--src/test/ui/traits/issue-97576.stderr11
12 files changed, 126 insertions, 51 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index e78d9a59982..519fb7ea264 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -722,11 +722,7 @@ impl<'tcx> DeadVisitor<'tcx> {
                         traits_str,
                         is_are
                     );
-                    let multispan = ign_traits
-                        .iter()
-                        .map(|(_, impl_id)| self.tcx.def_span(*impl_id))
-                        .collect::<Vec<_>>();
-                    err.span_note(multispan, &msg);
+                    err.note(&msg);
                 }
                 err.emit();
             });
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index a51e6e58f67..d0f20022bfb 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -21,7 +21,9 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
 use rustc_middle::hir::map;
 use rustc_middle::ty::{
-    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
+    self,
+    subst::{GenericArgKind, SubstsRef},
+    suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
     GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, ToPredicate, Ty, TyCtxt,
     TypeFoldable,
 };
@@ -458,6 +460,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             _ => (false, None),
         };
 
+        let generic_args_have_impl_trait = |args: SubstsRef<'tcx>| -> bool {
+            args.iter().any(|arg| match arg.unpack() {
+                GenericArgKind::Type(ty) => match ty.kind() {
+                    ty::Param(param) => param.name.as_str().starts_with("impl"),
+                    _ => false,
+                },
+                _ => false,
+            })
+        };
+
         // FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
         //        don't suggest `T: Sized + ?Sized`.
         let mut hir_id = body_id;
@@ -588,7 +600,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         | hir::ItemKind::TraitAlias(generics, _)
                         | hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }),
                     ..
-                }) if !param_ty => {
+                }) if !param_ty
+                    && !generic_args_have_impl_trait(trait_pred.skip_binder().trait_ref.substs) =>
+                {
                     // Missing generic type parameter bound.
                     let param_name = self_ty.to_string();
                     let constraint = trait_pred.print_modifiers_and_trait_path().to_string();
diff --git a/compiler/rustc_typeck/src/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs
index 3f1b4828d1a..3903448a007 100644
--- a/compiler/rustc_typeck/src/coherence/mod.rs
+++ b/compiler/rustc_typeck/src/coherence/mod.rs
@@ -57,7 +57,7 @@ fn enforce_trait_manually_implementable(
             E0322,
             "explicit impls for the `Pointee` trait are not permitted"
         )
-        .span_label(span, "impl of 'Pointee' not allowed")
+        .span_label(span, "impl of `Pointee` not allowed")
         .emit();
         return;
     }
@@ -70,7 +70,7 @@ fn enforce_trait_manually_implementable(
             E0322,
             "explicit impls for the `DiscriminantKind` trait are not permitted"
         )
-        .span_label(span, "impl of 'DiscriminantKind' not allowed")
+        .span_label(span, "impl of `DiscriminantKind` not allowed")
         .emit();
         return;
     }
@@ -83,7 +83,7 @@ fn enforce_trait_manually_implementable(
             E0322,
             "explicit impls for the `Sized` trait are not permitted"
         )
-        .span_label(span, "impl of 'Sized' not allowed")
+        .span_label(span, "impl of `Sized` not allowed")
         .emit();
         return;
     }
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 35ac5c8ebf6..cc395759b20 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -284,8 +284,13 @@ impl<T> Box<T> {
         Self::new_zeroed_in(Global)
     }
 
-    /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
+    /// Constructs a new `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
     /// `x` will be pinned in memory and unable to be moved.
+    ///
+    /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin(x)`
+    /// does the same as <code>[Box::into_pin]\([Box::new]\(x))</code>. Consider using
+    /// [`into_pin`](Box::into_pin) if you already have a `Box<T>`, or if you want to
+    /// construct a (pinned) `Box` in a different way than with [`Box::new`].
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "pin", since = "1.33.0")]
     #[must_use]
@@ -573,8 +578,13 @@ impl<T, A: Allocator> Box<T, A> {
         unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) }
     }
 
-    /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
+    /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement [`Unpin`], then
     /// `x` will be pinned in memory and unable to be moved.
+    ///
+    /// Constructing and pinning of the `Box` can also be done in two steps: `Box::pin_in(x, alloc)`
+    /// does the same as <code>[Box::into_pin]\([Box::new_in]\(x, alloc))</code>. Consider using
+    /// [`into_pin`](Box::into_pin) if you already have a `Box<T, A>`, or if you want to
+    /// construct a (pinned) `Box` in a different way than with [`Box::new_in`].
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
@@ -1190,12 +1200,18 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
         unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
     }
 
-    /// Converts a `Box<T>` into a `Pin<Box<T>>`
+    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
+    /// `*boxed` will be pinned in memory and unable to be moved.
     ///
     /// This conversion does not allocate on the heap and happens in place.
     ///
     /// This is also available via [`From`].
     ///
+    /// Constructing and pinning a `Box` with <code>Box::into_pin([Box::new]\(x))</code>
+    /// can also be written more concisely using <code>[Box::pin]\(x)</code>.
+    /// This `into_pin` method is useful if you already have a `Box<T>`, or you are
+    /// constructing a (pinned) `Box` in a different way than with [`Box::new`].
+    ///
     /// # Notes
     ///
     /// It's not recommended that crates add an impl like `From<Box<T>> for Pin<T>`,
@@ -1458,9 +1474,17 @@ impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
 where
     A: 'static,
 {
-    /// Converts a `Box<T>` into a `Pin<Box<T>>`
+    /// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
+    /// `*boxed` will be pinned in memory and unable to be moved.
     ///
     /// This conversion does not allocate on the heap and happens in place.
+    ///
+    /// This is also available via [`Box::into_pin`].
+    ///
+    /// Constructing and pinning a `Box` with <code><Pin<Box\<T>>>::from([Box::new]\(x))</code>
+    /// can also be written more concisely using <code>[Box::pin]\(x)</code>.
+    /// This `From` implementation is useful if you already have a `Box<T>`, or you are
+    /// constructing a (pinned) `Box` in a different way than with [`Box::new`].
     fn from(boxed: Box<T, A>) -> Self {
         Box::into_pin(boxed)
     }
diff --git a/src/test/rustdoc/nested-modules.rs b/src/test/rustdoc/nested-modules.rs
new file mode 100644
index 00000000000..1596f46740e
--- /dev/null
+++ b/src/test/rustdoc/nested-modules.rs
@@ -0,0 +1,42 @@
+#![crate_name = "aCrate"]
+
+mod a_module {
+    pub fn private_function() {}
+
+    pub use a_module::private_function as other_private_function;
+
+    pub mod a_nested_module {
+        // @has aCrate/a_nested_module/index.html '//a[@href="fn.a_nested_public_function.html"]' 'a_nested_public_function'
+        // @has aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()'
+        pub fn a_nested_public_function() {}
+
+        // @has aCrate/a_nested_module/index.html '//a[@href="fn.another_nested_public_function.html"]' 'another_nested_public_function'
+        // @has aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()'
+        pub use a_nested_module::a_nested_public_function as another_nested_public_function;
+    }
+
+    // @!has aCrate/a_nested_module/index.html 'yet_another_nested_public_function'
+    pub use a_nested_module::a_nested_public_function as yet_another_nested_public_function;
+
+    // @!has aCrate/a_nested_module/index.html 'one_last_nested_public_function'
+    pub use a_nested_module::another_nested_public_function as one_last_nested_public_function;
+}
+
+// @!has aCrate/index.html 'a_module'
+// @has aCrate/index.html '//a[@href="a_nested_module/index.html"]' 'a_nested_module'
+pub use a_module::a_nested_module;
+
+// @has aCrate/index.html '//a[@href="fn.a_nested_public_function.html"]' 'a_nested_public_function'
+// @has aCrate/index.html '//a[@href="fn.another_nested_public_function.html"]' 'another_nested_public_function'
+// @has aCrate/index.html '//a[@href="fn.yet_another_nested_public_function.html"]' 'yet_another_nested_public_function'
+// @has aCrate/index.html '//a[@href="fn.one_last_nested_public_function.html"]' 'one_last_nested_public_function'
+pub use a_module::{
+    a_nested_module::{a_nested_public_function, another_nested_public_function},
+    one_last_nested_public_function, yet_another_nested_public_function,
+};
+
+// @has aCrate/index.html '//a[@href="fn.private_function.html"]' 'private_function'
+// @!has aCrate/fn.private_function.html 'a_module'
+// @has aCrate/index.html '//a[@href="fn.other_private_function.html"]' 'other_private_function'
+// @!has aCrate/fn.other_private_function.html 'a_module'
+pub use a_module::{other_private_function, private_function};
diff --git a/src/test/ui/coherence/coherence-impls-sized.stderr b/src/test/ui/coherence/coherence-impls-sized.stderr
index 9cf5ed38c9c..e1e4acd4cd8 100644
--- a/src/test/ui/coherence/coherence-impls-sized.stderr
+++ b/src/test/ui/coherence/coherence-impls-sized.stderr
@@ -35,37 +35,37 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:14:1
    |
 LL | impl Sized for TestE {}
-   | ^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:17:1
    |
 LL | impl Sized for MyType {}
-   | ^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:20:1
    |
 LL | impl Sized for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:24:1
    |
 LL | impl Sized for &'static NotSync {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:27:1
    |
 LL | impl Sized for [MyType] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
   --> $DIR/coherence-impls-sized.rs:31:1
    |
 LL | impl Sized for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr
index 2a44e56a330..58aaf978dc7 100644
--- a/src/test/ui/derive-uninhabited-enum-38885.stderr
+++ b/src/test/ui/derive-uninhabited-enum-38885.stderr
@@ -5,12 +5,7 @@ LL |     Void(Void),
    |     ^^^^^^^^^^
    |
    = note: `-W dead-code` implied by `-W unused`
-note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
-  --> $DIR/derive-uninhabited-enum-38885.rs:10:10
-   |
-LL | #[derive(Debug)]
-   |          ^^^^^
-   = note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/derives/clone-debug-dead-code.stderr b/src/test/ui/derives/clone-debug-dead-code.stderr
index 67bb574315a..031b8ce713e 100644
--- a/src/test/ui/derives/clone-debug-dead-code.stderr
+++ b/src/test/ui/derives/clone-debug-dead-code.stderr
@@ -16,12 +16,7 @@ error: field is never read: `f`
 LL | struct B { f: () }
    |            ^^^^^
    |
-note: `B` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
-  --> $DIR/clone-debug-dead-code.rs:9:10
-   |
-LL | #[derive(Clone)]
-   |          ^^^^^
-   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: `B` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
 
 error: field is never read: `f`
   --> $DIR/clone-debug-dead-code.rs:14:12
@@ -29,12 +24,7 @@ error: field is never read: `f`
 LL | struct C { f: () }
    |            ^^^^^
    |
-note: `C` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
-  --> $DIR/clone-debug-dead-code.rs:13:10
-   |
-LL | #[derive(Debug)]
-   |          ^^^^^
-   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: `C` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
 
 error: field is never read: `f`
   --> $DIR/clone-debug-dead-code.rs:18:12
@@ -42,12 +32,7 @@ error: field is never read: `f`
 LL | struct D { f: () }
    |            ^^^^^
    |
-note: `D` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
-  --> $DIR/clone-debug-dead-code.rs:17:10
-   |
-LL | #[derive(Debug,Clone)]
-   |          ^^^^^ ^^^^^
-   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: `D` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
 
 error: field is never read: `f`
   --> $DIR/clone-debug-dead-code.rs:21:12
diff --git a/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr
index 54360c4f47b..38cfd13b9b8 100644
--- a/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr
+++ b/src/test/ui/enum-discriminant/forbidden-discriminant-kind-impl.stderr
@@ -2,7 +2,7 @@ error[E0322]: explicit impls for the `DiscriminantKind` trait are not permitted
   --> $DIR/forbidden-discriminant-kind-impl.rs:9:1
    |
 LL | impl DiscriminantKind for NewType {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'DiscriminantKind' not allowed
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `DiscriminantKind` not allowed
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr
index 3b5683a7748..57f8ca74f83 100644
--- a/src/test/ui/lint/dead-code/unused-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-variant.stderr
@@ -9,12 +9,7 @@ note: the lint level is defined here
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
-note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
-  --> $DIR/unused-variant.rs:3:10
-   |
-LL | #[derive(Clone)]
-   |          ^^^^^
-   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/issue-97576.rs b/src/test/ui/traits/issue-97576.rs
new file mode 100644
index 00000000000..fdc85e9fa89
--- /dev/null
+++ b/src/test/ui/traits/issue-97576.rs
@@ -0,0 +1,13 @@
+struct Foo {
+    bar: String,
+}
+
+impl Foo {
+    pub fn new(bar: impl ToString) -> Self {
+        Self {
+            bar: bar.into(), //~ ERROR the trait bound `String: From<impl ToString>` is not satisfied
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-97576.stderr b/src/test/ui/traits/issue-97576.stderr
new file mode 100644
index 00000000000..bdee073d6e3
--- /dev/null
+++ b/src/test/ui/traits/issue-97576.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `String: From<impl ToString>` is not satisfied
+  --> $DIR/issue-97576.rs:8:22
+   |
+LL |             bar: bar.into(),
+   |                      ^^^^ the trait `From<impl ToString>` is not implemented for `String`
+   |
+   = note: required because of the requirements on the impl of `Into<String>` for `impl ToString`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.