Rollup merge of #147219 - Kivooeo:typeof-is-imposter, r=jdonszelmann
Add proper error handling for closure in impl
Fixes https://github.com/rust-lang/rust/issues/147146
Fixes https://github.com/rust-lang/rust/issues/146620
Not sure if it can cause any regressions or anything, as for test also have no idea where to store this one
cc ```@theemathas```
r? compiler
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index aa5c172..b1da6f7 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -34,7 +34,7 @@
use crate::back::write::to_llvm_code_model;
use crate::callee::get_fn;
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
-use crate::llvm::Metadata;
+use crate::llvm::{Metadata, MetadataKindId};
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util};
@@ -1006,11 +1006,11 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
pub(crate) fn set_metadata<'a>(
&self,
val: &'a Value,
- kind_id: impl Into<llvm::MetadataKindId>,
+ kind_id: MetadataKindId,
md: &'ll Metadata,
) {
let node = self.get_metadata_value(md);
- llvm::LLVMSetMetadata(val, kind_id.into(), node);
+ llvm::LLVMSetMetadata(val, kind_id, node);
}
}
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
index bc4f6bb..d50eb53 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
@@ -2,26 +2,25 @@
use std::ffi::CString;
-use crate::common::AsCCharPtr;
use crate::coverageinfo::ffi;
use crate::llvm;
pub(crate) fn covmap_var_name() -> CString {
- CString::new(llvm::build_byte_buffer(|s| unsafe {
+ CString::new(llvm::build_byte_buffer(|s| {
llvm::LLVMRustCoverageWriteCovmapVarNameToString(s);
}))
.expect("covmap variable name should not contain NUL")
}
pub(crate) fn covmap_section_name(llmod: &llvm::Module) -> CString {
- CString::new(llvm::build_byte_buffer(|s| unsafe {
+ CString::new(llvm::build_byte_buffer(|s| {
llvm::LLVMRustCoverageWriteCovmapSectionNameToString(llmod, s);
}))
.expect("covmap section name should not contain NUL")
}
pub(crate) fn covfun_section_name(llmod: &llvm::Module) -> CString {
- CString::new(llvm::build_byte_buffer(|s| unsafe {
+ CString::new(llvm::build_byte_buffer(|s| {
llvm::LLVMRustCoverageWriteCovfunSectionNameToString(llmod, s);
}))
.expect("covfun section name should not contain NUL")
@@ -34,7 +33,7 @@ pub(crate) fn create_pgo_func_name_var<'ll>(
unsafe {
llvm::LLVMRustCoverageCreatePGOFuncNameVar(
llfn,
- mangled_fn_name.as_c_char_ptr(),
+ mangled_fn_name.as_ptr(),
mangled_fn_name.len(),
)
}
@@ -44,7 +43,7 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef<str>]) -> Vec<u8
let (pointers, lengths) = filenames
.into_iter()
.map(AsRef::as_ref)
- .map(|s: &str| (s.as_c_char_ptr(), s.len()))
+ .map(|s: &str| (s.as_ptr(), s.len()))
.unzip::<_, _, Vec<_>, Vec<_>>();
llvm::build_byte_buffer(|buffer| unsafe {
@@ -89,12 +88,12 @@ pub(crate) fn write_function_mappings_to_buffer(
/// Hashes some bytes into a 64-bit hash, via LLVM's `IndexedInstrProf::ComputeHash`,
/// as required for parts of the LLVM coverage mapping format.
pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
- unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_c_char_ptr(), bytes.len()) }
+ unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_ptr(), bytes.len()) }
}
/// Returns LLVM's `coverage::CovMapVersion::CurrentVersion` (CoverageMapping.h)
/// as a raw numeric value. For historical reasons, the numeric value is 1 less
/// than the number in the version's name, so `Version7` is actually `6u32`.
pub(crate) fn mapping_version() -> u32 {
- unsafe { llvm::LLVMRustCoverageMappingVersion() }
+ llvm::LLVMRustCoverageMappingVersion()
}
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 1e4ace4..bc20c75 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1611,16 +1611,12 @@ enum VCallVisibility {
let v = [llvm::LLVMValueAsMetadata(cx.const_usize(0)), typeid];
llvm::LLVMRustGlobalAddMetadata(
vtable,
- llvm::MD_type as c_uint,
+ llvm::MD_type,
llvm::LLVMMDNodeInContext2(cx.llcx, v.as_ptr(), v.len()),
);
let vcall_visibility = llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64));
let vcall_visibility_metadata = llvm::LLVMMDNodeInContext2(cx.llcx, &vcall_visibility, 1);
- llvm::LLVMGlobalSetMetadata(
- vtable,
- llvm::MetadataType::MD_vcall_visibility as c_uint,
- vcall_visibility_metadata,
- );
+ llvm::LLVMGlobalSetMetadata(vtable, llvm::MD_vcall_visibility, vcall_visibility_metadata);
}
}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index afd2991..e9f9226 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -29,6 +29,7 @@
DITemplateTypeParameter, DIType, DebugEmissionKind, DebugNameTableKind,
};
use crate::llvm;
+use crate::llvm::MetadataKindId;
/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
/// which has a different ABI from Rust or C++ `bool`.
@@ -513,31 +514,6 @@ pub(crate) enum FileType {
ObjectFile,
}
-/// LLVMMetadataType
-#[derive(Copy, Clone)]
-#[repr(C)]
-#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
-pub(crate) enum MetadataType {
- MD_dbg = 0,
- MD_tbaa = 1,
- MD_prof = 2,
- MD_fpmath = 3,
- MD_range = 4,
- MD_tbaa_struct = 5,
- MD_invariant_load = 6,
- MD_alias_scope = 7,
- MD_noalias = 8,
- MD_nontemporal = 9,
- MD_mem_parallel_loop_access = 10,
- MD_nonnull = 11,
- MD_unpredictable = 15,
- MD_align = 17,
- MD_type = 19,
- MD_vcall_visibility = 28,
- MD_noundef = 29,
- MD_kcfi_type = 36,
-}
-
/// Must match the layout of `LLVMInlineAsmDialect`.
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
@@ -1035,16 +1011,6 @@ pub struct GEPNoWrapFlags : c_uint {
unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
pub(crate) type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
-#[derive(Copy, Clone)]
-#[repr(transparent)]
-pub(crate) struct MetadataKindId(c_uint);
-
-impl From<MetadataType> for MetadataKindId {
- fn from(value: MetadataType) -> Self {
- Self(value as c_uint)
- }
-}
-
unsafe extern "C" {
// Create and destroy contexts.
pub(crate) fn LLVMContextDispose(C: &'static mut Context);
@@ -1139,7 +1105,11 @@ pub(crate) fn LLVMStructTypeInContext<'a>(
pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t);
pub(crate) fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value);
pub(crate) safe fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: MetadataKindId, Node: &'a Value);
- pub(crate) fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
+ pub(crate) fn LLVMGlobalSetMetadata<'a>(
+ Val: &'a Value,
+ KindID: MetadataKindId,
+ Metadata: &'a Metadata,
+ );
pub(crate) safe fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
// Operations on constants of any type
@@ -2059,7 +2029,7 @@ pub(crate) fn LLVMDIBuilderCreateParameterVariable<'ll>(
// Operations on all values
pub(crate) fn LLVMRustGlobalAddMetadata<'a>(
Val: &'a Value,
- KindID: c_uint,
+ KindID: MetadataKindId,
Metadata: &'a Metadata,
);
pub(crate) fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
@@ -2256,8 +2226,11 @@ pub(crate) fn LLVMRustInlineAsmVerify(
ConstraintsLen: size_t,
) -> bool;
+ /// A list of pointer-length strings is passed as two pointer-length slices,
+ /// one slice containing pointers and one slice containing their corresponding
+ /// lengths. The implementation will check that both slices have the same length.
pub(crate) fn LLVMRustCoverageWriteFilenamesToBuffer(
- Filenames: *const *const c_char,
+ Filenames: *const *const c_uchar, // See "PTR_LEN_STR".
FilenamesLen: size_t,
Lengths: *const size_t,
LengthsLen: size_t,
@@ -2280,18 +2253,25 @@ pub(crate) fn LLVMRustCoverageWriteFunctionMappingsToBuffer(
pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar(
F: &Value,
- FuncName: *const c_char,
+ FuncName: *const c_uchar, // See "PTR_LEN_STR".
FuncNameLen: size_t,
) -> &Value;
- pub(crate) fn LLVMRustCoverageHashBytes(Bytes: *const c_char, NumBytes: size_t) -> u64;
+ pub(crate) fn LLVMRustCoverageHashBytes(
+ Bytes: *const c_uchar, // See "PTR_LEN_STR".
+ NumBytes: size_t,
+ ) -> u64;
- pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString);
+ pub(crate) safe fn LLVMRustCoverageWriteCovmapSectionNameToString(
+ M: &Module,
+ OutStr: &RustString,
+ );
+ pub(crate) safe fn LLVMRustCoverageWriteCovfunSectionNameToString(
+ M: &Module,
+ OutStr: &RustString,
+ );
+ pub(crate) safe fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
- pub(crate) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString);
-
- pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
-
- pub(crate) fn LLVMRustCoverageMappingVersion() -> u32;
+ pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32;
pub(crate) fn LLVMRustDebugMetadataVersion() -> u32;
pub(crate) fn LLVMRustVersionMajor() -> u32;
pub(crate) fn LLVMRustVersionMinor() -> u32;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs
new file mode 100644
index 0000000..a8a671b
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs
@@ -0,0 +1,71 @@
+use libc::c_uint;
+
+pub(crate) use self::fixed_kinds::*;
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub(crate) struct MetadataKindId(c_uint);
+
+macro_rules! declare_fixed_metadata_kinds {
+ (
+ $(
+ FIXED_MD_KIND($variant:ident, $value:literal)
+ )*
+ ) => {
+ // Use a submodule to group all declarations into one `#[expect(..)]`.
+ #[expect(dead_code)]
+ mod fixed_kinds {
+ use super::MetadataKindId;
+ $(
+ #[expect(non_upper_case_globals)]
+ pub(crate) const $variant: MetadataKindId = MetadataKindId($value);
+ )*
+ }
+ };
+}
+
+// Must be kept in sync with the corresponding static assertions in `RustWrapper.cpp`.
+declare_fixed_metadata_kinds! {
+ FIXED_MD_KIND(MD_dbg, 0)
+ FIXED_MD_KIND(MD_tbaa, 1)
+ FIXED_MD_KIND(MD_prof, 2)
+ FIXED_MD_KIND(MD_fpmath, 3)
+ FIXED_MD_KIND(MD_range, 4)
+ FIXED_MD_KIND(MD_tbaa_struct, 5)
+ FIXED_MD_KIND(MD_invariant_load, 6)
+ FIXED_MD_KIND(MD_alias_scope, 7)
+ FIXED_MD_KIND(MD_noalias, 8)
+ FIXED_MD_KIND(MD_nontemporal, 9)
+ FIXED_MD_KIND(MD_mem_parallel_loop_access, 10)
+ FIXED_MD_KIND(MD_nonnull, 11)
+ FIXED_MD_KIND(MD_dereferenceable, 12)
+ FIXED_MD_KIND(MD_dereferenceable_or_null, 13)
+ FIXED_MD_KIND(MD_make_implicit, 14)
+ FIXED_MD_KIND(MD_unpredictable, 15)
+ FIXED_MD_KIND(MD_invariant_group, 16)
+ FIXED_MD_KIND(MD_align, 17)
+ FIXED_MD_KIND(MD_loop, 18)
+ FIXED_MD_KIND(MD_type, 19)
+ FIXED_MD_KIND(MD_section_prefix, 20)
+ FIXED_MD_KIND(MD_absolute_symbol, 21)
+ FIXED_MD_KIND(MD_associated, 22)
+ FIXED_MD_KIND(MD_callees, 23)
+ FIXED_MD_KIND(MD_irr_loop, 24)
+ FIXED_MD_KIND(MD_access_group, 25)
+ FIXED_MD_KIND(MD_callback, 26)
+ FIXED_MD_KIND(MD_preserve_access_index, 27)
+ FIXED_MD_KIND(MD_vcall_visibility, 28)
+ FIXED_MD_KIND(MD_noundef, 29)
+ FIXED_MD_KIND(MD_annotation, 30)
+ FIXED_MD_KIND(MD_nosanitize, 31)
+ FIXED_MD_KIND(MD_func_sanitize, 32)
+ FIXED_MD_KIND(MD_exclude, 33)
+ FIXED_MD_KIND(MD_memprof, 34)
+ FIXED_MD_KIND(MD_callsite, 35)
+ FIXED_MD_KIND(MD_kcfi_type, 36)
+ FIXED_MD_KIND(MD_pcsections, 37)
+ FIXED_MD_KIND(MD_DIAssignID, 38)
+ FIXED_MD_KIND(MD_coro_outside_frame, 39)
+ FIXED_MD_KIND(MD_mmra, 40)
+ FIXED_MD_KIND(MD_noalias_addrspace, 41)
+}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index 1115d82..9a53dac 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -11,13 +11,14 @@
pub(crate) use self::CallConv::*;
pub(crate) use self::CodeGenOptSize::*;
-pub(crate) use self::MetadataType::*;
pub(crate) use self::ffi::*;
+pub(crate) use self::metadata_kind::*;
use crate::common::AsCCharPtr;
pub(crate) mod diagnostic;
pub(crate) mod enzyme_ffi;
mod ffi;
+mod metadata_kind;
pub(crate) use self::enzyme_ffi::*;
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 9ecaf5f..5b97898 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -306,7 +306,7 @@ fn add_type_metadata(&self, function: &'ll Value, typeid: &[u8]) {
let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata];
llvm::LLVMRustGlobalAddMetadata(
function,
- llvm::MD_type as c_uint,
+ llvm::MD_type,
llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()),
)
}
@@ -318,7 +318,7 @@ fn set_type_metadata(&self, function: &'ll Value, typeid: &[u8]) {
let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata];
llvm::LLVMGlobalSetMetadata(
function,
- llvm::MD_type as c_uint,
+ llvm::MD_type,
llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()),
)
}
@@ -333,7 +333,7 @@ fn add_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) {
unsafe {
llvm::LLVMRustGlobalAddMetadata(
function,
- llvm::MD_kcfi_type as c_uint,
+ llvm::MD_kcfi_type,
llvm::LLVMMDNodeInContext2(
self.llcx,
&llvm::LLVMValueAsMetadata(kcfi_type_metadata),
@@ -348,7 +348,7 @@ fn set_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) {
unsafe {
llvm::LLVMGlobalSetMetadata(
function,
- llvm::MD_kcfi_type as c_uint,
+ llvm::MD_kcfi_type,
llvm::LLVMMDNodeInContext2(
self.llcx,
&llvm::LLVMValueAsMetadata(kcfi_type_metadata),
diff --git a/compiler/rustc_error_codes/src/error_codes/E0719.md b/compiler/rustc_error_codes/src/error_codes/E0719.md
index cd981db..6aec38b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0719.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0719.md
@@ -1,4 +1,4 @@
-An associated type value was specified more than once.
+An associated item was specified more than once in a trait object.
Erroneous code example:
@@ -7,21 +7,15 @@
trait BarTrait {}
// error: associated type `Item` in trait `Iterator` is specified twice
-struct Foo<T: Iterator<Item: FooTrait, Item: BarTrait>> { f: T }
+type Foo = dyn Iterator<Item = u32, Item = u32>;
```
-`Item` in trait `Iterator` cannot be specified multiple times for struct `Foo`.
-To fix this, create a new trait that is a combination of the desired traits and
-specify the associated type with the new trait.
+To fix this, remove the duplicate specifier:
Corrected example:
```
-trait FooTrait {}
-trait BarTrait {}
-trait FooBarTrait: FooTrait + BarTrait {}
-
-struct Foo<T: Iterator<Item: FooBarTrait>> { f: T } // ok!
+type Foo = dyn Iterator<Item = u32>; // ok!
```
For more information about associated types, see [the book][bk-at]. For more
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index ba54fa8..9841faf 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -12,7 +12,7 @@
use super::ItemCtxt;
use super::predicates_of::assert_only_contains_predicates_from;
-use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter};
+use crate::hir_ty_lowering::{HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter};
/// For associated types we include both bounds written on the type
/// (`type X: Trait`) and predicates from the trait: `where Self::X: Trait`.
@@ -37,7 +37,14 @@ fn associated_type_bounds<'tcx>(
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
let mut bounds = Vec::new();
- icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
+ icx.lowerer().lower_bounds(
+ item_ty,
+ hir_bounds,
+ &mut bounds,
+ ty::List::empty(),
+ filter,
+ OverlappingAsssocItemConstraints::Allowed,
+ );
match filter {
PredicateFilter::All
@@ -347,7 +354,14 @@ fn opaque_type_bounds<'tcx>(
ty::print::with_reduced_queries!({
let icx = ItemCtxt::new(tcx, opaque_def_id);
let mut bounds = Vec::new();
- icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
+ icx.lowerer().lower_bounds(
+ item_ty,
+ hir_bounds,
+ &mut bounds,
+ ty::List::empty(),
+ filter,
+ OverlappingAsssocItemConstraints::Allowed,
+ );
// Implicit bounds are added to opaque types unless a `?Trait` bound is found
match filter {
PredicateFilter::All
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index dd3590f..ffdf2a2 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -18,7 +18,9 @@
use crate::collect::ItemCtxt;
use crate::constrained_generic_params as cgp;
use crate::delegation::inherit_predicates_for_delegation_item;
-use crate::hir_ty_lowering::{HirTyLowerer, PredicateFilter, RegionInferReason};
+use crate::hir_ty_lowering::{
+ HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
+};
/// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `explicit_predicates_of`, plus
@@ -187,6 +189,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
&mut bounds,
ty::List::empty(),
PredicateFilter::All,
+ OverlappingAsssocItemConstraints::Allowed,
);
icx.lowerer().add_sizedness_bounds(
&mut bounds,
@@ -289,6 +292,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
&mut bounds,
bound_vars,
PredicateFilter::All,
+ OverlappingAsssocItemConstraints::Allowed,
);
predicates.extend(bounds);
}
@@ -659,7 +663,14 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
let self_param_ty = tcx.types.self_param;
let mut bounds = Vec::new();
- icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
+ icx.lowerer().lower_bounds(
+ self_param_ty,
+ superbounds,
+ &mut bounds,
+ ty::List::empty(),
+ filter,
+ OverlappingAsssocItemConstraints::Allowed,
+ );
match filter {
PredicateFilter::All
| PredicateFilter::SelfOnly
@@ -984,6 +995,7 @@ fn probe_ty_param_bounds_in_generics(
&mut bounds,
bound_vars,
filter,
+ OverlappingAsssocItemConstraints::Allowed,
);
}
@@ -1063,6 +1075,7 @@ pub(super) fn const_conditions<'tcx>(
&mut bounds,
bound_vars,
PredicateFilter::ConstIfConst,
+ OverlappingAsssocItemConstraints::Allowed,
);
}
_ => {}
@@ -1083,6 +1096,7 @@ pub(super) fn const_conditions<'tcx>(
&mut bounds,
ty::List::empty(),
PredicateFilter::ConstIfConst,
+ OverlappingAsssocItemConstraints::Allowed,
);
}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index 99dc8e6..8682fdc 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -21,7 +21,8 @@
use super::errors::GenericsArgsErrExtend;
use crate::errors;
use crate::hir_ty_lowering::{
- AssocItemQSelf, FeedConstTy, HirTyLowerer, PredicateFilter, RegionInferReason,
+ AssocItemQSelf, FeedConstTy, HirTyLowerer, OverlappingAsssocItemConstraints, PredicateFilter,
+ RegionInferReason,
};
#[derive(Debug, Default)]
@@ -338,6 +339,7 @@ pub(crate) fn lower_bounds<'hir, I: IntoIterator<Item = &'hir hir::GenericBound<
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
predicate_filter: PredicateFilter,
+ overlapping_assoc_constraints: OverlappingAsssocItemConstraints,
) where
'tcx: 'hir,
{
@@ -362,6 +364,7 @@ pub(crate) fn lower_bounds<'hir, I: IntoIterator<Item = &'hir hir::GenericBound<
param_ty,
bounds,
predicate_filter,
+ overlapping_assoc_constraints,
);
}
hir::GenericBound::Outlives(lifetime) => {
@@ -402,7 +405,7 @@ pub(super) fn lower_assoc_item_constraint(
trait_ref: ty::PolyTraitRef<'tcx>,
constraint: &hir::AssocItemConstraint<'tcx>,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
- duplicates: &mut FxIndexMap<DefId, Span>,
+ duplicates: Option<&mut FxIndexMap<DefId, Span>>,
path_span: Span,
predicate_filter: PredicateFilter,
) -> Result<(), ErrorGuaranteed> {
@@ -458,17 +461,19 @@ pub(super) fn lower_assoc_item_constraint(
)
.expect("failed to find associated item");
- duplicates
- .entry(assoc_item.def_id)
- .and_modify(|prev_span| {
- self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
- span: constraint.span,
- prev_span: *prev_span,
- item_name: constraint.ident,
- def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
- });
- })
- .or_insert(constraint.span);
+ if let Some(duplicates) = duplicates {
+ duplicates
+ .entry(assoc_item.def_id)
+ .and_modify(|prev_span| {
+ self.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
+ span: constraint.span,
+ prev_span: *prev_span,
+ item_name: constraint.ident,
+ def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
+ });
+ })
+ .or_insert(constraint.span);
+ }
let projection_term = if let ty::AssocTag::Fn = assoc_tag {
let bound_vars = tcx.late_bound_vars(constraint.hir_id);
@@ -600,6 +605,7 @@ pub(super) fn lower_assoc_item_constraint(
bounds,
projection_ty.bound_vars(),
predicate_filter,
+ OverlappingAsssocItemConstraints::Allowed,
);
}
PredicateFilter::SelfOnly
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
index c248cd7..c0b1377 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs
@@ -23,7 +23,9 @@
use super::HirTyLowerer;
use crate::errors::SelfInTypeAlias;
-use crate::hir_ty_lowering::{GenericArgCountMismatch, PredicateFilter, RegionInferReason};
+use crate::hir_ty_lowering::{
+ GenericArgCountMismatch, OverlappingAsssocItemConstraints, PredicateFilter, RegionInferReason,
+};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Lower a trait object type from the HIR to our internal notion of a type.
@@ -60,6 +62,7 @@ pub(super) fn lower_trait_object_ty(
dummy_self,
&mut user_written_bounds,
PredicateFilter::SelfOnly,
+ OverlappingAsssocItemConstraints::Forbidden,
);
if let Err(GenericArgCountMismatch { invalid_args, .. }) = result.correct {
potential_assoc_types.extend(invalid_args);
@@ -157,10 +160,7 @@ pub(super) fn lower_trait_object_ty(
self.dcx()
.struct_span_err(
span,
- format!(
- "conflicting associated type bounds for `{item}` when \
- expanding trait alias"
- ),
+ format!("conflicting associated type bounds for `{item}`"),
)
.with_span_label(
old_proj_span,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 9b198d0..eb66080 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -332,6 +332,15 @@ pub(crate) enum GenericArgPosition {
MethodCall,
}
+/// Whether to allow duplicate associated iten constraints in a trait ref, e.g.
+/// `Trait<Assoc = Ty, Assoc = Ty>`. This is forbidden in `dyn Trait<...>`
+/// but allowed everywhere else.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub(crate) enum OverlappingAsssocItemConstraints {
+ Allowed,
+ Forbidden,
+}
+
/// A marker denoting that the generic arguments that were
/// provided did not match the respective generic parameters.
#[derive(Clone, Debug)]
@@ -752,6 +761,7 @@ pub(crate) fn lower_poly_trait_ref(
self_ty: Ty<'tcx>,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
predicate_filter: PredicateFilter,
+ overlapping_assoc_item_constraints: OverlappingAsssocItemConstraints,
) -> GenericArgCountResult {
let tcx = self.tcx();
@@ -908,7 +918,10 @@ pub(crate) fn lower_poly_trait_ref(
}
}
- let mut dup_constraints = FxIndexMap::default();
+ let mut dup_constraints = (overlapping_assoc_item_constraints
+ == OverlappingAsssocItemConstraints::Forbidden)
+ .then_some(FxIndexMap::default());
+
for constraint in trait_segment.args().constraints {
// Don't register any associated item constraints for negative bounds,
// since we should have emitted an error for them earlier, and they
@@ -927,7 +940,7 @@ pub(crate) fn lower_poly_trait_ref(
poly_trait_ref,
constraint,
bounds,
- &mut dup_constraints,
+ dup_constraints.as_mut(),
constraint.span,
predicate_filter,
);
@@ -2484,6 +2497,7 @@ pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
&mut bounds,
ty::List::empty(),
PredicateFilter::All,
+ OverlappingAsssocItemConstraints::Allowed,
);
self.add_sizedness_bounds(
&mut bounds,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 833ce43..35253e4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -611,19 +611,13 @@ pub(crate) fn resolve_rvalue_scopes(&self, def_id: DefId) {
typeck_results.rvalue_scopes = rvalue_scopes;
}
- /// Unify the inference variables corresponding to coroutine witnesses, and save all the
- /// predicates that were stalled on those inference variables.
- ///
- /// This process allows to conservatively save all predicates that do depend on the coroutine
- /// interior types, for later processing by `check_coroutine_obligations`.
- ///
- /// We must not attempt to select obligations after this method has run, or risk query cycle
- /// ICE.
+ /// Drain all obligations that are stalled on coroutines defined in this body.
#[instrument(level = "debug", skip(self))]
- pub(crate) fn resolve_coroutine_interiors(&self) {
- // Try selecting all obligations that are not blocked on inference variables.
- // Once we start unifying coroutine witnesses, trying to select obligations on them will
- // trigger query cycle ICEs, as doing so requires MIR.
+ pub(crate) fn drain_stalled_coroutine_obligations(&self) {
+ // Make as much inference progress as possible before
+ // draining the stalled coroutine obligations as this may
+ // change obligations from being stalled on infer vars to
+ // being stalled on a coroutine.
self.select_obligations_where_possible(|_| {});
let ty::TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index acc0481..9f5a85b 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -243,18 +243,15 @@ fn typeck_with_inspect<'tcx>(
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
- // This must be the last thing before `report_ambiguity_errors`.
- fcx.resolve_coroutine_interiors();
-
- debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
-
// We need to handle opaque types before emitting ambiguity errors as applying
// defining uses may guide type inference.
if fcx.next_trait_solver() {
fcx.handle_opaque_type_uses_next();
}
- fcx.select_obligations_where_possible(|_| {});
+ // This must be the last thing before `report_ambiguity_errors` below except `select_obligations_where_possible`.
+ // So don't put anything after this.
+ fcx.drain_stalled_coroutine_obligations();
if fcx.infcx.tainted_by_errors().is_none() {
fcx.report_ambiguity_errors();
}
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index b989d41..a640dcb 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -170,6 +170,10 @@ pub fn take_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'
std::mem::take(&mut self.inner.borrow_mut().region_obligations)
}
+ pub fn clone_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'tcx>> {
+ self.inner.borrow().region_obligations.clone()
+ }
+
pub fn register_region_assumption(&self, assumption: ty::ArgOutlivesPredicate<'tcx>) {
let mut inner = self.inner.borrow_mut();
inner.undo_log.push(UndoLog::PushRegionAssumption);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 58ec72b..be2fd07 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -1,3 +1,4 @@
+use std::any::Any;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
@@ -6,13 +7,20 @@
use rustc_ast as ast;
use rustc_attr_parsing::{ShouldEmit, validate_attr};
+use rustc_codegen_ssa::back::archive::ArArchiveBuilderBuilder;
+use rustc_codegen_ssa::back::link::link_binary;
use rustc_codegen_ssa::traits::CodegenBackend;
+use rustc_codegen_ssa::{CodegenResults, CrateInfo};
+use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::jobserver::Proxy;
use rustc_data_structures::sync;
use rustc_errors::LintBuffer;
-use rustc_metadata::{DylibError, load_symbol_from_dylib};
-use rustc_middle::ty::CurrentGcx;
-use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
+use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib};
+use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::ty::{CurrentGcx, TyCtxt};
+use rustc_session::config::{
+ Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple,
+};
use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
use rustc_session::{EarlyDiagCtxt, Session, filesearch, lint};
use rustc_span::edit_distance::find_best_match_for_name;
@@ -316,12 +324,13 @@ pub fn get_codegen_backend(
let backend = backend_name
.or(target.default_codegen_backend.as_deref())
.or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND"))
- .unwrap_or("llvm");
+ .unwrap_or("dummy");
match backend {
filename if filename.contains('.') => {
load_backend_from_dylib(early_dcx, filename.as_ref())
}
+ "dummy" => || Box::new(DummyCodegenBackend),
#[cfg(feature = "llvm")]
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
@@ -334,6 +343,63 @@ pub fn get_codegen_backend(
unsafe { load() }
}
+struct DummyCodegenBackend;
+
+impl CodegenBackend for DummyCodegenBackend {
+ fn locale_resource(&self) -> &'static str {
+ ""
+ }
+
+ fn name(&self) -> &'static str {
+ "dummy"
+ }
+
+ fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
+ Box::new(CodegenResults {
+ modules: vec![],
+ allocator_module: None,
+ crate_info: CrateInfo::new(tcx, String::new()),
+ })
+ }
+
+ fn join_codegen(
+ &self,
+ ongoing_codegen: Box<dyn Any>,
+ _sess: &Session,
+ _outputs: &OutputFilenames,
+ ) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
+ (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default())
+ }
+
+ fn link(
+ &self,
+ sess: &Session,
+ codegen_results: CodegenResults,
+ metadata: EncodedMetadata,
+ outputs: &OutputFilenames,
+ ) {
+ // JUSTIFICATION: TyCtxt no longer available here
+ #[allow(rustc::bad_opt_access)]
+ if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) {
+ #[allow(rustc::untranslatable_diagnostic)]
+ #[allow(rustc::diagnostic_outside_of_impl)]
+ sess.dcx().fatal(format!(
+ "crate type {} not supported by the dummy codegen backend",
+ sess.opts.crate_types[0],
+ ));
+ }
+
+ link_binary(
+ sess,
+ &ArArchiveBuilderBuilder,
+ codegen_results,
+ metadata,
+ outputs,
+ self.name(),
+ );
+ }
+}
+
// This is used for rustdoc, but it uses similar machinery to codegen backend
// loading, so we leave the code here. It is potentially useful for other tools
// that want to invoke the rustc binary while linking to rustc as well.
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 4a77812..2b83ea2 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1824,3 +1824,55 @@
return 6; // Default fallback depth
}
#endif
+
+// Statically assert that the fixed metadata kind IDs declared in
+// `metadata_kind.rs` match the ones actually used by LLVM.
+#define FIXED_MD_KIND(VARIANT, VALUE) \
+ static_assert(::llvm::LLVMContext::VARIANT == VALUE);
+// Must be kept in sync with the corresponding list in `metadata_kind.rs`.
+FIXED_MD_KIND(MD_dbg, 0)
+FIXED_MD_KIND(MD_tbaa, 1)
+FIXED_MD_KIND(MD_prof, 2)
+FIXED_MD_KIND(MD_fpmath, 3)
+FIXED_MD_KIND(MD_range, 4)
+FIXED_MD_KIND(MD_tbaa_struct, 5)
+FIXED_MD_KIND(MD_invariant_load, 6)
+FIXED_MD_KIND(MD_alias_scope, 7)
+FIXED_MD_KIND(MD_noalias, 8)
+FIXED_MD_KIND(MD_nontemporal, 9)
+FIXED_MD_KIND(MD_mem_parallel_loop_access, 10)
+FIXED_MD_KIND(MD_nonnull, 11)
+FIXED_MD_KIND(MD_dereferenceable, 12)
+FIXED_MD_KIND(MD_dereferenceable_or_null, 13)
+FIXED_MD_KIND(MD_make_implicit, 14)
+FIXED_MD_KIND(MD_unpredictable, 15)
+FIXED_MD_KIND(MD_invariant_group, 16)
+FIXED_MD_KIND(MD_align, 17)
+FIXED_MD_KIND(MD_loop, 18)
+FIXED_MD_KIND(MD_type, 19)
+FIXED_MD_KIND(MD_section_prefix, 20)
+FIXED_MD_KIND(MD_absolute_symbol, 21)
+FIXED_MD_KIND(MD_associated, 22)
+FIXED_MD_KIND(MD_callees, 23)
+FIXED_MD_KIND(MD_irr_loop, 24)
+FIXED_MD_KIND(MD_access_group, 25)
+FIXED_MD_KIND(MD_callback, 26)
+FIXED_MD_KIND(MD_preserve_access_index, 27)
+FIXED_MD_KIND(MD_vcall_visibility, 28)
+FIXED_MD_KIND(MD_noundef, 29)
+FIXED_MD_KIND(MD_annotation, 30)
+FIXED_MD_KIND(MD_nosanitize, 31)
+FIXED_MD_KIND(MD_func_sanitize, 32)
+FIXED_MD_KIND(MD_exclude, 33)
+FIXED_MD_KIND(MD_memprof, 34)
+FIXED_MD_KIND(MD_callsite, 35)
+FIXED_MD_KIND(MD_kcfi_type, 36)
+FIXED_MD_KIND(MD_pcsections, 37)
+FIXED_MD_KIND(MD_DIAssignID, 38)
+FIXED_MD_KIND(MD_coro_outside_frame, 39)
+FIXED_MD_KIND(MD_mmra, 40)
+FIXED_MD_KIND(MD_noalias_addrspace, 41)
+// If some fixed metadata kinds are not present and consistent in all supported
+// LLVM versions, it's fine to omit them from this list; in that case Rust-side
+// code cannot declare them as fixed IDs and must look them up by name instead.
+#undef FIXED_MD_KIND
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index ecc7426..39e604b 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -158,12 +158,22 @@ pub(crate) fn base(
SplitDebuginfo::Off,
]),
+ // Tell the linker that we would like it to avoid irreproducible binaries.
+ //
// This environment variable is pretty magical but is intended for
// producing deterministic builds. This was first discovered to be used
// by the `ar` tool as a way to control whether or not mtime entries in
- // the archive headers were set to zero or not. It appears that
- // eventually the linker got updated to do the same thing and now reads
- // this environment variable too in recent versions.
+ // the archive headers were set to zero or not.
+ //
+ // In `ld64-351.8`, shipped with Xcode 9.3, the linker was updated to
+ // read this flag too. Linker versions that don't support this flag
+ // may embed modification timestamps in binaries (especially in debug
+ // information).
+ //
+ // A cleaner alternative would be to pass the `-reproducible` flag,
+ // though that is only supported since `ld64-819.6` shipped with Xcode
+ // 14, which is too new for our minimum supported version:
+ // https://doc.rust-lang.org/rustc/platform-support/apple-darwin.html#host-tooling
//
// For some more info see the commentary on #47086
link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index d485eb7..bec1275 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1897,6 +1897,7 @@ pub(super) fn report_similar_impl_candidates(
other: bool,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
+ let parent_map = self.tcx.visible_parent_map(());
let alternative_candidates = |def_id: DefId| {
let mut impl_candidates: Vec<_> = self
.tcx
@@ -1921,7 +1922,21 @@ pub(super) fn report_similar_impl_candidates(
// FIXME(compiler-errors): This could be generalized, both to
// be more granular, and probably look past other `#[fundamental]`
// types, too.
- self.tcx.visibility(def.did()).is_accessible_from(body_def_id, self.tcx)
+ let mut did = def.did();
+ if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) {
+ // don't suggest foreign `#[doc(hidden)]` types
+ if !did.is_local() {
+ while let Some(parent) = parent_map.get(&did) {
+ if self.tcx.is_doc_hidden(did) {
+ return false;
+ }
+ did = *parent;
+ }
+ }
+ true
+ } else {
+ false
+ }
} else {
true
}
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index 7540cbe..e55ffb4 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -55,6 +55,12 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
span: Span,
disable_implied_bounds_hack: bool,
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
+ // Inside mir borrowck, each computation starts with an empty list.
+ assert!(
+ ocx.infcx.inner.borrow().region_obligations().is_empty(),
+ "compute_implied_outlives_bounds assumes region obligations are empty before starting"
+ );
+
let normalize_ty = |ty| -> Result<_, NoSolution> {
// We must normalize the type so we can compute the right outlives components.
// for example, if we have some constrained param type like `T: Trait<Out = U>`,
@@ -143,7 +149,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
&& ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break()
{
for TypeOutlivesConstraint { sup_type, sub_region, .. } in
- ocx.infcx.take_registered_region_obligations()
+ ocx.infcx.clone_registered_region_obligations()
{
let mut components = smallvec![];
push_outlives_components(ocx.infcx.tcx, sup_type, &mut components);
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 627e5c7..023238a 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -277,7 +277,9 @@
// This is repr(C) to future-proof against possible field-reordering, which
// would interfere with otherwise safe [into|from]_raw() of transmutable
// inner types.
-#[repr(C)]
+// repr(align(2)) (forcing alignment to at least 2) is required because usize
+// has 1-byte alignment on AVR.
+#[repr(C, align(2))]
struct RcInner<T: ?Sized> {
strong: Cell<usize>,
weak: Cell<usize>,
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 3a8695d..6432bdf 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -341,7 +341,7 @@ pub struct Weak<
// but it is not necessarily a valid pointer.
// `Weak::new` sets this to `usize::MAX` so that it doesn’t need
// to allocate space on the heap. That's not a value a real pointer
- // will ever have because RcInner has alignment at least 2.
+ // will ever have because ArcInner has alignment at least 2.
ptr: NonNull<ArcInner<T>>,
alloc: A,
}
@@ -366,7 +366,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// This is repr(C) to future-proof against possible field-reordering, which
// would interfere with otherwise safe [into|from]_raw() of transmutable
// inner types.
-#[repr(C)]
+// Unlike RcInner, repr(align(2)) is not strictly required because atomic types
+// have the alignment same as its size, but we use it for consistency and clarity.
+#[repr(C, align(2))]
struct ArcInner<T: ?Sized> {
strong: Atomic<usize>,
@@ -1613,9 +1615,9 @@ pub fn into_raw_with_allocator(this: Self) -> (*const T, A) {
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
- // SAFETY: This cannot go through Deref::deref or RcInnerPtr::inner because
+ // SAFETY: This cannot go through Deref::deref or ArcInnerPtr::inner because
// this is required to retain raw/mut provenance such that e.g. `get_mut` can
- // write through the pointer after the Rc is recovered through `from_raw`.
+ // write through the pointer after the Arc is recovered through `from_raw`.
unsafe { &raw mut (*ptr).data }
}
@@ -2450,7 +2452,7 @@ pub fn get_mut(this: &mut Self) -> Option<&mut T> {
/// If any other `Arc` or [`Weak`] pointers to the same allocation exist, then
/// they must not be dereferenced or have active borrows for the duration
/// of the returned borrow, and their inner type must be exactly the same as the
- /// inner type of this Rc (including lifetimes). This is trivially the case if no
+ /// inner type of this Arc (including lifetimes). This is trivially the case if no
/// such pointers exist, for example immediately after `Arc::new`.
///
/// # Examples
@@ -3022,7 +3024,7 @@ pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self {
// Otherwise, we're guaranteed the pointer came from a nondangling Weak.
// SAFETY: data_offset is safe to call, as ptr references a real (potentially dropped) T.
let offset = unsafe { data_offset(ptr) };
- // Thus, we reverse the offset to get the whole RcInner.
+ // Thus, we reverse the offset to get the whole ArcInner.
// SAFETY: the pointer originated from a Weak, so this offset is safe.
unsafe { ptr.byte_sub(offset) as *mut ArcInner<T> }
};
@@ -4015,7 +4017,7 @@ impl<T: ?Sized, A: Allocator> Unpin for Arc<T, A> {}
/// valid instance of T, but the T is allowed to be dropped.
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> usize {
// Align the unsized value to the end of the ArcInner.
- // Because RcInner is repr(C), it will always be the last field in memory.
+ // Because ArcInner is repr(C), it will always be the last field in memory.
// SAFETY: since the only unsized types possible are slices, trait objects,
// and extern types, the input safety requirement is currently enough to
// satisfy the requirements of align_of_val_raw; this is an implementation
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index ae910e0..7053ae8 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -2203,16 +2203,13 @@ unsafe impl<T> Sync for ChunksExactMut<'_, T> where T: Sync {}
#[unstable(feature = "array_windows", issue = "75027")]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ArrayWindows<'a, T: 'a, const N: usize> {
- slice_head: *const T,
- num: usize,
- marker: PhantomData<&'a [T; N]>,
+ v: &'a [T],
}
impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> {
#[inline]
pub(super) const fn new(slice: &'a [T]) -> Self {
- let num_windows = slice.len().saturating_sub(N - 1);
- Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
+ Self { v: slice }
}
}
@@ -2222,49 +2219,34 @@ impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
#[inline]
fn next(&mut self) -> Option<Self::Item> {
- if self.num == 0 {
- return None;
+ let ret = self.v.first_chunk();
+ if ret.is_some() {
+ self.v = &self.v[1..];
}
- // SAFETY:
- // This is safe because it's indexing into a slice guaranteed to be length > N.
- let ret = unsafe { &*self.slice_head.cast::<[T; N]>() };
- // SAFETY: Guaranteed that there are at least 1 item remaining otherwise
- // earlier branch would've been hit
- self.slice_head = unsafe { self.slice_head.add(1) };
-
- self.num -= 1;
- Some(ret)
+ ret
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
- (self.num, Some(self.num))
+ let size = self.v.len().saturating_sub(N - 1);
+ (size, Some(size))
}
#[inline]
fn count(self) -> usize {
- self.num
+ self.len()
}
#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
- if self.num <= n {
- self.num = 0;
- return None;
- }
- // SAFETY:
- // This is safe because it's indexing into a slice guaranteed to be length > N.
- let ret = unsafe { &*self.slice_head.add(n).cast::<[T; N]>() };
- // SAFETY: Guaranteed that there are at least n items remaining
- self.slice_head = unsafe { self.slice_head.add(n + 1) };
-
- self.num -= n + 1;
- Some(ret)
+ let idx = n.min(self.v.len());
+ self.v = &self.v[idx..];
+ self.next()
}
#[inline]
- fn last(mut self) -> Option<Self::Item> {
- self.nth(self.num.checked_sub(1)?)
+ fn last(self) -> Option<Self::Item> {
+ self.v.last_chunk()
}
}
@@ -2272,32 +2254,25 @@ fn last(mut self) -> Option<Self::Item> {
impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T; N]> {
- if self.num == 0 {
- return None;
+ let ret = self.v.last_chunk();
+ if ret.is_some() {
+ self.v = &self.v[..self.v.len() - 1];
}
- // SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
- let ret = unsafe { &*self.slice_head.add(self.num - 1).cast::<[T; N]>() };
- self.num -= 1;
- Some(ret)
+ ret
}
#[inline]
fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
- if self.num <= n {
- self.num = 0;
- return None;
- }
- // SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
- let ret = unsafe { &*self.slice_head.add(self.num - (n + 1)).cast::<[T; N]>() };
- self.num -= n + 1;
- Some(ret)
+ let idx = self.v.len().saturating_sub(n);
+ self.v = &self.v[..idx];
+ self.next_back()
}
}
#[unstable(feature = "array_windows", issue = "75027")]
impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
fn is_empty(&self) -> bool {
- self.num == 0
+ self.v.len() < N
}
}
diff --git a/library/coretests/tests/iter/sources.rs b/library/coretests/tests/iter/sources.rs
index 506feba..5a391cb 100644
--- a/library/coretests/tests/iter/sources.rs
+++ b/library/coretests/tests/iter/sources.rs
@@ -31,6 +31,17 @@ fn test_repeat_take_collect() {
}
#[test]
+#[should_panic = "iterator is infinite"]
+fn test_repeat_count() {
+ repeat(42).count();
+}
+
+#[test]
+fn test_repeat_last() {
+ assert_eq!(repeat(42).last(), Some(42));
+}
+
+#[test]
fn test_repeat_with() {
#[derive(PartialEq, Debug)]
struct NotClone(usize);
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index e7d5479..92558f2 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -26,18 +26,16 @@ pub(super) struct HandleCounters {
$(
pub(crate) struct $oty {
handle: handle::Handle,
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
- // way of doing this, but that requires unstable features.
- // rust-analyzer uses this code and avoids unstable features.
- _marker: PhantomData<*mut ()>,
}
+ impl !Send for $oty {}
+ impl !Sync for $oty {}
+
// Forward `Drop::drop` to the inherent `drop` method.
impl Drop for $oty {
fn drop(&mut self) {
$oty {
handle: self.handle,
- _marker: PhantomData,
}.drop();
}
}
@@ -64,7 +62,6 @@ impl<S> DecodeMut<'_, '_, S> for $oty {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
$oty {
handle: handle::Handle::decode(r, s),
- _marker: PhantomData,
}
}
}
@@ -74,12 +71,11 @@ fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) struct $ity {
handle: handle::Handle,
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
- // way of doing this, but that requires unstable features.
- // rust-analyzer uses this code and avoids unstable features.
- _marker: PhantomData<*mut ()>,
}
+ impl !Send for $ity {}
+ impl !Sync for $ity {}
+
impl<S> Encode<S> for $ity {
fn encode(self, w: &mut Writer, s: &mut S) {
self.handle.encode(w, s);
@@ -90,7 +86,6 @@ impl<S> DecodeMut<'_, '_, S> for $ity {
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
$ity {
handle: handle::Handle::decode(r, s),
- _marker: PhantomData,
}
}
}
@@ -144,7 +139,7 @@ macro_rules! define_client_side {
buf.clear();
api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ());
- reverse_encode!(buf; $($arg),*);
+ $($arg.encode(&mut buf, &mut ());)*
buf = bridge.dispatch.call(buf);
diff --git a/library/proc_macro/src/bridge/closure.rs b/library/proc_macro/src/bridge/closure.rs
index e0e6884..e513390 100644
--- a/library/proc_macro/src/bridge/closure.rs
+++ b/library/proc_macro/src/bridge/closure.rs
@@ -6,9 +6,7 @@
pub(super) struct Closure<'a, A, R> {
call: unsafe extern "C" fn(*mut Env, A) -> R,
env: *mut Env,
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
- // this, but that requires unstable features. rust-analyzer uses this code
- // and avoids unstable features.
+ // Prevent Send and Sync impls.
//
// The `'a` lifetime parameter represents the lifetime of `Env`.
_marker: PhantomData<*mut &'a mut ()>,
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index d60a76f..1b09deb 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -119,26 +119,6 @@ macro_rules! with_api_handle_types {
};
}
-// FIXME(eddyb) this calls `encode` for each argument, but in reverse,
-// to match the ordering in `reverse_decode`.
-macro_rules! reverse_encode {
- ($writer:ident;) => {};
- ($writer:ident; $first:ident $(, $rest:ident)*) => {
- reverse_encode!($writer; $($rest),*);
- $first.encode(&mut $writer, &mut ());
- }
-}
-
-// FIXME(eddyb) this calls `decode` for each argument, but in reverse,
-// to avoid borrow conflicts from borrows started by `&mut` arguments.
-macro_rules! reverse_decode {
- ($reader:ident, $s:ident;) => {};
- ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
- reverse_decode!($reader, $s; $($rest: $rest_ty),*);
- let $first = <$first_ty>::decode(&mut $reader, $s);
- }
-}
-
#[allow(unsafe_code)]
mod arena;
#[allow(unsafe_code)]
@@ -180,13 +160,11 @@ pub struct BridgeConfig<'a> {
/// If 'true', always invoke the default panic hook
force_show_panics: bool,
-
- // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
- // this, but that requires unstable features. rust-analyzer uses this code
- // and avoids unstable features.
- _marker: marker::PhantomData<*mut ()>,
}
+impl !Send for BridgeConfig<'_> {}
+impl !Sync for BridgeConfig<'_> {}
+
#[forbid(unsafe_code)]
#[allow(non_camel_case_types)]
mod api_tags {
diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs
index 5beda7c..0bb3069 100644
--- a/library/proc_macro/src/bridge/server.rs
+++ b/library/proc_macro/src/bridge/server.rs
@@ -178,7 +178,7 @@ fn dispatch(&mut self, mut buf: Buffer) -> Buffer {
$(api_tags::Method::$name(m) => match m {
$(api_tags::$name::$method => {
let mut call_method = || {
- reverse_decode!(reader, handle_store; $($arg: $arg_ty),*);
+ $(let $arg = <$arg_ty>::decode(&mut reader, handle_store);)*
$name::$method(server, $($arg),*)
};
// HACK(eddyb) don't use `panic::catch_unwind` in a panic.
@@ -295,12 +295,7 @@ fn run_bridge_and_client(
let mut dispatch = |buf| dispatcher.dispatch(buf);
- run_client(BridgeConfig {
- input,
- dispatch: (&mut dispatch).into(),
- force_show_panics,
- _marker: marker::PhantomData,
- })
+ run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
}
}
@@ -331,12 +326,7 @@ fn run_bridge_and_client(
client.recv().expect("server died while client waiting for reply")
};
- run_client(BridgeConfig {
- input,
- dispatch: (&mut dispatch).into(),
- force_show_panics,
- _marker: marker::PhantomData,
- })
+ run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics })
});
while let Some(b) = server.recv() {
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 162b4fd..613abd7 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -27,7 +27,6 @@
#![feature(panic_can_unwind)]
#![feature(restricted_std)]
#![feature(rustc_attrs)]
-#![feature(stmt_expr_attributes)]
#![feature(extend_one)]
#![recursion_limit = "256"]
#![allow(internal_features)]
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 718c7c2..6e3b1e6 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1412,6 +1412,99 @@ pub fn pop(&mut self) -> bool {
}
}
+ /// Sets whether the path has a trailing [separator](MAIN_SEPARATOR).
+ ///
+ /// The value returned by [`has_trailing_sep`](Path::has_trailing_sep) will be equivalent to
+ /// the provided value if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(path_trailing_sep)]
+ /// use std::path::PathBuf;
+ ///
+ /// let mut p = PathBuf::from("dir");
+ ///
+ /// assert!(!p.has_trailing_sep());
+ /// p.set_trailing_sep(false);
+ /// assert!(!p.has_trailing_sep());
+ /// p.set_trailing_sep(true);
+ /// assert!(p.has_trailing_sep());
+ /// p.set_trailing_sep(false);
+ /// assert!(!p.has_trailing_sep());
+ ///
+ /// p = PathBuf::from("/");
+ /// assert!(p.has_trailing_sep());
+ /// p.set_trailing_sep(false);
+ /// assert!(p.has_trailing_sep());
+ /// ```
+ #[unstable(feature = "path_trailing_sep", issue = "142503")]
+ pub fn set_trailing_sep(&mut self, trailing_sep: bool) {
+ if trailing_sep { self.push_trailing_sep() } else { self.pop_trailing_sep() }
+ }
+
+ /// Adds a trailing [separator](MAIN_SEPARATOR) to the path.
+ ///
+ /// This acts similarly to [`Path::with_trailing_sep`], but mutates the underlying `PathBuf`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(path_trailing_sep)]
+ /// use std::ffi::OsStr;
+ /// use std::path::PathBuf;
+ ///
+ /// let mut p = PathBuf::from("dir");
+ ///
+ /// assert!(!p.has_trailing_sep());
+ /// p.push_trailing_sep();
+ /// assert!(p.has_trailing_sep());
+ /// p.push_trailing_sep();
+ /// assert!(p.has_trailing_sep());
+ ///
+ /// p = PathBuf::from("dir/");
+ /// p.push_trailing_sep();
+ /// assert_eq!(p.as_os_str(), OsStr::new("dir/"));
+ /// ```
+ #[unstable(feature = "path_trailing_sep", issue = "142503")]
+ pub fn push_trailing_sep(&mut self) {
+ if !self.has_trailing_sep() {
+ self.push("");
+ }
+ }
+
+ /// Removes a trailing [separator](MAIN_SEPARATOR) from the path, if possible.
+ ///
+ /// This acts similarly to [`Path::trim_trailing_sep`], but mutates the underlying `PathBuf`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(path_trailing_sep)]
+ /// use std::ffi::OsStr;
+ /// use std::path::PathBuf;
+ ///
+ /// let mut p = PathBuf::from("dir//");
+ ///
+ /// assert!(p.has_trailing_sep());
+ /// assert_eq!(p.as_os_str(), OsStr::new("dir//"));
+ /// p.pop_trailing_sep();
+ /// assert!(!p.has_trailing_sep());
+ /// assert_eq!(p.as_os_str(), OsStr::new("dir"));
+ /// p.pop_trailing_sep();
+ /// assert!(!p.has_trailing_sep());
+ /// assert_eq!(p.as_os_str(), OsStr::new("dir"));
+ ///
+ /// p = PathBuf::from("/");
+ /// assert!(p.has_trailing_sep());
+ /// p.pop_trailing_sep();
+ /// assert!(p.has_trailing_sep());
+ /// ```
+ #[unstable(feature = "path_trailing_sep", issue = "142503")]
+ pub fn pop_trailing_sep(&mut self) {
+ self.inner.truncate(self.trim_trailing_sep().as_os_str().len());
+ }
+
/// Updates [`self.file_name`] to `file_name`.
///
/// If [`self.file_name`] was [`None`], this is equivalent to pushing
@@ -1610,7 +1703,7 @@ fn _add_extension(&mut self, extension: &OsStr) -> bool {
let new = extension.as_encoded_bytes();
if !new.is_empty() {
// truncate until right after the file name
- // this is necessary for trimming the trailing slash
+ // this is necessary for trimming the trailing separator
let end_file_name = file_name[file_name.len()..].as_ptr().addr();
let start = self.inner.as_encoded_bytes().as_ptr().addr();
self.inner.truncate(end_file_name.wrapping_sub(start));
@@ -2755,6 +2848,94 @@ pub fn extension(&self) -> Option<&OsStr> {
self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.and(after))
}
+ /// Checks whether the path ends in a trailing [separator](MAIN_SEPARATOR).
+ ///
+ /// This is generally done to ensure that a path is treated as a directory, not a file,
+ /// although it does not actually guarantee that such a path is a directory on the underlying
+ /// file system.
+ ///
+ /// Despite this behavior, two paths are still considered the same in Rust whether they have a
+ /// trailing separator or not.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(path_trailing_sep)]
+ /// use std::path::Path;
+ ///
+ /// assert!(Path::new("dir/").has_trailing_sep());
+ /// assert!(!Path::new("file.rs").has_trailing_sep());
+ /// ```
+ #[unstable(feature = "path_trailing_sep", issue = "142503")]
+ #[must_use]
+ #[inline]
+ pub fn has_trailing_sep(&self) -> bool {
+ self.as_os_str().as_encoded_bytes().last().copied().is_some_and(is_sep_byte)
+ }
+
+ /// Ensures that a path has a trailing [separator](MAIN_SEPARATOR),
+ /// allocating a [`PathBuf`] if necessary.
+ ///
+ /// The resulting path will return true for [`has_trailing_sep`](Self::has_trailing_sep).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(path_trailing_sep)]
+ /// use std::ffi::OsStr;
+ /// use std::path::Path;
+ ///
+ /// assert_eq!(Path::new("dir//").with_trailing_sep().as_os_str(), OsStr::new("dir//"));
+ /// assert_eq!(Path::new("dir/").with_trailing_sep().as_os_str(), OsStr::new("dir/"));
+ /// assert!(!Path::new("dir").has_trailing_sep());
+ /// assert!(Path::new("dir").with_trailing_sep().has_trailing_sep());
+ /// ```
+ #[unstable(feature = "path_trailing_sep", issue = "142503")]
+ #[must_use]
+ #[inline]
+ pub fn with_trailing_sep(&self) -> Cow<'_, Path> {
+ if self.has_trailing_sep() { Cow::Borrowed(self) } else { Cow::Owned(self.join("")) }
+ }
+
+ /// Trims a trailing [separator](MAIN_SEPARATOR) from a path, if possible.
+ ///
+ /// The resulting path will return false for [`has_trailing_sep`](Self::has_trailing_sep) for
+ /// most paths.
+ ///
+ /// Some paths, like `/`, cannot be trimmed in this way.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(path_trailing_sep)]
+ /// use std::ffi::OsStr;
+ /// use std::path::Path;
+ ///
+ /// assert_eq!(Path::new("dir//").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
+ /// assert_eq!(Path::new("dir/").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
+ /// assert_eq!(Path::new("dir").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
+ /// assert_eq!(Path::new("/").trim_trailing_sep().as_os_str(), OsStr::new("/"));
+ /// assert_eq!(Path::new("//").trim_trailing_sep().as_os_str(), OsStr::new("//"));
+ /// ```
+ #[unstable(feature = "path_trailing_sep", issue = "142503")]
+ #[must_use]
+ #[inline]
+ pub fn trim_trailing_sep(&self) -> &Path {
+ if self.has_trailing_sep() && (!self.has_root() || self.parent().is_some()) {
+ let mut bytes = self.inner.as_encoded_bytes();
+ while let Some((last, init)) = bytes.split_last()
+ && is_sep_byte(*last)
+ {
+ bytes = init;
+ }
+
+ // SAFETY: Trimming trailing ASCII bytes will retain the validity of the string.
+ Path::new(unsafe { OsStr::from_encoded_bytes_unchecked(bytes) })
+ } else {
+ self
+ }
+ }
+
/// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
///
/// If `path` is absolute, it replaces the current path.
@@ -2907,7 +3088,7 @@ pub fn with_added_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
/// `a/b` all have `a` and `b` as components, but `./a/b` starts with
/// an additional [`CurDir`] component.
///
- /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
+ /// * Trailing separators are normalized away, so `/a/b` and `/a/b/` are equivalent.
///
/// Note that no other normalization takes place; in particular, `a/c`
/// and `a/b/../c` are distinct, to account for the possibility that `b`
@@ -3718,7 +3899,7 @@ impl Error for NormalizeError {}
///
/// On POSIX platforms, the path is resolved using [POSIX semantics][posix-semantics],
/// except that it stops short of resolving symlinks. This means it will keep `..`
-/// components and trailing slashes.
+/// components and trailing separators.
///
/// On Windows, for verbatim paths, this will simply return the path as given. For other
/// paths, this is currently equivalent to calling
diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs
index 7da1621..f00212b 100644
--- a/library/std/src/thread/current.rs
+++ b/library/std/src/thread/current.rs
@@ -133,12 +133,32 @@ pub(super) fn set_current(thread: Thread) -> Result<(), Thread> {
Ok(())
}
-/// Gets the id of the thread that invokes it.
+/// Gets the unique identifier of the thread which invokes it.
+///
+/// Calling this function may be more efficient than accessing the current
+/// thread id through the current thread handle. i.e. `thread::current().id()`.
///
/// This function will always succeed, will always return the same value for
/// one thread and is guaranteed not to call the global allocator.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(current_thread_id)]
+///
+/// use std::thread;
+///
+/// let other_thread = thread::spawn(|| {
+/// thread::current_id()
+/// });
+///
+/// let other_thread_id = other_thread.join().unwrap();
+/// assert_ne!(thread::current_id(), other_thread_id);
+/// ```
#[inline]
-pub(crate) fn current_id() -> ThreadId {
+#[must_use]
+#[unstable(feature = "current_thread_id", issue = "147194")]
+pub fn current_id() -> ThreadId {
// If accessing the persistent thread ID takes multiple TLS accesses, try
// to retrieve it from the current thread handle, which will only take one
// TLS access.
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 4d09b2b..1768369 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -183,7 +183,9 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub use current::current;
-pub(crate) use current::{current_id, current_or_unnamed, current_os_id, drop_current};
+#[unstable(feature = "current_thread_id", issue = "147194")]
+pub use current::current_id;
+pub(crate) use current::{current_or_unnamed, current_os_id, drop_current};
use current::{set_current, try_with_current};
mod spawnhook;
diff --git a/library/std/tests/path.rs b/library/std/tests/path.rs
index 837a14b..c60edbd 100644
--- a/library/std/tests/path.rs
+++ b/library/std/tests/path.rs
@@ -1,4 +1,9 @@
-#![feature(clone_to_uninit, maybe_uninit_slice, normalize_lexically)]
+// tidy-alphabetical-start
+#![feature(clone_to_uninit)]
+#![feature(maybe_uninit_slice)]
+#![feature(normalize_lexically)]
+#![feature(path_trailing_sep)]
+// tidy-alphabetical-end
use std::clone::CloneToUninit;
use std::ffi::OsStr;
@@ -2542,3 +2547,34 @@ fn compare_path_like_to_str_like() {
assert!(path_buf == s);
assert!(s == path_buf);
}
+
+#[test]
+fn test_trim_trailing_sep() {
+ assert_eq!(Path::new("/").trim_trailing_sep().as_os_str(), OsStr::new("/"));
+ assert_eq!(Path::new("//").trim_trailing_sep().as_os_str(), OsStr::new("//"));
+ assert_eq!(Path::new("").trim_trailing_sep().as_os_str(), OsStr::new(""));
+ assert_eq!(Path::new(".").trim_trailing_sep().as_os_str(), OsStr::new("."));
+ assert_eq!(Path::new("./").trim_trailing_sep().as_os_str(), OsStr::new("."));
+ assert_eq!(Path::new(".//").trim_trailing_sep().as_os_str(), OsStr::new("."));
+ assert_eq!(Path::new("..").trim_trailing_sep().as_os_str(), OsStr::new(".."));
+ assert_eq!(Path::new("../").trim_trailing_sep().as_os_str(), OsStr::new(".."));
+ assert_eq!(Path::new("..//").trim_trailing_sep().as_os_str(), OsStr::new(".."));
+
+ #[cfg(any(windows, target_os = "cygwin"))]
+ {
+ assert_eq!(Path::new("\\").trim_trailing_sep().as_os_str(), OsStr::new("\\"));
+ assert_eq!(Path::new("\\\\").trim_trailing_sep().as_os_str(), OsStr::new("\\\\"));
+ assert_eq!(Path::new("c:/").trim_trailing_sep().as_os_str(), OsStr::new("c:/"));
+ assert_eq!(Path::new("c://").trim_trailing_sep().as_os_str(), OsStr::new("c://"));
+ assert_eq!(Path::new("c:./").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+ assert_eq!(Path::new("c:.//").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+ assert_eq!(Path::new("c:../").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+ assert_eq!(Path::new("c:..//").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+ assert_eq!(Path::new("c:\\").trim_trailing_sep().as_os_str(), OsStr::new("c:\\"));
+ assert_eq!(Path::new("c:\\\\").trim_trailing_sep().as_os_str(), OsStr::new("c:\\\\"));
+ assert_eq!(Path::new("c:.\\").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+ assert_eq!(Path::new("c:.\\\\").trim_trailing_sep().as_os_str(), OsStr::new("c:."));
+ assert_eq!(Path::new("c:..\\").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+ assert_eq!(Path::new("c:..\\\\").trim_trailing_sep().as_os_str(), OsStr::new("c:.."));
+ }
+}
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 7865b68..37462c6 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -1024,12 +1024,9 @@ fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Rustc::from_build_compiler(run.builder, compilers.build_compiler(), target));
compilers.build_compiler()
}
- Mode::ToolBootstrap => {
- // bootstrap/host tools should be documented with the stage 0 compiler
- prepare_doc_compiler(run.builder, run.builder.host_target, 1)
- }
Mode::ToolTarget => {
- // target tools should be documented with the in-tree compiler
+ // when shipping multiple docs together in one folder,
+ // they all need to use the same rustdoc version
prepare_doc_compiler(run.builder, run.builder.host_target, run.builder.top_stage)
}
_ => {
@@ -1132,7 +1129,11 @@ fn metadata(&self) -> Option<StepMetadata> {
tool_doc!(
BuildHelper,
"src/build_helper",
- mode = Mode::ToolBootstrap,
+ // ideally, this would use ToolBootstrap,
+ // but we distribute these docs together in the same folder
+ // as a bunch of stage1 tools, and you can't mix rustdoc versions
+ // because that breaks cross-crate data (particularly search)
+ mode = Mode::ToolTarget,
is_library = true,
crates = ["build_helper"]
);
@@ -1175,25 +1176,25 @@ fn metadata(&self) -> Option<StepMetadata> {
// "specialization" feature in its build script when it detects a nightly toolchain.
allow_features: "specialization"
);
-tool_doc!(Tidy, "src/tools/tidy", mode = Mode::ToolBootstrap, crates = ["tidy"]);
+tool_doc!(Tidy, "src/tools/tidy", mode = Mode::ToolTarget, crates = ["tidy"]);
tool_doc!(
Bootstrap,
"src/bootstrap",
- mode = Mode::ToolBootstrap,
+ mode = Mode::ToolTarget,
is_library = true,
crates = ["bootstrap"]
);
tool_doc!(
RunMakeSupport,
"src/tools/run-make-support",
- mode = Mode::ToolBootstrap,
+ mode = Mode::ToolTarget,
is_library = true,
crates = ["run_make_support"]
);
tool_doc!(
Compiletest,
"src/tools/compiletest",
- mode = Mode::ToolBootstrap,
+ mode = Mode::ToolTarget,
is_library = true,
crates = ["compiletest"]
);
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 88df469..3306435 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -1158,13 +1158,12 @@ fn dist_compiler_docs() {
[doc] embedded-book (book) <host>
[doc] edition-guide (book) <host>
[doc] style-guide (book) <host>
- [build] rustdoc 0 <host>
- [doc] rustc 0 <host> -> Tidy 1 <host>
- [doc] rustc 0 <host> -> Bootstrap 1 <host>
+ [doc] rustc 1 <host> -> Tidy 2 <host>
+ [doc] rustc 1 <host> -> Bootstrap 2 <host>
[doc] rustc 1 <host> -> releases 2 <host>
- [doc] rustc 0 <host> -> RunMakeSupport 1 <host>
- [doc] rustc 0 <host> -> BuildHelper 1 <host>
- [doc] rustc 0 <host> -> Compiletest 1 <host>
+ [doc] rustc 1 <host> -> RunMakeSupport 2 <host>
+ [doc] rustc 1 <host> -> BuildHelper 2 <host>
+ [doc] rustc 1 <host> -> Compiletest 2 <host>
[build] rustc 0 <host> -> RustInstaller 1 <host>
"
);
@@ -2686,8 +2685,11 @@ fn doc_compiletest_stage_2() {
.path("src/tools/compiletest")
.stage(2)
.render_steps(), @r"
- [build] rustdoc 0 <host>
- [doc] rustc 0 <host> -> Compiletest 1 <host>
+ [build] llvm <host>
+ [build] rustc 0 <host> -> rustc 1 <host>
+ [build] rustc 1 <host> -> std 1 <host>
+ [build] rustdoc 1 <host>
+ [doc] rustc 1 <host> -> Compiletest 2 <host>
");
}
diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py
index 65f18ba..3eb964d 100644
--- a/src/etc/lldb_providers.py
+++ b/src/etc/lldb_providers.py
@@ -761,7 +761,8 @@
def get_child_at_index(self, index: int) -> SBValue:
child: SBValue = self.valobj.GetChildAtIndex(index)
- return child.CreateChildAtOffset(str(index), 0, child.GetType())
+ offset = self.valobj.GetType().GetFieldAtIndex(index).byte_offset
+ return self.valobj.CreateChildAtOffset(str(index), offset, child.GetType())
def update(self):
pass
@@ -772,7 +773,7 @@
def get_type_name(self) -> str:
name = self.valobj.GetTypeName()
# remove "tuple$<" and ">", str.removeprefix and str.removesuffix require python 3.9+
- name = name[7:-1]
+ name = name[7:-1].strip()
return "(" + name + ")"
diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs
new file mode 100644
index 0000000..01cc05f
--- /dev/null
+++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs
@@ -0,0 +1,114 @@
+//@ edition: 2024
+
+#![feature(associated_const_equality, type_alias_impl_trait, return_type_notation)]
+#![allow(refining_impl_trait_internal)]
+
+use std::iter;
+
+fn rpit1() -> impl Iterator<Item: Copy, Item: Send> {
+ iter::empty()
+ //~^ ERROR type annotations needed
+}
+fn rpit2() -> impl Iterator<Item: Copy, Item: Copy> {
+ iter::empty()
+ //~^ ERROR type annotations needed
+}
+fn rpit3() -> impl Iterator<Item: 'static, Item: 'static> {
+ iter::empty()
+ //~^ ERROR type annotations needed
+}
+
+type Tait1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
+//~^ ERROR unconstrained opaque type
+type Tait2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
+//~^ ERROR unconstrained opaque type
+type Tait3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
+//~^ ERROR unconstrained opaque type
+
+type Tait4 = impl Iterator<Item: Copy, Item: Send>;
+//~^ ERROR unconstrained opaque type
+type Tait5 = impl Iterator<Item: Copy, Item: Copy>;
+//~^ ERROR unconstrained opaque type
+type Tait6 = impl Iterator<Item: 'static, Item: 'static>;
+//~^ ERROR unconstrained opaque type
+
+fn mismatch() -> impl Iterator<Item: Copy, Item: Send> {
+ //~^ ERROR [E0277]
+ iter::empty::<*const ()>()
+}
+
+fn mismatch_2() -> impl Iterator<Item: Copy, Item: Send> {
+ //~^ ERROR [E0277]
+ iter::empty::<String>()
+}
+
+trait Trait {
+ type Gat<T>;
+
+ const ASSOC: i32;
+
+ fn foo() -> impl Sized;
+}
+
+impl Trait for () {
+ type Gat<T> = ();
+
+ const ASSOC: i32 = 3;
+
+ fn foo() {}
+}
+
+impl Trait for u32 {
+ type Gat<T> = ();
+
+ const ASSOC: i32 = 4;
+
+ fn foo() -> u32 {
+ 42
+ }
+}
+
+fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+
+fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+
+fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+
+type MustFail = dyn Iterator<Item = i32, Item = u32>;
+//~^ ERROR [E0719]
+//~| ERROR conflicting associated type bounds
+
+trait Trait2 {
+ const ASSOC: u32;
+}
+
+type MustFail2 = dyn Trait2<ASSOC = 3u32, ASSOC = 4u32>;
+//~^ ERROR [E0719]
+//~| ERROR conflicting associated type bounds
+
+type MustFail3 = dyn Iterator<Item = i32, Item = i32>;
+//~^ ERROR [E0719]
+
+type MustFail4 = dyn Trait2<ASSOC = 3u32, ASSOC = 3u32>;
+//~^ ERROR [E0719]
+
+trait Trait3 {
+ fn foo() -> impl Iterator<Item = i32, Item = u32>;
+}
+
+impl Trait3 for () {
+ fn foo() -> impl Iterator<Item = i32, Item = u32> {
+ //~^ ERROR[E0271]
+ //~| ERROR[E0271]
+ [2u32].into_iter()
+ }
+}
+
+fn main() {
+ uncallable(iter::empty::<u32>()); //~ ERROR [E0271]
+ uncallable(iter::empty::<i32>()); //~ ERROR [E0271]
+ uncallable_const(()); //~ ERROR [E0271]
+ uncallable_const(4u32); //~ ERROR [E0271]
+ uncallable_rtn(()); //~ ERROR [E0271]
+ uncallable_rtn(17u32); //~ ERROR [E0271]
+}
diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr
new file mode 100644
index 0000000..1737d0d
--- /dev/null
+++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr
@@ -0,0 +1,268 @@
+error[E0282]: type annotations needed
+ --> $DIR/duplicate-bound-err.rs:9:5
+ |
+LL | iter::empty()
+ | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+ |
+help: consider specifying the generic argument
+ |
+LL | iter::empty::<T>()
+ | +++++
+
+error[E0282]: type annotations needed
+ --> $DIR/duplicate-bound-err.rs:13:5
+ |
+LL | iter::empty()
+ | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+ |
+help: consider specifying the generic argument
+ |
+LL | iter::empty::<T>()
+ | +++++
+
+error[E0282]: type annotations needed
+ --> $DIR/duplicate-bound-err.rs:17:5
+ |
+LL | iter::empty()
+ | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
+ |
+help: consider specifying the generic argument
+ |
+LL | iter::empty::<T>()
+ | +++++
+
+error: unconstrained opaque type
+ --> $DIR/duplicate-bound-err.rs:21:51
+ |
+LL | type Tait1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
+ | ^^^^^^^^^
+ |
+ = note: `Tait1` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+ --> $DIR/duplicate-bound-err.rs:23:51
+ |
+LL | type Tait2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
+ | ^^^^^^^^^
+ |
+ = note: `Tait2` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+ --> $DIR/duplicate-bound-err.rs:25:57
+ |
+LL | type Tait3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
+ | ^^^^^^^^^
+ |
+ = note: `Tait3` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+ --> $DIR/duplicate-bound-err.rs:28:14
+ |
+LL | type Tait4 = impl Iterator<Item: Copy, Item: Send>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Tait4` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+ --> $DIR/duplicate-bound-err.rs:30:14
+ |
+LL | type Tait5 = impl Iterator<Item: Copy, Item: Copy>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Tait5` must be used in combination with a concrete type within the same crate
+
+error: unconstrained opaque type
+ --> $DIR/duplicate-bound-err.rs:32:14
+ |
+LL | type Tait6 = impl Iterator<Item: 'static, Item: 'static>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `Tait6` must be used in combination with a concrete type within the same crate
+
+error[E0277]: `*const ()` cannot be sent between threads safely
+ --> $DIR/duplicate-bound-err.rs:35:18
+ |
+LL | fn mismatch() -> impl Iterator<Item: Copy, Item: Send> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely
+LL |
+LL | iter::empty::<*const ()>()
+ | -------------------------- return type was inferred to be `std::iter::Empty<*const ()>` here
+ |
+ = help: the trait `Send` is not implemented for `*const ()`
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+ --> $DIR/duplicate-bound-err.rs:40:20
+ |
+LL | fn mismatch_2() -> impl Iterator<Item: Copy, Item: Send> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+LL |
+LL | iter::empty::<String>()
+ | ----------------------- return type was inferred to be `std::iter::Empty<String>` here
+
+error[E0271]: expected `IntoIter<u32, 1>` to be an iterator that yields `i32`, but it yields `u32`
+ --> $DIR/duplicate-bound-err.rs:100:17
+ |
+LL | fn foo() -> impl Iterator<Item = i32, Item = u32> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+...
+LL | [2u32].into_iter()
+ | ------------------ return type was inferred to be `std::array::IntoIter<u32, 1>` here
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+ --> $DIR/duplicate-bound-err.rs:77:42
+ |
+LL | type MustFail = dyn Iterator<Item = i32, Item = u32>;
+ | ---------- ^^^^^^^^^^ re-bound here
+ | |
+ | `Item` bound here first
+
+error: conflicting associated type bounds for `Item`
+ --> $DIR/duplicate-bound-err.rs:77:17
+ |
+LL | type MustFail = dyn Iterator<Item = i32, Item = u32>;
+ | ^^^^^^^^^^^^^----------^^----------^
+ | | |
+ | | `Item` is specified to be `u32` here
+ | `Item` is specified to be `i32` here
+
+error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified
+ --> $DIR/duplicate-bound-err.rs:85:43
+ |
+LL | type MustFail2 = dyn Trait2<ASSOC = 3u32, ASSOC = 4u32>;
+ | ------------ ^^^^^^^^^^^^ re-bound here
+ | |
+ | `ASSOC` bound here first
+
+error: conflicting associated type bounds for `ASSOC`
+ --> $DIR/duplicate-bound-err.rs:85:18
+ |
+LL | type MustFail2 = dyn Trait2<ASSOC = 3u32, ASSOC = 4u32>;
+ | ^^^^^^^^^^^------------^^------------^
+ | | |
+ | | `ASSOC` is specified to be `4` here
+ | `ASSOC` is specified to be `3` here
+
+error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
+ --> $DIR/duplicate-bound-err.rs:89:43
+ |
+LL | type MustFail3 = dyn Iterator<Item = i32, Item = i32>;
+ | ---------- ^^^^^^^^^^ re-bound here
+ | |
+ | `Item` bound here first
+
+error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified
+ --> $DIR/duplicate-bound-err.rs:92:43
+ |
+LL | type MustFail4 = dyn Trait2<ASSOC = 3u32, ASSOC = 3u32>;
+ | ------------ ^^^^^^^^^^^^ re-bound here
+ | |
+ | `ASSOC` bound here first
+
+error[E0271]: expected `impl Iterator<Item = u32>` to be an iterator that yields `i32`, but it yields `u32`
+ --> $DIR/duplicate-bound-err.rs:100:17
+ |
+LL | fn foo() -> impl Iterator<Item = i32, Item = u32> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+ |
+note: required by a bound in `Trait3::foo::{anon_assoc#0}`
+ --> $DIR/duplicate-bound-err.rs:96:31
+ |
+LL | fn foo() -> impl Iterator<Item = i32, Item = u32>;
+ | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}`
+
+error[E0271]: expected `Empty<u32>` to be an iterator that yields `i32`, but it yields `u32`
+ --> $DIR/duplicate-bound-err.rs:108:16
+ |
+LL | uncallable(iter::empty::<u32>());
+ | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `uncallable`
+ --> $DIR/duplicate-bound-err.rs:71:32
+ |
+LL | fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+ | ^^^^^^^^^^ required by this bound in `uncallable`
+
+error[E0271]: expected `Empty<i32>` to be an iterator that yields `u32`, but it yields `i32`
+ --> $DIR/duplicate-bound-err.rs:109:16
+ |
+LL | uncallable(iter::empty::<i32>());
+ | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `uncallable`
+ --> $DIR/duplicate-bound-err.rs:71:44
+ |
+LL | fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+ | ^^^^^^^^^^ required by this bound in `uncallable`
+
+error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4`
+ --> $DIR/duplicate-bound-err.rs:110:22
+ |
+LL | uncallable_const(());
+ | ---------------- ^^ expected `4`, found `3`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected constant `4`
+ found constant `3`
+note: required by a bound in `uncallable_const`
+ --> $DIR/duplicate-bound-err.rs:73:46
+ |
+LL | fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+ | ^^^^^^^^^ required by this bound in `uncallable_const`
+
+error[E0271]: type mismatch resolving `<u32 as Trait>::ASSOC == 3`
+ --> $DIR/duplicate-bound-err.rs:111:22
+ |
+LL | uncallable_const(4u32);
+ | ---------------- ^^^^ expected `3`, found `4`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected constant `3`
+ found constant `4`
+note: required by a bound in `uncallable_const`
+ --> $DIR/duplicate-bound-err.rs:73:35
+ |
+LL | fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+ | ^^^^^^^^^ required by this bound in `uncallable_const`
+
+error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4`
+ --> $DIR/duplicate-bound-err.rs:112:20
+ |
+LL | uncallable_rtn(());
+ | -------------- ^^ expected `4`, found `3`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected constant `4`
+ found constant `3`
+note: required by a bound in `uncallable_rtn`
+ --> $DIR/duplicate-bound-err.rs:75:75
+ |
+LL | fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+ | ^^^^^^^^^ required by this bound in `uncallable_rtn`
+
+error[E0271]: type mismatch resolving `<u32 as Trait>::ASSOC == 3`
+ --> $DIR/duplicate-bound-err.rs:113:20
+ |
+LL | uncallable_rtn(17u32);
+ | -------------- ^^^^^ expected `3`, found `4`
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected constant `3`
+ found constant `4`
+note: required by a bound in `uncallable_rtn`
+ --> $DIR/duplicate-bound-err.rs:75:48
+ |
+LL | fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+ | ^^^^^^^^^ required by this bound in `uncallable_rtn`
+
+error: aborting due to 25 previous errors
+
+Some errors have detailed explanations: E0271, E0277, E0282, E0719.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs
new file mode 100644
index 0000000..696710d
--- /dev/null
+++ b/tests/ui/associated-type-bounds/duplicate-bound.rs
@@ -0,0 +1,240 @@
+//@ edition: 2024
+//@ run-pass
+
+#![feature(associated_const_equality, return_type_notation)]
+#![allow(dead_code, refining_impl_trait_internal, type_alias_bounds)]
+
+use std::iter;
+use std::mem::ManuallyDrop;
+
+struct Si1<T: Iterator<Item: Copy, Item: Send>> {
+ f: T,
+}
+struct Si2<T: Iterator<Item: Copy, Item: Copy>> {
+ f: T,
+}
+struct Si3<T: Iterator<Item: 'static, Item: 'static>> {
+ f: T,
+}
+struct Sw1<T>
+where
+ T: Iterator<Item: Copy, Item: Send>,
+{
+ f: T,
+}
+struct Sw2<T>
+where
+ T: Iterator<Item: Copy, Item: Copy>,
+{
+ f: T,
+}
+struct Sw3<T>
+where
+ T: Iterator<Item: 'static, Item: 'static>,
+{
+ f: T,
+}
+
+enum Ei1<T: Iterator<Item: Copy, Item: Send>> {
+ V(T),
+}
+enum Ei2<T: Iterator<Item: Copy, Item: Copy>> {
+ V(T),
+}
+enum Ei3<T: Iterator<Item: 'static, Item: 'static>> {
+ V(T),
+}
+enum Ew1<T>
+where
+ T: Iterator<Item: Copy, Item: Send>,
+{
+ V(T),
+}
+enum Ew2<T>
+where
+ T: Iterator<Item: Copy, Item: Copy>,
+{
+ V(T),
+}
+enum Ew3<T>
+where
+ T: Iterator<Item: 'static, Item: 'static>,
+{
+ V(T),
+}
+
+union Ui1<T: Iterator<Item: Copy, Item: Send>> {
+ f: ManuallyDrop<T>,
+}
+union Ui2<T: Iterator<Item: Copy, Item: Copy>> {
+ f: ManuallyDrop<T>,
+}
+union Ui3<T: Iterator<Item: 'static, Item: 'static>> {
+ f: ManuallyDrop<T>,
+}
+union Uw1<T>
+where
+ T: Iterator<Item: Copy, Item: Send>,
+{
+ f: ManuallyDrop<T>,
+}
+union Uw2<T>
+where
+ T: Iterator<Item: Copy, Item: Copy>,
+{
+ f: ManuallyDrop<T>,
+}
+union Uw3<T>
+where
+ T: Iterator<Item: 'static, Item: 'static>,
+{
+ f: ManuallyDrop<T>,
+}
+
+fn fi1<T: Iterator<Item: Copy, Item: Send>>() {}
+fn fi2<T: Iterator<Item: Copy, Item: Copy>>() {}
+fn fi3<T: Iterator<Item: 'static, Item: 'static>>() {}
+fn fw1<T>()
+where
+ T: Iterator<Item: Copy, Item: Send>,
+{
+}
+fn fw2<T>()
+where
+ T: Iterator<Item: Copy, Item: Copy>,
+{
+}
+fn fw3<T>()
+where
+ T: Iterator<Item: 'static, Item: 'static>,
+{
+}
+
+fn rpit1() -> impl Iterator<Item: Copy, Item: Send> {
+ iter::empty::<u32>()
+}
+fn rpit2() -> impl Iterator<Item: Copy, Item: Copy> {
+ iter::empty::<u32>()
+}
+fn rpit3() -> impl Iterator<Item: 'static, Item: 'static> {
+ iter::empty::<u32>()
+}
+fn apit1(_: impl Iterator<Item: Copy, Item: Send>) {}
+fn apit2(_: impl Iterator<Item: Copy, Item: Copy>) {}
+fn apit3(_: impl Iterator<Item: 'static, Item: 'static>) {}
+
+type Tait1<T: Iterator<Item: Copy, Item: Send>> = T;
+type Tait2<T: Iterator<Item: Copy, Item: Copy>> = T;
+type Tait3<T: Iterator<Item: 'static, Item: 'static>> = T;
+type Taw1<T>
+where
+ T: Iterator<Item: Copy, Item: Send>,
+= T;
+type Taw2<T>
+where
+ T: Iterator<Item: Copy, Item: Copy>,
+= T;
+type Taw3<T>
+where
+ T: Iterator<Item: 'static, Item: 'static>,
+= T;
+
+trait Tri1<T: Iterator<Item: Copy, Item: Send>> {}
+trait Tri2<T: Iterator<Item: Copy, Item: Copy>> {}
+trait Tri3<T: Iterator<Item: 'static, Item: 'static>> {}
+trait Trs1: Iterator<Item: Copy, Item: Send> {}
+trait Trs2: Iterator<Item: Copy, Item: Copy> {}
+trait Trs3: Iterator<Item: 'static, Item: 'static> {}
+trait Trw1<T>
+where
+ T: Iterator<Item: Copy, Item: Send>,
+{
+}
+trait Trw2<T>
+where
+ T: Iterator<Item: Copy, Item: Copy>,
+{
+}
+trait Trw3<T>
+where
+ T: Iterator<Item: 'static, Item: 'static>,
+{
+}
+trait Trsw1
+where
+ Self: Iterator<Item: Copy, Item: Send>,
+{
+}
+trait Trsw2
+where
+ Self: Iterator<Item: Copy, Item: Copy>,
+{
+}
+trait Trsw3
+where
+ Self: Iterator<Item: 'static, Item: 'static>,
+{
+}
+trait Tra1 {
+ type A: Iterator<Item: Copy, Item: Send>;
+}
+trait Tra2 {
+ type A: Iterator<Item: Copy, Item: Copy>;
+}
+trait Tra3 {
+ type A: Iterator<Item: 'static, Item: 'static>;
+}
+
+trait Trait {
+ type Gat<T>;
+
+ const ASSOC: i32;
+
+ fn foo() -> impl Sized;
+}
+
+impl Trait for () {
+ type Gat<T> = ();
+
+ const ASSOC: i32 = 3;
+
+ fn foo() {}
+}
+
+trait Subtrait: Trait<Gat<u32> = u32, Gat<u64> = u64> {}
+
+fn f<T: Trait<Gat<i32> = (), Gat<i64> = ()>>() {
+ let _: T::Gat<i32> = ();
+ let _: T::Gat<i64> = ();
+}
+
+fn g<T: Trait<Gat<i32> = (), Gat<i64> = &'static str>>() {
+ let _: T::Gat<i32> = ();
+ let _: T::Gat<i64> = "";
+}
+
+fn uncallable(_: impl Iterator<Item = i32, Item = u32>) {}
+
+fn callable(_: impl Iterator<Item = i32, Item = i32>) {}
+
+fn uncallable_const(_: impl Trait<ASSOC = 3, ASSOC = 4>) {}
+
+fn callable_const(_: impl Trait<ASSOC = 3, ASSOC = 3>) {}
+
+fn uncallable_rtn(_: impl Trait<foo(..): Trait<ASSOC = 3>, foo(..): Trait<ASSOC = 4>>) {}
+
+fn callable_rtn(_: impl Trait<foo(..): Send, foo(..): Send, foo(..): Eq>) {}
+
+trait Trait2 {
+ const ASSOC: u32;
+}
+
+trait Trait3 {
+ fn foo() -> impl Iterator<Item = i32, Item = u32>;
+}
+
+fn main() {
+ callable(iter::empty::<i32>());
+ callable_const(());
+ callable_rtn(());
+}
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
deleted file mode 100644
index e9d9478..0000000
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ /dev/null
@@ -1,278 +0,0 @@
-#![feature(type_alias_impl_trait)]
-
-use std::iter;
-use std::mem::ManuallyDrop;
-
-struct SI1<T: Iterator<Item: Copy, Item: Send>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- f: T,
-}
-struct SI2<T: Iterator<Item: Copy, Item: Copy>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- f: T,
-}
-struct SI3<T: Iterator<Item: 'static, Item: 'static>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- f: T,
-}
-struct SW1<T>
-where
- T: Iterator<Item: Copy, Item: Send>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- f: T,
-}
-struct SW2<T>
-where
- T: Iterator<Item: Copy, Item: Copy>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- f: T,
-}
-struct SW3<T>
-where
- T: Iterator<Item: 'static, Item: 'static>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- f: T,
-}
-
-enum EI1<T: Iterator<Item: Copy, Item: Send>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- V(T),
-}
-enum EI2<T: Iterator<Item: Copy, Item: Copy>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- V(T),
-}
-enum EI3<T: Iterator<Item: 'static, Item: 'static>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- V(T),
-}
-enum EW1<T>
-where
- T: Iterator<Item: Copy, Item: Send>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- V(T),
-}
-enum EW2<T>
-where
- T: Iterator<Item: Copy, Item: Copy>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- V(T),
-}
-enum EW3<T>
-where
- T: Iterator<Item: 'static, Item: 'static>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- V(T),
-}
-
-union UI1<T: Iterator<Item: Copy, Item: Send>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- f: ManuallyDrop<T>,
-}
-union UI2<T: Iterator<Item: Copy, Item: Copy>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- f: ManuallyDrop<T>,
-}
-union UI3<T: Iterator<Item: 'static, Item: 'static>> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- f: ManuallyDrop<T>,
-}
-union UW1<T>
-where
- T: Iterator<Item: Copy, Item: Send>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- f: ManuallyDrop<T>,
-}
-union UW2<T>
-where
- T: Iterator<Item: Copy, Item: Copy>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- f: ManuallyDrop<T>,
-}
-union UW3<T>
-where
- T: Iterator<Item: 'static, Item: 'static>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
- f: ManuallyDrop<T>,
-}
-
-fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FW1<T>()
-where
- T: Iterator<Item: Copy, Item: Send>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-fn FW2<T>()
-where
- T: Iterator<Item: Copy, Item: Copy>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-fn FW3<T>()
-where
- T: Iterator<Item: 'static, Item: 'static>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-
-fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- iter::empty()
- //~^ ERROR type annotations needed
-}
-fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- iter::empty()
- //~^ ERROR type annotations needed
-}
-fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- iter::empty()
- //~^ ERROR type annotations needed
-}
-fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-
-type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-type TAW1<T>
-where
- T: Iterator<Item: Copy, Item: Send>,
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-= T;
-type TAW2<T>
-where
- T: Iterator<Item: Copy, Item: Copy>,
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-= T;
-type TAW3<T>
-where
- T: Iterator<Item: 'static, Item: 'static>,
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-= T;
-
-type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR unconstrained opaque type
-
-trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRS1: Iterator<Item: Copy, Item: Send> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRS2: Iterator<Item: Copy, Item: Copy> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRS3: Iterator<Item: 'static, Item: 'static> {}
-//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-trait TRW1<T>
-where
- T: Iterator<Item: Copy, Item: Send>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRW2<T>
-where
- T: Iterator<Item: Copy, Item: Copy>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRW3<T>
-where
- T: Iterator<Item: 'static, Item: 'static>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRSW1
-where
- Self: Iterator<Item: Copy, Item: Send>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRSW2
-where
- Self: Iterator<Item: Copy, Item: Copy>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRSW3
-where
- Self: Iterator<Item: 'static, Item: 'static>,
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-{
-}
-trait TRA1 {
- type A: Iterator<Item: Copy, Item: Send>;
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-}
-trait TRA2 {
- type A: Iterator<Item: Copy, Item: Copy>;
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-}
-trait TRA3 {
- type A: Iterator<Item: 'static, Item: 'static>;
- //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
- //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-}
-
-fn main() {}
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
deleted file mode 100644
index 68fbb34..0000000
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ /dev/null
@@ -1,751 +0,0 @@
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:6:36
- |
-LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:10:36
- |
-LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:14:39
- |
-LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> {
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:20:29
- |
-LL | T: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:27:29
- |
-LL | T: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:34:32
- |
-LL | T: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:40:34
- |
-LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:44:34
- |
-LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:48:37
- |
-LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> {
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:54:29
- |
-LL | T: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:61:29
- |
-LL | T: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:68:32
- |
-LL | T: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:74:35
- |
-LL | union UI1<T: Iterator<Item: Copy, Item: Send>> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:78:35
- |
-LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:82:38
- |
-LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> {
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:88:29
- |
-LL | T: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:95:29
- |
-LL | T: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:102:32
- |
-LL | T: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:108:32
- |
-LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:110:32
- |
-LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:112:35
- |
-LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:116:29
- |
-LL | T: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:122:29
- |
-LL | T: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:128:32
- |
-LL | T: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:133:42
- |
-LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:139:42
- |
-LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:145:45
- |
-LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:151:40
- |
-LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:153:40
- |
-LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:155:43
- |
-LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:158:35
- |
-LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:160:35
- |
-LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:162:38
- |
-LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:166:29
- |
-LL | T: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:171:29
- |
-LL | T: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:176:32
- |
-LL | T: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:180:36
- |
-LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:183:36
- |
-LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:186:39
- |
-LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:202:36
- |
-LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:204:36
- |
-LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:206:39
- |
-LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:208:34
- |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:208:34
- |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:208:34
- |
-LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:212:34
- |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:212:34
- |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:212:34
- |
-LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:216:37
- |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:216:37
- |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:216:37
- |
-LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:222:29
- |
-LL | T: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:228:29
- |
-LL | T: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:234:32
- |
-LL | T: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:240:32
- |
-LL | Self: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:240:32
- |
-LL | Self: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:240:32
- |
-LL | Self: Iterator<Item: Copy, Item: Send>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:248:32
- |
-LL | Self: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:248:32
- |
-LL | Self: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:248:32
- |
-LL | Self: Iterator<Item: Copy, Item: Copy>,
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:256:35
- |
-LL | Self: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:256:35
- |
-LL | Self: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:256:35
- |
-LL | Self: Iterator<Item: 'static, Item: 'static>,
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:263:34
- |
-LL | type A: Iterator<Item: Copy, Item: Send>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:263:34
- |
-LL | type A: Iterator<Item: Copy, Item: Send>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:268:34
- |
-LL | type A: Iterator<Item: Copy, Item: Copy>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:268:34
- |
-LL | type A: Iterator<Item: Copy, Item: Copy>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:273:37
- |
-LL | type A: Iterator<Item: 'static, Item: 'static>;
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:273:37
- |
-LL | type A: Iterator<Item: 'static, Item: 'static>;
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:133:42
- |
-LL | fn FRPIT1() -> impl Iterator<Item: Copy, Item: Send> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0282]: type annotations needed
- --> $DIR/duplicate.rs:136:5
- |
-LL | iter::empty()
- | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
- |
-help: consider specifying the generic argument
- |
-LL | iter::empty::<T>()
- | +++++
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:139:42
- |
-LL | fn FRPIT2() -> impl Iterator<Item: Copy, Item: Copy> {
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0282]: type annotations needed
- --> $DIR/duplicate.rs:142:5
- |
-LL | iter::empty()
- | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
- |
-help: consider specifying the generic argument
- |
-LL | iter::empty::<T>()
- | +++++
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:145:45
- |
-LL | fn FRPIT3() -> impl Iterator<Item: 'static, Item: 'static> {
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0282]: type annotations needed
- --> $DIR/duplicate.rs:148:5
- |
-LL | iter::empty()
- | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty`
- |
-help: consider specifying the generic argument
- |
-LL | iter::empty::<T>()
- | +++++
-
-error: unconstrained opaque type
- --> $DIR/duplicate.rs:180:51
- |
-LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
- | ^^^^^^^^^
- |
- = note: `ETAI1` must be used in combination with a concrete type within the same crate
-
-error: unconstrained opaque type
- --> $DIR/duplicate.rs:183:51
- |
-LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
- | ^^^^^^^^^
- |
- = note: `ETAI2` must be used in combination with a concrete type within the same crate
-
-error: unconstrained opaque type
- --> $DIR/duplicate.rs:186:57
- |
-LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
- | ^^^^^^^^^
- |
- = note: `ETAI3` must be used in combination with a concrete type within the same crate
-
-error: unconstrained opaque type
- --> $DIR/duplicate.rs:189:14
- |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `ETAI4` must be used in combination with a concrete type within the same crate
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:189:40
- |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:189:40
- |
-LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: unconstrained opaque type
- --> $DIR/duplicate.rs:193:14
- |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `ETAI5` must be used in combination with a concrete type within the same crate
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:193:40
- |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:193:40
- |
-LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: unconstrained opaque type
- --> $DIR/duplicate.rs:197:14
- |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `ETAI6` must be used in combination with a concrete type within the same crate
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:197:43
- |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/duplicate.rs:197:43
- |
-LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 87 previous errors
-
-Some errors have detailed explanations: E0282, E0719.
-For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
index 71a4a26..e96a244 100644
--- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
+++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -1,4 +1,4 @@
-error: conflicting associated type bounds for `Item` when expanding trait alias
+error: conflicting associated type bounds for `Item`
--> $DIR/associated-types-overridden-binding-2.rs:6:13
|
LL | trait I32Iterator = Iterator<Item = i32>;
diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr
index 3b20015..08ab9b6 100644
--- a/tests/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr
@@ -22,7 +22,7 @@
LL | trait I32Iterator = Iterator<Item = i32>;
| ^^^^^^^^^^ required by this bound in `I32Iterator`
-error: conflicting associated type bounds for `Item` when expanding trait alias
+error: conflicting associated type bounds for `Item`
--> $DIR/associated-types-overridden-binding.rs:10:13
|
LL | trait I32Iterator = Iterator<Item = i32>;
diff --git a/tests/ui/coroutine/handle_opaques_before_coroutines.rs b/tests/ui/coroutine/handle_opaques_before_coroutines.rs
new file mode 100644
index 0000000..2771c77
--- /dev/null
+++ b/tests/ui/coroutine/handle_opaques_before_coroutines.rs
@@ -0,0 +1,15 @@
+// test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/239
+//@edition: 2024
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+fn foo<'a>() -> impl Send {
+ if false {
+ foo();
+ }
+ async {}
+}
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0719.rs b/tests/ui/error-codes/E0719.rs
index 0ea6d19..d7b4b87 100644
--- a/tests/ui/error-codes/E0719.rs
+++ b/tests/ui/error-codes/E0719.rs
@@ -1,8 +1,3 @@
-trait Foo: Iterator<Item = i32, Item = i32> {}
-//~^ ERROR is already specified
-//~| ERROR is already specified
-//~| ERROR is already specified
-
type Unit = ();
fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
diff --git a/tests/ui/error-codes/E0719.stderr b/tests/ui/error-codes/E0719.stderr
index 7e8329d..f481756 100644
--- a/tests/ui/error-codes/E0719.stderr
+++ b/tests/ui/error-codes/E0719.stderr
@@ -1,33 +1,5 @@
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/E0719.rs:1:33
- |
-LL | trait Foo: Iterator<Item = i32, Item = i32> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/E0719.rs:1:33
- |
-LL | trait Foo: Iterator<Item = i32, Item = i32> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/E0719.rs:1:33
- |
-LL | trait Foo: Iterator<Item = i32, Item = i32> {}
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
- |
- = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/E0719.rs:8:42
+ --> $DIR/E0719.rs:3:42
|
LL | fn test() -> Box<dyn Iterator<Item = (), Item = Unit>> {
| --------- ^^^^^^^^^^^ re-bound here
@@ -35,13 +7,13 @@
| `Item` bound here first
error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
- --> $DIR/E0719.rs:14:38
+ --> $DIR/E0719.rs:9:38
|
LL | let _: &dyn Iterator<Item = i32, Item = i32>;
| ---------- ^^^^^^^^^^ re-bound here
| |
| `Item` bound here first
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0719`.
diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs
index 6548c03..e2750bc 100644
--- a/tests/ui/implied-bounds/bevy_world_query.rs
+++ b/tests/ui/implied-bounds/bevy_world_query.rs
@@ -1,6 +1,8 @@
-#![crate_name = "bevy_ecs"]
-
//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+#![crate_name = "bevy_ecs"]
// We currently special case bevy from erroring on incorrect implied bounds
// from normalization (issue #109628).
diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr
index d1c3d06..62a0263 100644
--- a/tests/ui/proc-macro/quote/not-quotable.stderr
+++ b/tests/ui/proc-macro/quote/not-quotable.stderr
@@ -15,8 +15,8 @@
Cow<'_, T>
Option<T>
Rc<T>
- RepInterp<T>
- and 25 others
+ bool
+ and 24 others
error: aborting due to 1 previous error
diff --git a/tests/ui/suggestions/auxiliary/hidden-struct.rs b/tests/ui/suggestions/auxiliary/hidden-struct.rs
index 30d69ac..1f495a9 100644
--- a/tests/ui/suggestions/auxiliary/hidden-struct.rs
+++ b/tests/ui/suggestions/auxiliary/hidden-struct.rs
@@ -1,3 +1,5 @@
+// `Foo` and `Bar` should not be suggested in diagnostics of dependents
+
#[doc(hidden)]
pub mod hidden {
pub struct Foo;
@@ -5,13 +7,29 @@ pub mod hidden {
pub mod hidden1 {
#[doc(hidden)]
- pub struct Foo;
-}
-
-
-#[doc(hidden)]
-pub(crate) mod hidden2 {
pub struct Bar;
}
-pub use hidden2::Bar;
+// `Baz` and `Quux` *should* be suggested in diagnostics of dependents
+
+#[doc(hidden)]
+pub mod hidden2 {
+ pub struct Baz;
+}
+
+pub use hidden2::Baz;
+
+#[doc(hidden)]
+pub(crate) mod hidden3 {
+ pub struct Quux;
+}
+
+pub use hidden3::Quux;
+
+pub trait Marker {}
+
+impl Marker for Option<u32> {}
+impl Marker for hidden::Foo {}
+impl Marker for hidden1::Bar {}
+impl Marker for Baz {}
+impl Marker for Quux {}
diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
index 281975d..a83e496 100644
--- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
+++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
@@ -1,5 +1,4 @@
//@ aux-build:hidden-struct.rs
-//@ compile-flags: --crate-type lib
extern crate hidden_struct;
@@ -9,7 +8,20 @@ mod local {
}
pub fn test(_: Foo) {}
-//~^ ERROR cannot find type `Foo` in this scope
+//~^ ERROR [E0412]
pub fn test2(_: Bar) {}
-//~^ ERROR cannot find type `Bar` in this scope
+//~^ ERROR [E0412]
+
+pub fn test3(_: Baz) {}
+//~^ ERROR [E0412]
+
+pub fn test4(_: Quux) {}
+//~^ ERROR [E0412]
+
+fn test5<T: hidden_struct::Marker>() {}
+
+fn main() {
+ test5::<i32>();
+ //~^ ERROR [E0277]
+}
diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr
index 7fb4d95..7036708 100644
--- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr
+++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr
@@ -1,5 +1,5 @@
error[E0412]: cannot find type `Foo` in this scope
- --> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16
+ --> $DIR/dont-suggest-foreign-doc-hidden.rs:10:16
|
LL | pub fn test(_: Foo) {}
| ^^^ not found in this scope
@@ -10,16 +10,50 @@
|
error[E0412]: cannot find type `Bar` in this scope
- --> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17
+ --> $DIR/dont-suggest-foreign-doc-hidden.rs:13:17
|
LL | pub fn test2(_: Bar) {}
| ^^^ not found in this scope
+
+error[E0412]: cannot find type `Baz` in this scope
+ --> $DIR/dont-suggest-foreign-doc-hidden.rs:16:17
+ |
+LL | pub fn test3(_: Baz) {}
+ | ^^^ not found in this scope
|
help: consider importing this struct
|
-LL + use hidden_struct::Bar;
+LL + use hidden_struct::Baz;
|
-error: aborting due to 2 previous errors
+error[E0412]: cannot find type `Quux` in this scope
+ --> $DIR/dont-suggest-foreign-doc-hidden.rs:19:17
+ |
+LL | pub fn test4(_: Quux) {}
+ | ^^^^ not found in this scope
+ |
+help: consider importing this struct
+ |
+LL + use hidden_struct::Quux;
+ |
-For more information about this error, try `rustc --explain E0412`.
+error[E0277]: the trait bound `i32: Marker` is not satisfied
+ --> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13
+ |
+LL | test5::<i32>();
+ | ^^^ the trait `Marker` is not implemented for `i32`
+ |
+ = help: the following other types implement trait `Marker`:
+ Baz
+ Option<u32>
+ Quux
+note: required by a bound in `test5`
+ --> $DIR/dont-suggest-foreign-doc-hidden.rs:22:13
+ |
+LL | fn test5<T: hidden_struct::Marker>() {}
+ | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0412.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
index 2760c16..f603ff1 100644
--- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs
@@ -1,12 +1,5 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
-//@[next] failure-status: 101
-//@[next] known-bug: unknown
-//@[next] normalize-stderr: "note: .*\n\n" -> ""
-//@[next] normalize-stderr: "thread 'rustc' panicked.*\n.*\n" -> ""
-//@[next] normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
-//@[next] normalize-stderr: "delayed at .*" -> ""
-//@[next] rustc-env:RUST_BACKTRACE=0
//@ check-pass
trait Super {