diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index e78d9a5998284..519fb7ea2640a 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::>(); - 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 a51e6e58f67a9..d0f20022bfbad 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 3f1b4828d1af3..3903448a00731 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 35ac5c8ebf698..cc395759b2078 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -284,8 +284,13 @@ impl Box { Self::new_zeroed_in(Global) } - /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then + /// Constructs a new `Pin>`. 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 [Box::into_pin]\([Box::new]\(x)). Consider using + /// [`into_pin`](Box::into_pin) if you already have a `Box`, 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 Box { unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } - /// Constructs a new `Pin>`. If `T` does not implement `Unpin`, then + /// Constructs a new `Pin>`. 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 [Box::into_pin]\([Box::new_in]\(x, alloc)). Consider using + /// [`into_pin`](Box::into_pin) if you already have a `Box`, 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 Box { unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() } } - /// Converts a `Box` into a `Pin>` + /// Converts a `Box` into a `Pin>`. 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 Box::into_pin([Box::new]\(x)) + /// can also be written more concisely using [Box::pin]\(x). + /// This `into_pin` method is useful if you already have a `Box`, 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> for Pin`, @@ -1458,9 +1474,17 @@ impl const From> for Pin> where A: 'static, { - /// Converts a `Box` into a `Pin>` + /// Converts a `Box` into a `Pin>`. 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 >>::from([Box::new]\(x)) + /// can also be written more concisely using [Box::pin]\(x). + /// This `From` implementation is useful if you already have a `Box`, or you are + /// constructing a (pinned) `Box` in a different way than with [`Box::new`]. fn from(boxed: Box) -> 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 0000000000000..1596f46740e8f --- /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 9cf5ed38c9c6b..e1e4acd4cd82d 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 2a44e56a3302c..58aaf978dc7d6 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 67bb574315a72..031b8ce713eb4 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 54360c4f47b3e..38cfd13b9b88e 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 3b5683a7748fa..57f8ca74f83dd 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 0000000000000..fdc85e9fa8956 --- /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` 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 0000000000000..bdee073d6e39a --- /dev/null +++ b/src/test/ui/traits/issue-97576.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `String: From` is not satisfied + --> $DIR/issue-97576.rs:8:22 + | +LL | bar: bar.into(), + | ^^^^ the trait `From` is not implemented for `String` + | + = note: required because of the requirements on the impl of `Into` for `impl ToString` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.