{}
diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs
index 11b9da3032ae7..9f671b739cb14 100644
--- a/library/core/src/alloc/mod.rs
+++ b/library/core/src/alloc/mod.rs
@@ -743,6 +743,13 @@ where
}
}
+#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
+#[unstable_feature_bound(allocator_ext)]
+impl AllocatorNightly for core::pin::Pin
where
+ P: core::ops::Deref + core::pin::PinSafePointer
+{
+}
+
#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
unsafe impl AllocatorClone for &A {}
@@ -753,3 +760,22 @@ unsafe impl StaticAllocator for &A {}
#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
unsafe impl StaticAllocator for &mut A {}
+
+/// Allocator marker trait that is only implemented stably for `Global`.
+///
+/// This trait is used as a bound whenever a function constructing
+/// a type with an `#[unstable] A: Allocator = Global` parameter
+/// may be callable for `A != Global`.
+///
+/// This is to prevent stable code from e.g. constructing `Arc`
+/// using the `From> for Arc` impl.
+#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
+pub trait AllocatorNightly: Allocator {}
+
+#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
+#[unstable_feature_bound(allocator_ext)]
+impl AllocatorNightly for &A {}
+
+#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
+#[unstable_feature_bound(allocator_ext)]
+impl AllocatorNightly for &mut A {}
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index c6f94944006c9..fdca3d12ba3d4 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -504,3 +504,7 @@ pub mod __default_lib_allocator {
}
}
}
+
+#[unstable(feature = "allocator_ext", issue = "163177", implied_by = "allocator_api")]
+#[unstable_feature_bound(allocator_ext)]
+impl AllocatorNightly for System {}
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index f779fce47cd2f..b97bd93181f7a 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -21,7 +21,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_metadata::creader::CStore;
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode};
use rustc_span::symbol::kw;
-use rustc_span::{Ident, Symbol};
+use rustc_span::{Ident, Symbol, sym};
use tracing::{debug, trace};
use super::url_parts_builder::UrlPartsBuilder;
@@ -537,11 +537,25 @@ fn generate_item_def_id_path(
&& !def_id.is_local()
&& def_id.krate != original_def_id.krate;
} else {
+ // This hack is because primitive types are only documented in `core` and `std`.
+ // However, with `#[rustc_allow_incoherent_impl]`, a lot of primitive methods are
+ // implemented in `core`. Some of them are documented in `core` (like `[]::sort`) while
+ // others aren't (like `[]::to_vec`). So in case we're not documenting `core`, we link
+ // to `std`.
+ if !of_trait && crate_name != sym::core {
+ if ![sym::alloc, sym::std].contains(&crate_name) {
+ // We cannot link to this primitive's associated item as it's not part of
+ // `core`, `alloc` or `std` so returning early.
+ return Err(HrefError::UnnamableItem);
+ }
+ maybe_have_impl_not_in_def_crate = true;
+ }
prim = PrimitiveType::from_ty(ty);
}
}
let (shortty, fqp) = if let Some(prim) = prim {
+ let crate_name = if maybe_have_impl_not_in_def_crate { sym::std } else { crate_name };
(ItemType::Primitive, vec![crate_name, prim.as_sym()])
} else {
(
diff --git a/tests/mir-opt/const_prop/maybe_uninit.rs b/tests/mir-opt/const_prop/maybe_uninit.rs
index 649fea6252216..89c395a7be5bb 100644
--- a/tests/mir-opt/const_prop/maybe_uninit.rs
+++ b/tests/mir-opt/const_prop/maybe_uninit.rs
@@ -8,3 +8,10 @@ pub fn u8_array() -> [MaybeUninit; 8] {
// CHECK: _0 = const ;
[MaybeUninit::uninit(); 8]
}
+
+// EMIT_MIR maybe_uninit.u8_array_assume_init.GVN.diff
+pub fn u8_array_assume_init() -> [MaybeUninit; 8] {
+ // CHECK: fn u8_array_assume_init(
+ // CHECK: _0 = const ;
+ unsafe { MaybeUninit::uninit().assume_init() }
+}
diff --git a/tests/mir-opt/const_prop/maybe_uninit.u8_array_assume_init.GVN.diff b/tests/mir-opt/const_prop/maybe_uninit.u8_array_assume_init.GVN.diff
new file mode 100644
index 0000000000000..e0c4af329fadc
--- /dev/null
+++ b/tests/mir-opt/const_prop/maybe_uninit.u8_array_assume_init.GVN.diff
@@ -0,0 +1,36 @@
+- // MIR for `u8_array_assume_init` before GVN
++ // MIR for `u8_array_assume_init` after GVN
+
+ fn u8_array_assume_init() -> [MaybeUninit; 8] {
+ let mut _0: [std::mem::MaybeUninit; 8];
+ let mut _1: std::mem::MaybeUninit<[std::mem::MaybeUninit; 8]>;
+ scope 1 (inlined MaybeUninit::<[MaybeUninit; 8]>::uninit) {
+ }
+ scope 2 (inlined #[track_caller] MaybeUninit::<[MaybeUninit; 8]>::assume_init) {
+ scope 3 (inlined transmute_neo::; 8]>, [MaybeUninit; 8]>) {
+ }
+ }
+
+ bb0: {
+ StorageLive(_1);
+- _1 = MaybeUninit::<[MaybeUninit; 8]> { uninit: const () };
++ _1 = const ;
+ goto -> bb1;
+ }
+
+ bb1: {
+- _0 = copy _1 as [std::mem::MaybeUninit; 8] (Transmute);
++ _0 = const ;
+ StorageDead(_1);
+ return;
+ }
++ }
++
++ ALLOC0 (size: 8, align: 1) {
++ __ __ __ __ __ __ __ __ │ ░░░░░░░░
++ }
++
++ ALLOC1 (size: 8, align: 1) {
++ __ __ __ __ __ __ __ __ │ ░░░░░░░░
+ }
+
diff --git a/tests/rustdoc-html/jump-to-def/auxiliary/incoherent_impl_primitive.rs b/tests/rustdoc-html/jump-to-def/auxiliary/incoherent_impl_primitive.rs
new file mode 100644
index 0000000000000..98e9a5129417c
--- /dev/null
+++ b/tests/rustdoc-html/jump-to-def/auxiliary/incoherent_impl_primitive.rs
@@ -0,0 +1,7 @@
+#![feature(rustc_attrs)]
+#![allow(internal_features)]
+
+impl [T] {
+ #[rustc_allow_incoherent_impl]
+ pub fn f(&self) {}
+}
diff --git a/tests/rustdoc-html/jump-to-def/incoherent_impl-primitive.rs b/tests/rustdoc-html/jump-to-def/incoherent_impl-primitive.rs
new file mode 100644
index 0000000000000..9a4609953a178
--- /dev/null
+++ b/tests/rustdoc-html/jump-to-def/incoherent_impl-primitive.rs
@@ -0,0 +1,25 @@
+// This test checks that outside of `core`/`alloc`/`std`, we don't link to incoherent method impl
+// because there is no page to link to since primitive are only documented in `core` and `std`.
+
+//@ aux-build: incoherent_impl_primitive.rs
+//@ build-aux-docs
+//@ compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+extern crate incoherent_impl_primitive;
+
+//@ has 'src/foo/incoherent_impl-primitive.rs.html'
+
+// It should contain only the link to "first". Sadly, because of the limit, we cannot test
+// if a link doesn't have an attribute so for now, we simply ensure that the number of ``
+// (including both line numbers and jump to def links) is superior by one to the number of
+// line ``. If so, we know there is only one jump to def link.
+//@ count - '//pre/code/a' 7
+//@ count - '//pre/code/a[@id]' 6
+//@ has - '//pre/code/a[@href="{{channel}}/core/primitive.slice.html#method.first"]' 'first'
+
+fn foo() {
+ let x = ["a"].f();
+ ["a"].first();
+}
diff --git a/tests/ui/associated-inherent-types/issue-111404-1.stderr b/tests/ui/associated-inherent-types/issue-111404-1.current.stderr
similarity index 88%
rename from tests/ui/associated-inherent-types/issue-111404-1.stderr
rename to tests/ui/associated-inherent-types/issue-111404-1.current.stderr
index 9a5b69497c0cf..b77b3c00a69f9 100644
--- a/tests/ui/associated-inherent-types/issue-111404-1.stderr
+++ b/tests/ui/associated-inherent-types/issue-111404-1.current.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/issue-111404-1.rs:10:11
+ --> $DIR/issue-111404-1.rs:14:11
|
LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -8,7 +8,7 @@ LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
found struct `Foo fn(&'b ())>`
error[E0308]: mismatched types
- --> $DIR/issue-111404-1.rs:10:11
+ --> $DIR/issue-111404-1.rs:14:11
|
LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -18,13 +18,13 @@ LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: higher-ranked subtype error
- --> $DIR/issue-111404-1.rs:10:1
+ --> $DIR/issue-111404-1.rs:14:1
|
LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
- --> $DIR/issue-111404-1.rs:10:1
+ --> $DIR/issue-111404-1.rs:14:1
|
LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: higher-ranked subtype error
- --> $DIR/issue-111404-1.rs:10:8
+ --> $DIR/issue-111404-1.rs:14:8
|
LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
| ^
diff --git a/tests/ui/associated-inherent-types/issue-111404-1.next.stderr b/tests/ui/associated-inherent-types/issue-111404-1.next.stderr
new file mode 100644
index 0000000000000..812a6ee052d29
--- /dev/null
+++ b/tests/ui/associated-inherent-types/issue-111404-1.next.stderr
@@ -0,0 +1,9 @@
+error[E0271]: type mismatch resolving `Foo::Assoc == &()`
+ --> $DIR/issue-111404-1.rs:14:11
+ |
+LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-inherent-types/issue-111404-1.rs b/tests/ui/associated-inherent-types/issue-111404-1.rs
index cad6d48b1c5af..a23856d0eac8d 100644
--- a/tests/ui/associated-inherent-types/issue-111404-1.rs
+++ b/tests/ui/associated-inherent-types/issue-111404-1.rs
@@ -1,3 +1,7 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@ [next] compile-flags: -Znext-solver
+
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
@@ -8,10 +12,11 @@ impl<'a> Foo {
}
fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
-//~^ ERROR mismatched types [E0308]
-//~| ERROR mismatched types [E0308]
-//~| ERROR higher-ranked subtype error
-//~| ERROR higher-ranked subtype error
-//~| ERROR higher-ranked subtype error
+//[current]~^ ERROR mismatched types [E0308]
+//[current]~| ERROR mismatched types [E0308]
+//[current]~| ERROR higher-ranked subtype error
+//[current]~| ERROR higher-ranked subtype error
+//[current]~| ERROR higher-ranked subtype error
+//[next]~^^^^^^ ERROR type mismatch resolving
fn main() {}
diff --git a/tests/ui/checked-type-alias/variance-1.stderr b/tests/ui/checked-type-alias/variance-1.stderr
index 5eb2f5d0673aa..40b59b43910e8 100644
--- a/tests/ui/checked-type-alias/variance-1.stderr
+++ b/tests/ui/checked-type-alias/variance-1.stderr
@@ -10,7 +10,7 @@ error[E0392]: type parameter `T` is never used
--> $DIR/variance-1.rs:17:24
|
LL | struct WrapDiscard<'a, T>(Discard<'a, T>);
- | ^ - `T` is named here, but is likely unused in the containing type
+ | ^ - `T` is named here, but is not used in the type that wraps it
| |
| unused type parameter
|
diff --git a/tests/ui/checked-type-alias/variance-overflow.rs b/tests/ui/checked-type-alias/variance-overflow.rs
index 0b5b58e083133..3da7da1ed425d 100644
--- a/tests/ui/checked-type-alias/variance-overflow.rs
+++ b/tests/ui/checked-type-alias/variance-overflow.rs
@@ -19,4 +19,15 @@ struct First(Second);
type Second = Second; // diverging free alias type
//~^ ERROR overflow normalizing the type alias `Second`
+// The same applies when a diverging alias mentions a type parameter. The argument grows with
+// every step, so there is no repeated `(DefId, args)` pair to detect the divergence with.
+// Variance inference must stop at the recursion limit, and reporting the unused parameter
+// must not restart the expansion.
+type Diverging = Diverging<(T,)>;
+//~^ ERROR overflow normalizing the type alias `Diverging<
+
+struct Wrap(Diverging);
+//~^ ERROR type parameter `T` is never used
+//~| ERROR overflow normalizing the type alias `Diverging<
+
fn main() {}
diff --git a/tests/ui/checked-type-alias/variance-overflow.stderr b/tests/ui/checked-type-alias/variance-overflow.stderr
index 35486ccdc169f..3ea61d9ade9f3 100644
--- a/tests/ui/checked-type-alias/variance-overflow.stderr
+++ b/tests/ui/checked-type-alias/variance-overflow.stderr
@@ -23,7 +23,34 @@ LL | type Second = Second; // diverging free alias type
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
-error: aborting due to 3 previous errors
+error[E0275]: overflow normalizing the type alias `Diverging<(((((((_,),),),),),),)>`
+ --> $DIR/variance-overflow.rs:26:1
+ |
+LL | type Diverging = Diverging<(T,)>;
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-overflow.rs:29:13
+ |
+LL | struct Wrap(Diverging);
+ | ^ - `T` is named here, but is not used in the type that wraps it
+ | |
+ | unused type parameter
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0275]: overflow normalizing the type alias `Diverging<(((((((_,),),),),),),)>`
+ --> $DIR/variance-overflow.rs:29:16
+ |
+LL | struct Wrap(Diverging);
+ | ^^^^^^^^^^^^
+ |
+ = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error: aborting due to 6 previous errors
Some errors have detailed explanations: E0275, E0392.
For more information about an error, try `rustc --explain E0275`.
diff --git a/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.rs b/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.rs
new file mode 100644
index 0000000000000..22542e4142fb5
--- /dev/null
+++ b/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.rs
@@ -0,0 +1,25 @@
+// A mention forwarded through free aliases still does not count as a use when the final type
+// ignores the parameter. The diagnostic should label the original mention even though the
+// intermediate aliases mention the parameter too.
+
+#![feature(checked_type_aliases)]
+
+struct Ignores {}
+//~^ ERROR type parameter `T` is never used
+
+type Forward = Discard;
+type Discard = Ignores;
+
+struct Wrap(Forward);
+//~^ ERROR type parameter `T` is never used
+
+// An alias can occur with different arguments in the same type. Here `Repeat` preserves its
+// parameter through `Id`, so the enclosing struct uses `T` only recursively. The unrelated
+// `Id` must not hide that recursive use.
+type Id = T;
+type Repeat = (Id, Id);
+
+struct Recursive(Repeat>>);
+//~^ ERROR type parameter `T` is only used recursively
+
+fn main() {}
diff --git a/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.stderr b/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.stderr
new file mode 100644
index 0000000000000..069916d57b514
--- /dev/null
+++ b/tests/ui/checked-type-alias/variance-unused-param-through-alias-chain.stderr
@@ -0,0 +1,34 @@
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-unused-param-through-alias-chain.rs:7:16
+ |
+LL | struct Ignores {}
+ | ^ unused type parameter
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-unused-param-through-alias-chain.rs:13:13
+ |
+LL | struct Wrap(Forward);
+ | ^ - `T` is named here, but is not used in the type that wraps it
+ | |
+ | unused type parameter
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: type parameter `T` is only used recursively
+ --> $DIR/variance-unused-param-through-alias-chain.rs:22:42
+ |
+LL | struct Recursive(Repeat>>);
+ | - ^
+ | |
+ | type parameter must be used non-recursively in the definition
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = note: all type parameters must be used in a non-recursive way in order to constrain their variance
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.dedup.stderr b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.dedup.stderr
new file mode 100644
index 0000000000000..e8fb5732febdc
--- /dev/null
+++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.dedup.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.dup.stderr b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.dup.stderr
new file mode 100644
index 0000000000000..017884aff53a4
--- /dev/null
+++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.dup.stderr
@@ -0,0 +1,54 @@
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.incr-dedup.stderr b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.incr-dedup.stderr
new file mode 100644
index 0000000000000..e8fb5732febdc
--- /dev/null
+++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.incr-dedup.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.incr-dup.stderr b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.incr-dup.stderr
new file mode 100644
index 0000000000000..017884aff53a4
--- /dev/null
+++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.incr-dup.stderr
@@ -0,0 +1,54 @@
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
+ --> $DIR/deduplicate-diagnostics-incr.rs:11:11
+ |
+LL | #[global_allocator]
+ | ------------------- in this attribute macro expansion
+LL | static A: usize = 0;
+ | ^^^^^ the nightly-only, unstable trait `GlobalAllocator` is not implemented for `usize`
+ |
+help: the trait `GlobalAllocator` is implemented for `System`
+ --> $SRC_DIR/std/src/alloc.rs:LL:COL
+ = note: required for `usize` to implement `GlobalAlloc`
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.rs b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.rs
new file mode 100644
index 0000000000000..72bed90bba4c7
--- /dev/null
+++ b/tests/ui/diagnostic-flags/deduplicate-diagnostics-incr.rs
@@ -0,0 +1,17 @@
+//! Test that span parents (which are incremental only) are ignored when deduplicating diagnostics.
+//! Regression test for #162901.
+
+//@ revisions: dedup dup incr-dedup incr-dup
+//@[dedup] compile-flags: -Z deduplicate-diagnostics=yes
+//@[incr-dup] incremental
+//@[incr-dedup] incremental
+//@[incr-dedup] compile-flags: -Z deduplicate-diagnostics=yes
+
+#[global_allocator]
+static A: usize = 0;
+//[dedup,dup,incr-dedup,incr-dup]~^ ERROR E0277
+//[dup,incr-dup]~| ERROR E0277
+//[dup,incr-dup]~| ERROR E0277
+//[dup,incr-dup]~| ERROR E0277
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.rs b/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.rs
index 17a81b5705dfb..6acc1baf319ef 100644
--- a/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.rs
+++ b/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.rs
@@ -11,8 +11,6 @@ impl<'a> Foo {
}
fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
-//~^ ERROR: higher-ranked subtype error
-//~| ERROR: lifetime bound not satisfied [E0478]
-//~| ERROR: lifetime bound not satisfied [E0478]
+//~^ ERROR type mismatch resolving
fn main() {}
diff --git a/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.stderr b/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.stderr
index 47227014ec567..4a032c267e80a 100644
--- a/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.stderr
+++ b/tests/ui/traits/next-solver/implied_outlives_bounds_not_resolving_vars_ice.stderr
@@ -1,23 +1,9 @@
-error[E0478]: lifetime bound not satisfied
+error[E0271]: type mismatch resolving `Foo::Assoc == &()`
--> $DIR/implied_outlives_bounds_not_resolving_vars_ice.rs:13:11
|
LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
-error[E0478]: lifetime bound not satisfied
- --> $DIR/implied_outlives_bounds_not_resolving_vars_ice.rs:13:11
- |
-LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: higher-ranked subtype error
- --> $DIR/implied_outlives_bounds_not_resolving_vars_ice.rs:13:8
- |
-LL | fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {}
- | ^
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
-For more information about this error, try `rustc --explain E0478`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/traits/next-solver/normalize/deeply-normalize-fallback-issue-160875.rs b/tests/ui/traits/next-solver/normalize/deeply-normalize-fallback-issue-160875.rs
new file mode 100644
index 0000000000000..de94cad403a3a
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize/deeply-normalize-fallback-issue-160875.rs
@@ -0,0 +1,34 @@
+//@ needs-rustc-debug-assertions
+//@ compile-flags: -Znext-solver
+
+// Regression test for #160875.
+//
+// Eagerly normalizing the inner alias makes the outer alias fail the leak check:
+// `Foo fn(&'b ())>` cannot be equated with the impl's `Foo`.
+// Deep normalization must propagate that failure. Retrying the original aliases
+// with `ReplaceAliasWithInfer` instead moved the lifetime equalities into nested
+// goals, whose constraints were invisible to the parent's leak check.
+//
+// The fallback incorrectly succeeded and returned `fn(?3t)`. Resolving that value
+// only hid the failed leak check. With debug assertions enabled, returning the
+// unresolved value also triggered an assertion in `normalize_erasing_regions`.
+//
+// The invalid const body reaches MIR signature normalization in metadata-only
+// tests. Keep debug assertions enabled to catch the original ICE as well.
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Foo(T);
+
+impl<'a> Foo {
+ type Assoc = &'a ();
+}
+
+const fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {
+ //~^ ERROR type mismatch resolving
+ x
+ //~^ ERROR cannot find value `x` in this scope
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize/deeply-normalize-fallback-issue-160875.stderr b/tests/ui/traits/next-solver/normalize/deeply-normalize-fallback-issue-160875.stderr
new file mode 100644
index 0000000000000..680e5f702b423
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize/deeply-normalize-fallback-issue-160875.stderr
@@ -0,0 +1,16 @@
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/deeply-normalize-fallback-issue-160875.rs:30:5
+ |
+LL | x
+ | ^ not found in this scope
+
+error[E0271]: type mismatch resolving `Foo::Assoc == &()`
+ --> $DIR/deeply-normalize-fallback-issue-160875.rs:28:17
+ |
+LL | const fn bar(_: fn(Foo fn(Foo::Assoc)>::Assoc)) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0271, E0425.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/variance/variance-unused-type-param.rs b/tests/ui/variance/variance-unused-type-param.rs
index ef3c41ca5560c..bad994b5e280d 100644
--- a/tests/ui/variance/variance-unused-type-param.rs
+++ b/tests/ui/variance/variance-unused-type-param.rs
@@ -33,4 +33,29 @@ struct DoubleNothing {
s: SomeStruct,
}
+// A mention nested inside another type argument still does not count as a use.
+struct NestedNothing {
+//~^ ERROR parameter `T` is never used
+ s: SomeStruct>,
+}
+
+type Discard = ();
+//~^ ERROR parameter `T` is never used
+
+struct ThroughTypeAlias(Discard);
+//~^ ERROR parameter `T` is never used
+
+// Only the unused parameter should receive the diagnostic.
+struct SecondUnused { a: A }
+//~^ ERROR parameter `B` is never used
+
+struct UsesSecondUnused(SecondUnused);
+//~^ ERROR parameter `T` is never used
+
+// The alias mentions `T`, but only to forward it to something that throws it away.
+type Forward = SomeStruct;
+
+struct ThroughForwardingAlias(Forward);
+//~^ ERROR parameter `T` is never used
+
fn main() {}
diff --git a/tests/ui/variance/variance-unused-type-param.stderr b/tests/ui/variance/variance-unused-type-param.stderr
index c747532e62836..d02addc5a5e53 100644
--- a/tests/ui/variance/variance-unused-type-param.stderr
+++ b/tests/ui/variance/variance-unused-type-param.stderr
@@ -69,11 +69,75 @@ LL | struct DoubleNothing {
| ^ unused type parameter
LL |
LL | s: SomeStruct,
- | - `T` is named here, but is likely unused in the containing type
+ | - `T` is named here, but is not used in the type that wraps it
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
-error: aborting due to 8 previous errors
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-unused-type-param.rs:37:22
+ |
+LL | struct NestedNothing {
+ | ^ unused type parameter
+LL |
+LL | s: SomeStruct>,
+ | - `T` is named here, but is not used in the type that wraps it
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0091]: type parameter `T` is never used
+ --> $DIR/variance-unused-type-param.rs:42:14
+ |
+LL | type Discard = ();
+ | ^ unused type parameter
+ |
+ = help: consider removing `T` or referring to it in the body of the type alias
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-unused-type-param.rs:45:25
+ |
+LL | struct ThroughTypeAlias(Discard);
+ | ^ - `T` is named here, but is not used in the type that wraps it
+ | |
+ | unused type parameter
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `B` is never used
+ --> $DIR/variance-unused-type-param.rs:49:24
+ |
+LL | struct SecondUnused { a: A }
+ | ^ unused type parameter
+ |
+ = help: consider removing `B`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `B` to be a const parameter, use `const B: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-unused-type-param.rs:52:25
+ |
+LL | struct UsesSecondUnused(SecondUnused);
+ | ^ - `T` is named here, but is not used in the type that wraps it
+ | |
+ | unused type parameter
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+ --> $DIR/variance-unused-type-param.rs:58:31
+ |
+LL | struct ThroughForwardingAlias(Forward);
+ | ^ - `T` is named here, but is not used in the type that wraps it
+ | |
+ | unused type parameter
+ |
+ = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+ = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error: aborting due to 14 previous errors
-For more information about this error, try `rustc --explain E0392`.
+Some errors have detailed explanations: E0091, E0392.
+For more information about an error, try `rustc --explain E0091`.
diff --git a/typos.toml b/typos.toml
index 8976759b3b259..215a971527e85 100644
--- a/typos.toml
+++ b/typos.toml
@@ -35,6 +35,7 @@ numer = "numer" # short for numerator, not a typo for "number"
old-skool = "old-skool" # variant spelling of "old-school"
optin = "optin" # short for opt-in
publically = "publically"
+raison = "raison" # part of the French phrase "raison d'être"
rplace = "rplace" # short for R-place
splitted = "splitted"
sythetic = "sythetic" # typo in vendored LLVM sources