diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 85f31b75e240a..88f8b7cc51704 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,5 +1,5 @@ // tidy-alphabetical-start -#![cfg_attr(all(feature = "nightly", bootstrap), feature(assert_matches))] +#![cfg_attr(all(feature = "nightly", bootstrap, test), feature(assert_matches))] #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(step_trait))] diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index f1b31365013ec..d535998a10816 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1103,6 +1103,45 @@ impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility; } +pub(crate) struct RustcDiagnosticItemParser; + +impl SingleAttributeParser for RustcDiagnosticItemParser { + const PATH: &[Symbol] = &[sym::rustc_diagnostic_item]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Trait), + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::MacroDef), + Allow(Target::TyAlias), + Allow(Target::AssocTy), + Allow(Target::AssocConst), + Allow(Target::Fn), + Allow(Target::Const), + Allow(Target::Mod), + Allow(Target::Impl { of_trait: false }), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Crate), + ]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + let Some(value) = nv.value_as_str() else { + cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + Some(AttributeKind::RustcDiagnosticItem(value)) + } +} + pub(crate) struct RustcSymbolName; impl SingleAttributeParser for RustcSymbolName { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index c6f0914bfbdaf..e000d68520739 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -203,6 +203,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 0c4a82f3d2f36..23ad964c7cd90 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -24,13 +24,13 @@ use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use tracing::{debug, instrument}; use super::reverse_sccs::ReverseSccGraph; -use crate::BorrowckInferCtxt; use crate::consumers::RegionInferenceContext; use crate::session_diagnostics::LifetimeMismatchOpaqueParam; use crate::type_check::canonical::fully_perform_op_raw; use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::type_check::{Locations, MirTypeckRegionConstraints}; use crate::universal_regions::{RegionClassification, UniversalRegions}; +use crate::{BorrowckInferCtxt, CollectRegionConstraintsResult}; mod member_constraints; mod region_ctxt; @@ -126,6 +126,31 @@ fn nll_var_to_universal_region<'tcx>( } } +/// Record info needed to report the same name error later. +#[derive(Copy, Clone, Debug)] +pub(crate) struct UnexpectedHiddenRegion<'tcx> { + // The def_id of the body where this error occurs. + // Needed to handle region vars with their corresponding `infcx`. + def_id: LocalDefId, + opaque_type_key: OpaqueTypeKey<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, + member_region: Region<'tcx>, +} + +impl<'tcx> UnexpectedHiddenRegion<'tcx> { + pub(crate) fn to_error(self) -> (LocalDefId, DeferredOpaqueTypeError<'tcx>) { + let UnexpectedHiddenRegion { def_id, opaque_type_key, hidden_type, member_region } = self; + ( + def_id, + DeferredOpaqueTypeError::UnexpectedHiddenRegion { + opaque_type_key, + hidden_type, + member_region, + }, + ) + } +} + /// Collect all defining uses of opaque types inside of this typeck root. This /// expects the hidden type to be mapped to the definition parameters of the opaque /// and errors if we end up with distinct hidden types. @@ -176,11 +201,13 @@ struct DefiningUse<'tcx> { /// It also means that this whole function is not really soundness critical as we /// recheck all uses of the opaques regardless. pub(crate) fn compute_definition_site_hidden_types<'tcx>( + def_id: LocalDefId, infcx: &BorrowckInferCtxt<'tcx>, universal_region_relations: &Frozen>, constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, hidden_types: &mut FxIndexMap>, + unconstrained_hidden_type_errors: &mut Vec>, opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], ) -> Vec> { let mut errors = Vec::new(); @@ -204,8 +231,10 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( // up equal to one of their choice regions and compute the actual hidden type of // the opaque type definition. This is stored in the `root_cx`. compute_definition_site_hidden_types_from_defining_uses( + def_id, &rcx, hidden_types, + unconstrained_hidden_type_errors, &defining_uses, &mut errors, ); @@ -274,8 +303,10 @@ fn collect_defining_uses<'tcx>( #[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))] fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( + def_id: LocalDefId, rcx: &RegionCtxt<'_, 'tcx>, hidden_types: &mut FxIndexMap>, + unconstrained_hidden_type_errors: &mut Vec>, defining_uses: &[DefiningUse<'tcx>], errors: &mut Vec>, ) { @@ -293,16 +324,29 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( Ok(hidden_type) => hidden_type, Err(r) => { debug!("UnexpectedHiddenRegion: {:?}", r); - errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion { - hidden_type, - opaque_type_key, - member_region: ty::Region::new_var(tcx, r), - }); - let guar = tcx.dcx().span_delayed_bug( - hidden_type.span, - "opaque type with non-universal region args", - ); - ty::ProvisionalHiddenType::new_error(tcx, guar) + // If we're using the next solver, the unconstrained region may be resolved by a + // fully defining use from another body. + // So we don't generate error eagerly here. + if rcx.infcx.tcx.use_typing_mode_borrowck() { + unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion { + def_id, + hidden_type, + opaque_type_key, + member_region: ty::Region::new_var(tcx, r), + }); + continue; + } else { + errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion { + hidden_type, + opaque_type_key, + member_region: ty::Region::new_var(tcx, r), + }); + let guar = tcx.dcx().span_delayed_bug( + hidden_type.span, + "opaque type with non-universal region args", + ); + ty::ProvisionalHiddenType::new_error(tcx, guar) + } } }; @@ -570,6 +614,40 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( errors } +/// We handle `UnexpectedHiddenRegion` error lazily in the next solver as +/// there may be a fully defining use in another body. +/// +/// In case such a defining use does not exist, we register an error here. +pub(crate) fn handle_unconstrained_hidden_type_errors<'tcx>( + tcx: TyCtxt<'tcx>, + hidden_types: &mut FxIndexMap>, + unconstrained_hidden_type_errors: &mut Vec>, + collect_region_constraints_results: &mut FxIndexMap< + LocalDefId, + CollectRegionConstraintsResult<'tcx>, + >, +) { + let mut unconstrained_hidden_type_errors = std::mem::take(unconstrained_hidden_type_errors); + unconstrained_hidden_type_errors + .retain(|unconstrained| !hidden_types.contains_key(&unconstrained.opaque_type_key.def_id)); + + unconstrained_hidden_type_errors.iter().for_each(|t| { + tcx.dcx() + .span_delayed_bug(t.hidden_type.span, "opaque type with non-universal region args"); + }); + + // `UnexpectedHiddenRegion` error contains region var which only makes sense in the + // corresponding `infcx`. + // So we need to insert the error to the body where it originates from. + for error in unconstrained_hidden_type_errors { + let (def_id, error) = error.to_error(); + let Some(result) = collect_region_constraints_results.get_mut(&def_id) else { + unreachable!("the body should depend on opaques type if it has opaque use"); + }; + result.deferred_opaque_type_errors.push(error); + } +} + /// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types. /// We do not check these new uses so this could be unsound. /// diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index 4d42055df1687..a082aba35b8a7 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -12,8 +12,9 @@ use smallvec::SmallVec; use crate::consumers::BorrowckConsumer; use crate::nll::compute_closure_requirements_modulo_opaques; use crate::region_infer::opaque_types::{ - apply_definition_site_hidden_types, clone_and_resolve_opaque_types, + UnexpectedHiddenRegion, apply_definition_site_hidden_types, clone_and_resolve_opaque_types, compute_definition_site_hidden_types, detect_opaque_types_added_while_handling_opaque_types, + handle_unconstrained_hidden_type_errors, }; use crate::type_check::{Locations, constraint_conversion}; use crate::{ @@ -26,7 +27,12 @@ use crate::{ pub(super) struct BorrowCheckRootCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, + /// This contains fully resolved hidden types or `ty::Error`. hidden_types: FxIndexMap>, + /// This contains unconstrained regions in hidden types. + /// Only used for deferred error reporting. See + /// [`crate::region_infer::opaque_types::handle_unconstrained_hidden_type_errors`] + unconstrained_hidden_type_errors: Vec>, /// The region constraints computed by [borrowck_collect_region_constraints]. This uses /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before /// their parents. @@ -49,6 +55,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { tcx, root_def_id, hidden_types: Default::default(), + unconstrained_hidden_type_errors: Default::default(), collect_region_constraints_results: Default::default(), propagated_borrowck_results: Default::default(), tainted_by_errors: None, @@ -84,23 +91,32 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { fn handle_opaque_type_uses(&mut self) { let mut per_body_info = Vec::new(); - for input in self.collect_region_constraints_results.values_mut() { + for (def_id, input) in &mut self.collect_region_constraints_results { let (num_entries, opaque_types) = clone_and_resolve_opaque_types( &input.infcx, &input.universal_region_relations, &mut input.constraints, ); input.deferred_opaque_type_errors = compute_definition_site_hidden_types( + *def_id, &input.infcx, &input.universal_region_relations, &input.constraints, Rc::clone(&input.location_map), &mut self.hidden_types, + &mut self.unconstrained_hidden_type_errors, &opaque_types, ); per_body_info.push((num_entries, opaque_types)); } + handle_unconstrained_hidden_type_errors( + self.tcx, + &mut self.hidden_types, + &mut self.unconstrained_hidden_type_errors, + &mut self.collect_region_constraints_results, + ); + for (input, (opaque_types_storage_num_entries, opaque_types)) in self.collect_region_constraints_results.values_mut().zip(per_body_info) { diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index e7daf57de0f03..656e7b0aec5b2 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -2,8 +2,8 @@ // Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Only used to define intrinsics in `compiler_builtins.rs`. -#![feature(f16)] -#![feature(f128)] +#![cfg_attr(feature = "jit", feature(f16))] +#![cfg_attr(feature = "jit", feature(f128))] // Note: please avoid adding other feature gates where possible #![warn(rust_2018_idioms)] #![warn(unreachable_pub)] diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/doc.md b/compiler/rustc_codegen_llvm/src/debuginfo/doc.md index aaec4e68c1743..f5ea5ea77c4bc 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/doc.md +++ b/compiler/rustc_codegen_llvm/src/debuginfo/doc.md @@ -16,7 +16,7 @@ module to generate correct metadata and insert it into the LLVM IR. As the exact format of metadata trees may change between different LLVM versions, we now use LLVM [DIBuilder](https://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) -to create metadata where possible. This will hopefully ease the adaption of +to create metadata where possible. This will hopefully ease the adaptation of this module to future LLVM versions. The public API of the module is a set of functions that will insert the @@ -87,19 +87,19 @@ describe the type anew. This behavior is encapsulated in the ## Source Locations and Line Information In addition to data type descriptions the debugging information must also -allow to map machine code locations back to source code locations in order +allow mapping machine code locations back to source code locations in order to be useful. This functionality is also handled in this module. The -following functions allow to control source mappings: +following functions allow controlling source mappings: + `set_source_location()` + `clear_source_location()` + `start_emitting_source_locations()` -`set_source_location()` allows to set the current source location. All IR +`set_source_location()` allows setting the current source location. All IR instructions created after a call to this function will be linked to the given source location, until another location is specified with `set_source_location()` or the source location is cleared with -`clear_source_location()`. In the later case, subsequent IR instruction +`clear_source_location()`. In the latter case, subsequent IR instructions will not be linked to any source location. As you can see, this is a stateful API (mimicking the one in LLVM), so be careful with source locations set by previous calls. It's probably best to not rely on any diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 9f39750d81252..ae28e3d7d1929 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -471,9 +471,9 @@ fn report_eval_error<'tcx>( span, inline_fluent!( "evaluation of `{$instance}` failed {$num_frames -> - [0] here - *[other] inside this call -}" + [0] here + *[other] inside this call + }" ), ); for frame in frames { diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index da4f97db1c59c..8bc515a8b1b5d 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -491,10 +491,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { Err(err) => throw_ub_custom!( inline_fluent!( "invalid align passed to `{$name}`: {$align} is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {\"\"} -}" + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" ), name = "const_allocate", err_kind = err.diag_ident(), @@ -521,10 +521,10 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { Err(err) => throw_ub_custom!( inline_fluent!( "invalid align passed to `{$name}`: {$align} is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {\"\"} -}" + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" ), name = "const_deallocate", err_kind = err.diag_ident(), diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index a673e0cb1efbd..cba2c462bf22d 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -393,16 +393,17 @@ impl Subdiagnostic for FrameNote { } let msg = diag.eagerly_translate(inline_fluent!( r#"{$times -> - [0] {const_eval_frame_note_inner} - *[other] [... {$times} additional calls {const_eval_frame_note_inner} ...] -} - -const_eval_frame_note_inner = inside {$where_ -> - [closure] closure - [instance] `{$instance}` - *[other] {""} -} -"# + [0] inside {$where_ -> + [closure] closure + [instance] `{$instance}` + *[other] {""} + } + *[other] [... {$times} additional calls inside {$where_ -> + [closure] closure + [instance] `{$instance}` + *[other] {""} + } ...] + }"# )); diag.remove_arg("times"); diag.remove_arg("where_"); @@ -663,89 +664,96 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { InvalidMeta(InvalidMetaKind::SliceTooBig) => "invalid metadata in wide pointer: slice is bigger than largest supported object".into(), InvalidMeta(InvalidMetaKind::TooBig) => "invalid metadata in wide pointer: total size is bigger than largest supported object".into(), UnterminatedCString(_) => "reading a null-terminated string starting at {$pointer} with no null found before end of allocation".into(), - PointerUseAfterFree(_, _) => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$alloc_id} has been freed, so this pointer is dangling"), - PointerOutOfBounds { .. } => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } -}, but got {$pointer} which {$ptr_offset_is_neg -> - [true] points to before the beginning of the allocation - *[false] {$inbounds_size_is_neg -> - [false] {$alloc_size_minus_ptr_offset -> - [0] is at or beyond the end of the allocation of size {$alloc_size -> - [1] 1 byte - *[x] {$alloc_size} bytes - } - [1] is only 1 byte from the end of the allocation - *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation - } - *[true] {$ptr_offset_abs -> - [0] is at the beginning of the allocation - *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation - } - } -} -"), - DanglingIntPointer { addr: 0, .. } => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } -}, but got null pointer"), - DanglingIntPointer { .. } => inline_fluent!("{$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } -}, but got {$pointer} which is a dangling pointer (it has no provenance)"), - AlignmentCheckFailed { .. } => inline_fluent!("{$msg -> - [AccessedPtr] accessing memory - *[other] accessing memory based on pointer -} with alignment {$has}, but alignment {$required} is required"), + PointerUseAfterFree(_, _) => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$alloc_id} has been freed, so this pointer is dangling" + ), + PointerOutOfBounds { .. } => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got {$pointer} which {$ptr_offset_is_neg -> + [true] points to before the beginning of the allocation + *[false] {$inbounds_size_is_neg -> + [false] {$alloc_size_minus_ptr_offset -> + [0] is at or beyond the end of the allocation of size {$alloc_size -> + [1] 1 byte + *[x] {$alloc_size} bytes + } + [1] is only 1 byte from the end of the allocation + *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation + } + *[true] {$ptr_offset_abs -> + [0] is at the beginning of the allocation + *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation + } + } + }" + ), + DanglingIntPointer { addr: 0, .. } => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got null pointer"), + DanglingIntPointer { .. } => inline_fluent!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got {$pointer} which is a dangling pointer (it has no provenance)"), + AlignmentCheckFailed { .. } => inline_fluent!( + "{$msg -> + [AccessedPtr] accessing memory + *[other] accessing memory based on pointer + } with alignment {$has}, but alignment {$required} is required" + ), WriteToReadOnly(_) => inline_fluent!("writing to {$allocation} which is read-only"), DerefFunctionPointer(_) => inline_fluent!("accessing {$allocation} which contains a function"), DerefVTablePointer(_) => inline_fluent!("accessing {$allocation} which contains a vtable"), @@ -936,9 +944,9 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { NullFnPtr { .. } => { inline_fluent!( "{$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null -} function pointer" + [true] maybe-null + *[false] null + } function pointer" ) } NeverVal => { @@ -1021,17 +1029,17 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { NullPtr { ptr_kind: PointerKind::Box, .. } => { inline_fluent!( "{$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null -} box" + [true] maybe-null + *[false] null + } box" ) } NullPtr { ptr_kind: PointerKind::Ref(_), .. } => { inline_fluent!( "{$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null -} reference" + [true] maybe-null + *[false] null + } reference" ) } DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 49038315b546e..c70038f5b18fb 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -466,10 +466,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // a < b if intrinsic_name == sym::ptr_offset_from_unsigned { throw_ub_custom!( - inline_fluent!("`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr -> - [true] address - *[false] offset -} than second: {$a_offset} < {$b_offset}"), + inline_fluent!( + "`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr -> + [true] address + *[false] offset + } than second: {$a_offset} < {$b_offset}" + ), a_offset = a_offset, b_offset = b_offset, is_addr = is_addr, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 28dae2ef3b8b7..200155ab010e1 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -293,10 +293,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub_custom!( inline_fluent!( "{$kind -> - [dealloc] deallocating - [realloc] reallocating - *[other] {\"\"} -} {$ptr} which does not point to the beginning of an object" + [dealloc] deallocating + [realloc] reallocating + *[other] {\"\"} + } {$ptr} which does not point to the beginning of an object" ), ptr = format!("{ptr:?}"), kind = "realloc" @@ -379,10 +379,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { throw_ub_custom!( inline_fluent!( "{$kind -> - [dealloc] deallocating - [realloc] reallocating - *[other] {\"\"} -} {$ptr} which does not point to the beginning of an object" + [dealloc] deallocating + [realloc] reallocating + *[other] {\"\"} + } {$ptr} which does not point to the beginning of an object" ), ptr = format!("{ptr:?}"), kind = "dealloc", @@ -396,11 +396,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "fn", @@ -410,11 +410,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "vtable", @@ -424,11 +424,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "typeid", @@ -438,11 +438,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { err_ub_custom!( inline_fluent!( "deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {\"\"} -}" + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" ), alloc_id = alloc_id, kind = "static_mem" diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index a56b5f5fdc7d3..594d6d294d75a 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -12,6 +12,7 @@ #![allow(rustc::potential_query_instability)] #![cfg_attr(bootstrap, feature(assert_matches))] #![cfg_attr(bootstrap, feature(cold_path))] +#![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] #![feature(allocator_api)] #![feature(ascii_char)] @@ -30,7 +31,6 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(sized_hierarchy)] -#![feature(test)] #![feature(thread_id_value)] #![feature(trusted_len)] #![feature(type_alias_impl_trait)] diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index c36afc6fc8897..ae3e33498ea19 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -60,11 +60,13 @@ impl Diagnostic<'_, G> for TargetDataLayoutErrors<'_> { .with_arg("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { - Diag::new(dcx, level, inline_fluent!("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {\"\"} - }")) + Diag::new(dcx, level, inline_fluent!( + "invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind -> + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" + )) .with_arg("cause", cause) .with_arg("err_kind", err.diag_ident()) .with_arg("align", err.align()) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index cfd4ae3795e14..1a95b7db60a70 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -14,8 +14,6 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] -#![feature(try_blocks)] -#![feature(yeet_expr)] // tidy-alphabetical-end extern crate self as rustc_errors; @@ -63,6 +61,7 @@ pub use rustc_error_messages::{ use rustc_hashes::Hash128; use rustc_lint_defs::LintExpectationId; pub use rustc_lint_defs::{Applicability, listify, pluralize}; +pub use rustc_macros::inline_fluent; use rustc_macros::{Decodable, Encodable}; pub use rustc_span::ErrorGuaranteed; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker, catch_fatal_errors}; @@ -1561,7 +1560,7 @@ impl DelayedDiagInner { let msg = match self.note.status() { BacktraceStatus::Captured => inline_fluent!( "delayed at {$emitted_at} -{$note}" + {$note}" ), // Avoid the needless newline when no backtrace has been captured, // the display impl should just be a single line. diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index b5de3f87e9f35..c6d30032f1af4 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -90,14 +90,3 @@ impl Translator { } } } - -/// This macro creates a translatable `DiagMessage` from a literal string. -/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired. -/// -/// This is a macro because in the future we may want to globally register these messages. -#[macro_export] -macro_rules! inline_fluent { - ($inline: literal) => { - rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed($inline)) - }; -} diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 91f98d475f00a..5efaea44b3b9d 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -919,7 +919,7 @@ impl SyntaxExtension { fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool { // FIXME(estebank): instead of reusing `#[rustc_diagnostic_item]` as a proxy, introduce a // new attribute purely for this under the `#[diagnostic]` namespace. - ast::attr::find_by_name(attrs, sym::rustc_diagnostic_item).is_some() + find_attr!(attrs, AttributeKind::RustcDiagnosticItem(..)) } /// Constructs a syntax extension with the given properties diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index d74e8442545b7..2c2dae0fef52e 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -862,13 +862,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ register_tool, CrateLevel, template!(List: &["tool1, tool2, ..."]), DuplicatesOk, EncodeCrossCrate::No, experimental!(register_tool), ), - - // lang-team MCP 147 - gated!( - deprecated_safe, Normal, template!(List: &[r#"since = "version", note = "...""#]), ErrorFollowing, - EncodeCrossCrate::Yes, experimental!(deprecated_safe), - ), - // `#[cfi_encoding = ""]` gated!( cfi_encoding, Normal, template!(NameValueStr: "encoding"), ErrorPreceding, diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 4f4691468911a..71a735cd8cc78 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -102,6 +102,8 @@ declare_features! ( /// Allows default type parameters to influence type inference. (removed, default_type_parameter_fallback, "1.82.0", Some(27336), Some("never properly implemented; requires significant design work"), 127655), + /// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait + (removed, deprecated_safe, "CURRENT_RUSTC_VERSION", Some(94978), Some("never properly implemented, in the way of attribute refactor"), 152554), /// Allows deriving traits as per `SmartPointer` specification (removed, derive_smart_pointer, "1.84.0", Some(123430), Some("replaced by `CoercePointee`"), 131284), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index add09c3ea58b0..082558cf9a93f 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -454,8 +454,6 @@ declare_features! ( /// Allows the use of default values on struct definitions and the construction of struct /// literals with the functional update syntax without a base. (unstable, default_field_values, "1.85.0", Some(132162)), - /// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait - (unstable, deprecated_safe, "1.61.0", Some(94978)), /// Allows having using `suggestion` in the `#[deprecated]` attribute. (unstable, deprecated_suggestion, "1.61.0", Some(94785)), /// Allows deref patterns. diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index e28ecd06b89bc..568d189becf7f 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1156,6 +1156,9 @@ pub enum AttributeKind { /// Represents `#[rustc_deprecated_safe_2024]` RustcDeprecatedSafe2024 { suggestion: Symbol }, + /// Represents `#[rustc_diagnostic_item]` + RustcDiagnosticItem(Symbol), + /// Represents `#[rustc_dummy]`. RustcDummy, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index b4cf244bfb8aa..3ee4785420fa2 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -113,6 +113,7 @@ impl AttributeKind { RustcDelayedBugFromInsideQuery => No, RustcDenyExplicitImpl(..) => No, RustcDeprecatedSafe2024 { .. } => Yes, + RustcDiagnosticItem(..) => Yes, RustcDummy => No, RustcDumpDefParents => No, RustcDumpItemBounds => No, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 03bbc9c0a7c9b..2fc1f1ab01d27 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1063,6 +1063,70 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>( ) } +/// Convert `ReLateParam`s in `value` back into `ReBound`s and bind it with `bound_vars`. +fn late_param_regions_to_bound<'tcx, T>( + tcx: TyCtxt<'tcx>, + scope: DefId, + bound_vars: &'tcx ty::List>, + value: T, +) -> ty::Binder<'tcx, T> +where + T: ty::TypeFoldable>, +{ + let value = fold_regions(tcx, value, |r, debruijn| match r.kind() { + ty::ReLateParam(lp) => { + // Should be in scope, otherwise inconsistency happens somewhere. + assert_eq!(lp.scope, scope); + + let br = match lp.kind { + // These variants preserve the bound var index. + kind @ (ty::LateParamRegionKind::Anon(idx) + | ty::LateParamRegionKind::NamedAnon(idx, _)) => { + let idx = idx as usize; + let var = ty::BoundVar::from_usize(idx); + + let Some(ty::BoundVariableKind::Region(kind)) = bound_vars.get(idx).copied() + else { + bug!("unexpected late-bound region {kind:?} for bound vars {bound_vars:?}"); + }; + + ty::BoundRegion { var, kind } + } + + // For named regions, look up the corresponding bound var. + ty::LateParamRegionKind::Named(def_id) => bound_vars + .iter() + .enumerate() + .find_map(|(idx, bv)| match bv { + ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::Named(did)) + if did == def_id => + { + Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind }) + } + _ => None, + }) + .unwrap(), + + ty::LateParamRegionKind::ClosureEnv => bound_vars + .iter() + .enumerate() + .find_map(|(idx, bv)| match bv { + ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::ClosureEnv) => { + Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind }) + } + _ => None, + }) + .unwrap(), + }; + + ty::Region::new_bound(tcx, debruijn, br) + } + _ => r, + }); + + ty::Binder::bind_with_vars(value, bound_vars) +} + fn recover_infer_ret_ty<'tcx>( icx: &ItemCtxt<'tcx>, infer_ret_ty: &'tcx hir::Ty<'tcx>, @@ -1138,13 +1202,22 @@ fn recover_infer_ret_ty<'tcx>( ); } let guar = diag.emit(); - ty::Binder::dummy(tcx.mk_fn_sig( + + // If we return a dummy binder here, we can ICE later in borrowck when it encounters + // `ReLateParam` regions (e.g. in a local type annotation) which weren't registered via the + // signature binder. See #135845. + let bound_vars = tcx.late_bound_vars(hir_id); + let scope = def_id.to_def_id(); + + let fn_sig = tcx.mk_fn_sig( fn_sig.inputs().iter().copied(), recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)), fn_sig.c_variadic, fn_sig.safety, fn_sig.abi, - )) + ); + + late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig) } pub fn suggest_impl_trait<'tcx>( 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 1578f098dd953..cc52487189270 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2465,7 +2465,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let parent_did = tcx.parent(*def_id); (tcx.adt_def(parent_did), fn_args, parent_did) } - _ => return non_adt_or_variant_res(), + _ => { + let e = self.dcx().span_err( + span, + "complex const arguments must be placed inside of a `const` block", + ); + return Const::new_error(tcx, e); + } }; let variant_def = adt_def.variant_with_id(variant_did); diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 7fb9deaa1697b..dc7fe03dcf3c6 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] -#![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] +#![cfg_attr(all(feature = "nightly", test), feature(test))] +#![cfg_attr(feature = "nightly", feature(extend_one, step_trait))] #![cfg_attr(feature = "nightly", feature(new_range_api))] // tidy-alphabetical-end diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 0874037199687..aef0021d06603 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -446,7 +446,7 @@ impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { "specifically, {$num_captured -> [one] this lifetime is *[other] these lifetimes are - } in scope but not mentioned in the type's bounds" + } in scope but not mentioned in the type's bounds" ), ) .note(inline_fluent!( diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index e290098238e93..8c6507f68231b 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -353,8 +353,10 @@ impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> { self.label, inline_fluent!("will not be checked at usage sites of the type alias"), ); - diag.note(inline_fluent!("this is a known limitation of the type checker that may be lifted in a future edition. - see issue #112792 for more information")); + diag.note(inline_fluent!( + "this is a known limitation of the type checker that may be lifted in a future edition. + see issue #112792 for more information" + )); if self.enable_feat_help { diag.help(inline_fluent!("add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics")); } @@ -1748,10 +1750,12 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { if doctest { diag.help(inline_fluent!(r#"remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`"#)); } else { - diag.help(inline_fluent!("remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth -> - [one] `{$body_name}` - *[other] `{$body_name}` and up {$depth} bodies - }")); + diag.help(inline_fluent!( + "remove the `#[macro_export]` or move this `macro_rules!` outside the of the current {$body_kind_descr} {$depth -> + [one] `{$body_name}` + *[other] `{$body_name}` and up {$depth} bodies + }" + )); } diag.note(inline_fluent!("a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute")); diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index daf62277693a9..10a37637400be 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -196,10 +196,12 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if let Some((open, close, del)) = find_delimiters(cx, span) { lint.arg("already_suggested", suggest_display || suggest_debug); lint.multipart_suggestion( - inline_fluent!("{$already_suggested -> - [true] or use - *[false] use - } std::panic::panic_any instead"), + inline_fluent!( + "{$already_suggested -> + [true] or use + *[false] use + } std::panic::panic_any instead" + ), if del == '(' { vec![(span.until(open), "std::panic::panic_any".into())] } else { diff --git a/compiler/rustc_macros/src/diagnostics/inline_fluent.rs b/compiler/rustc_macros/src/diagnostics/inline_fluent.rs new file mode 100644 index 0000000000000..ab0ed6aa6e0e8 --- /dev/null +++ b/compiler/rustc_macros/src/diagnostics/inline_fluent.rs @@ -0,0 +1,10 @@ +use syn::{LitStr, parse_macro_input}; + +use crate::diagnostics::message::Message; + +pub(crate) fn inline_fluent(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let inline = parse_macro_input!(input as LitStr); + let message = + Message { attr_span: inline.span(), message_span: inline.span(), value: inline.value() }; + message.diag_message(None).into() +} diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index a036e61c37898..aef062a3d5504 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -1,11 +1,13 @@ mod diagnostic; mod diagnostic_builder; mod error; +mod inline_fluent; mod message; mod subdiagnostic; mod utils; use diagnostic::{DiagnosticDerive, LintDiagnosticDerive}; +pub(super) use inline_fluent::inline_fluent; use proc_macro2::TokenStream; use subdiagnostic::SubdiagnosticDerive; use synstructure::Structure; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 8cd6c02644481..29551e5af6b68 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![allow(rustc::default_hash_types)] -#![feature(if_let_guard)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_tracked_env)] @@ -241,6 +240,15 @@ decl_derive!( applicability)] => diagnostics::subdiagnostic_derive ); +/// This macro creates a translatable `DiagMessage` from a fluent format string. +/// It should be used in places where a translatable message is needed, but struct diagnostics are undesired. +/// +/// This macro statically checks that the message is valid Fluent, but not that variables in the Fluent message actually exist. +#[proc_macro] +pub fn inline_fluent(input: TokenStream) -> TokenStream { + diagnostics::inline_fluent(input) +} + decl_derive! { [PrintAttribute] => /// Derives `PrintAttribute` for `AttributeKind`. diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 22c8a0c4cd7ee..73a97a67bc907 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -1,6 +1,5 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![feature(decl_macro)] #![feature(error_iter)] #![feature(file_buffered)] #![feature(gen_blocks)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 2095327ea1b59..f0c85fec4ea6e 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -28,6 +28,7 @@ #![allow(internal_features)] #![allow(rustc::direct_use_of_rustc_type_ir)] #![cfg_attr(bootstrap, feature(assert_matches))] +#![cfg_attr(doc, feature(intra_doc_pointers))] #![feature(allocator_api)] #![feature(associated_type_defaults)] #![feature(box_as_ptr)] @@ -43,7 +44,6 @@ #![feature(file_buffered)] #![feature(gen_blocks)] #![feature(if_let_guard)] -#![feature(intra_doc_pointers)] #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] @@ -56,7 +56,6 @@ #![feature(try_trait_v2_residual)] #![feature(try_trait_v2_yeet)] #![feature(type_alias_impl_trait)] -#![feature(unwrap_infallible)] #![feature(yeet_expr)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index fce0158aa5111..903ef645207dd 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -128,19 +128,25 @@ pub struct Deprecated { impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated { fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) { diag.primary_message(match &self.since_kind { - DeprecatedSinceKind::InEffect => inline_fluent!("use of deprecated {$kind} `{$path}`{$has_note -> - [true] : {$note} - *[other] {\"\"} - }"), - DeprecatedSinceKind::InFuture => inline_fluent!("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note -> - [true] : {$note} - *[other] {\"\"} - }"), - DeprecatedSinceKind::InVersion(_) => { - inline_fluent!("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note -> + DeprecatedSinceKind::InEffect => inline_fluent!( + "use of deprecated {$kind} `{$path}`{$has_note -> + [true] : {$note} + *[other] {\"\"} + }" + ), + DeprecatedSinceKind::InFuture => inline_fluent!( + "use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note -> [true] : {$note} *[other] {\"\"} - }") + }" + ), + DeprecatedSinceKind::InVersion(_) => { + inline_fluent!( + "use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note -> + [true] : {$note} + *[other] {\"\"} + }" + ) } }); diag.arg("kind", self.kind); diff --git a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs index 789398c588808..448ed78702b70 100644 --- a/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs +++ b/compiler/rustc_mir_transform/src/lint_tail_expr_drop_order.rs @@ -542,10 +542,12 @@ impl Subdiagnostic for LocalLabel<'_> { dtor.add_to_diag(diag); } let msg = - diag.eagerly_translate(inline_fluent!("{$is_dropped_first_edition_2024 -> - [true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024 - *[false] `{$name}` will be dropped later as of Edition 2024 - }")); + diag.eagerly_translate(inline_fluent!( + "{$is_dropped_first_edition_2024 -> + [true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024 + *[false] `{$name}` will be dropped later as of Edition 2024 + }" + )); diag.span_label(self.span, msg); } } diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 014ccdc45ef88..31506ae38fa0b 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -2,12 +2,12 @@ // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(assert_matches))] +#![cfg_attr(test, feature(iter_order_by))] #![feature(box_patterns)] #![feature(debug_closure_helpers)] #![feature(default_field_values)] #![feature(if_let_guard)] #![feature(iter_intersperse)] -#![feature(iter_order_by)] #![recursion_limit = "256"] // tidy-alphabetical-end diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 08f2597e874d8..2d76363464a77 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -308,6 +308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDelayedBugFromInsideQuery | AttributeKind::RustcDenyExplicitImpl(..) | AttributeKind::RustcDeprecatedSafe2024 {..} + | AttributeKind::RustcDiagnosticItem(..) | AttributeKind::RustcDummy | AttributeKind::RustcDumpDefParents | AttributeKind::RustcDumpItemBounds @@ -392,13 +393,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::warn | sym::deny | sym::forbid - // need to be fixed - | sym::deprecated_safe // FIXME(deprecated_safe) // internal | sym::panic_handler | sym::lang | sym::default_lib_allocator - | sym::rustc_diagnostic_item | sym::rustc_nonnull_optimization_guaranteed | sym::rustc_inherit_overflow_checks | sym::rustc_on_unimplemented diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 8f572af02c249..c7b1dcb95e336 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -9,20 +9,21 @@ //! //! * Compiler internal types like `Ty` and `TyCtxt` +use rustc_hir::attrs::AttributeKind; use rustc_hir::diagnostic_items::DiagnosticItems; -use rustc_hir::{Attribute, CRATE_OWNER_ID, OwnerId}; +use rustc_hir::{CRATE_OWNER_ID, OwnerId, find_attr}; use rustc_middle::query::{LocalCrate, Providers}; use rustc_middle::ty::TyCtxt; +use rustc_span::Symbol; use rustc_span::def_id::{DefId, LOCAL_CRATE}; -use rustc_span::{Symbol, sym}; use crate::errors::DuplicateDiagnosticItemInCrate; fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) { let attrs = tcx.hir_attrs(owner.into()); - if let Some(name) = extract(attrs) { + if let Some(name) = find_attr!(attrs, AttributeKind::RustcDiagnosticItem(name) => name) { // insert into our table - collect_item(tcx, diagnostic_items, name, owner.to_def_id()); + collect_item(tcx, diagnostic_items, *name, owner.to_def_id()); } } @@ -53,13 +54,6 @@ fn report_duplicate_item( }); } -/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes. -fn extract(attrs: &[Attribute]) -> Option { - attrs.iter().find_map(|attr| { - if attr.has_name(sym::rustc_diagnostic_item) { attr.value_str() } else { None } - }) -} - /// Traverse and collect the diagnostic items in the current fn diagnostic_items(tcx: TyCtxt<'_>, _: LocalCrate) -> DiagnosticItems { // Initialize the collector. diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f420bba9b4e9c..8a70302c4c4e8 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -684,9 +684,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NoMainErr { // There were some functions named `main` though. Try to give the user a hint. inline_fluent!( "the main function must be defined at the crate level{$has_filename -> - [true] {\" \"}(in `{$filename}`) - *[false] {\"\"} - }" + [true] {\" \"}(in `{$filename}`) + *[false] {\"\"} + }" ) } else if self.has_filename { inline_fluent!("consider adding a `main` function to `{$filename}`") diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index ef6a8e80c72f2..dea57cf4eba51 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -4,11 +4,6 @@ //! //! This API is completely unstable and subject to change. -// tidy-alphabetical-start -#![feature(if_let_guard)] -#![feature(map_try_insert)] -// tidy-alphabetical-end - use rustc_middle::query::Providers; pub mod abi_test; diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index 9ffc237c63290..059bf47c579c8 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -4,7 +4,6 @@ // tidy-alphabetical-start #![allow(unused_crate_dependencies)] -#![cfg_attr(feature = "rustc", feature(if_let_guard))] // tidy-alphabetical-end pub(crate) mod checks; diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index 025ec0e7a8c85..dd5a3601b3232 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -14,7 +14,6 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_ty_tykind)] #![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] -#![feature(sized_hierarchy)] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_query_impl/src/dep_kind_vtables.rs b/compiler/rustc_query_impl/src/dep_kind_vtables.rs new file mode 100644 index 0000000000000..92fd9c6734d04 --- /dev/null +++ b/compiler/rustc_query_impl/src/dep_kind_vtables.rs @@ -0,0 +1,174 @@ +use rustc_middle::bug; +use rustc_middle::dep_graph::DepKindVTable; +use rustc_middle::ty::TyCtxt; +use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle}; +use rustc_query_system::query::QueryCache; + +use crate::plumbing::{force_from_dep_node_inner, try_load_from_on_disk_cache_inner}; +use crate::{QueryCtxt, QueryDispatcherUnerased, QueryFlags}; + +/// [`DepKindVTable`] constructors for special dep kinds that aren't queries. +#[expect(non_snake_case, reason = "use non-snake case to avoid collision with query names")] +mod non_query { + use super::*; + + // We use this for most things when incr. comp. is turned off. + pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|_, dep_node, _| { + bug!("force_from_dep_node: encountered {dep_node:?}") + }), + try_load_from_on_disk_cache: None, + name: &"Null", + } + } + + // We use this for the forever-red node. + pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|_, dep_node, _| { + bug!("force_from_dep_node: encountered {dep_node:?}") + }), + try_load_from_on_disk_cache: None, + name: &"Red", + } + } + + pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: Some(|tcx, _, prev_index| { + tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index); + true + }), + try_load_from_on_disk_cache: None, + name: &"SideEffect", + } + } + + pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: true, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Opaque, + force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")), + try_load_from_on_disk_cache: None, + name: &"AnonZeroDeps", + } + } + + pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: true, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"TraitSelect", + } + } + + pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Opaque, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"CompileCodegenUnit", + } + } + + pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Opaque, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"CompileMonoItem", + } + } + + pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> { + DepKindVTable { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"Metadata", + } + } +} + +/// Shared implementation of the [`DepKindVTable`] constructor for queries. +/// Called from macro-generated code for each query. +pub(crate) fn make_dep_kind_vtable_for_query<'tcx, Q, Cache, const FLAGS: QueryFlags>( + is_eval_always: bool, +) -> DepKindVTable<'tcx> +where + Q: QueryDispatcherUnerased<'tcx, Cache, FLAGS>, + Cache: QueryCache + 'tcx, +{ + let is_anon = FLAGS.is_anon; + let fingerprint_style = if is_anon { + FingerprintStyle::Opaque + } else { + >>::fingerprint_style() + }; + + if is_anon || !fingerprint_style.reconstructible() { + return DepKindVTable { + is_anon, + is_eval_always, + fingerprint_style, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: Q::NAME, + }; + } + + DepKindVTable { + is_anon, + is_eval_always, + fingerprint_style, + force_from_dep_node: Some(|tcx, dep_node, _| { + force_from_dep_node_inner(Q::query_dispatcher(tcx), tcx, dep_node) + }), + try_load_from_on_disk_cache: Some(|tcx, dep_node| { + try_load_from_on_disk_cache_inner(Q::query_dispatcher(tcx), tcx, dep_node) + }), + name: Q::NAME, + } +} + +/// Helper module containing a [`DepKindVTable`] constructor for each dep kind, +/// for use with [`rustc_middle::make_dep_kind_array`]. +/// +/// That macro will check that we gave it a constructor for every known dep kind. +mod _dep_kind_vtable_ctors { + // Re-export all of the vtable constructors for non-query and query dep kinds. + + // Non-query vtable constructors are defined in normal code. + pub(crate) use super::non_query::*; + // Query vtable constructors are defined via a macro. + pub(crate) use crate::_dep_kind_vtable_ctors_for_queries::*; +} + +pub fn make_dep_kind_vtables<'tcx>( + arena: &'tcx rustc_middle::arena::Arena<'tcx>, +) -> &'tcx [DepKindVTable<'tcx>] { + // Create an array of vtables, one for each dep kind (non-query and query). + let dep_kind_vtables: [DepKindVTable<'tcx>; _] = + rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors); + arena.alloc_from_iter(dep_kind_vtables) +} diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 9b2078275aae5..feeb072f027af 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -12,8 +12,7 @@ use std::marker::ConstParamTy; use rustc_data_structures::sync::AtomicU64; -use rustc_middle::arena::Arena; -use rustc_middle::dep_graph::{self, DepKind, DepKindVTable, DepNode, DepNodeIndex}; +use rustc_middle::dep_graph::{self, DepKind, DepNode, DepNodeIndex}; use rustc_middle::queries::{ self, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; @@ -27,6 +26,7 @@ use rustc_query_system::query::{ }; use rustc_span::{ErrorGuaranteed, Span}; +pub use crate::dep_kind_vtables::make_dep_kind_vtables; pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack}; pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all}; use crate::plumbing::{encode_all_query_results, try_mark_green}; @@ -34,11 +34,13 @@ use crate::profiling_support::QueryKeyStringCache; pub use crate::profiling_support::alloc_self_profile_query_strings; use crate::values::Value; +#[macro_use] +mod plumbing; + +mod dep_kind_vtables; mod error; mod execution; mod job; -#[macro_use] -mod plumbing; mod profiling_support; mod values; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 9804e6b217567..12cef31f58bb2 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -13,9 +13,10 @@ use rustc_hir::def_id::DefId; use rustc_hir::limit::Limit; use rustc_index::Idx; use rustc_middle::bug; +#[expect(unused_imports, reason = "used by doc comments")] +use rustc_middle::dep_graph::DepKindVTable; use rustc_middle::dep_graph::{ - self, DepContext, DepKindVTable, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex, - dep_kinds, + self, DepContext, DepNode, DepNodeIndex, DepsType, SerializedDepNodeIndex, dep_kinds, }; use rustc_middle::query::Key; use rustc_middle::query::on_disk_cache::{ @@ -26,7 +27,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::print::with_reduced_queries; use rustc_middle::ty::tls::{self, ImplicitCtxt}; use rustc_middle::ty::{self, TyCtxt}; -use rustc_query_system::dep_graph::{DepNodeKey, FingerprintStyle, HasDepContext}; +use rustc_query_system::dep_graph::{DepNodeKey, HasDepContext}; use rustc_query_system::query::{ QueryCache, QueryContext, QueryJobId, QuerySideEffect, QueryStackDeferred, QueryStackFrame, QueryStackFrameExtra, @@ -447,7 +448,8 @@ pub(crate) fn query_key_hash_verify<'tcx, C: QueryCache, const FLAGS: QueryFlags }); } -fn try_load_from_on_disk_cache<'tcx, C: QueryCache, const FLAGS: QueryFlags>( +/// Implementation of [`DepKindVTable::try_load_from_on_disk_cache`] for queries. +pub(crate) fn try_load_from_on_disk_cache_inner<'tcx, C: QueryCache, const FLAGS: QueryFlags>( query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, tcx: TyCtxt<'tcx>, dep_node: DepNode, @@ -496,7 +498,8 @@ where value } -fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>( +/// Implementation of [`DepKindVTable::force_from_dep_node`] for queries. +pub(crate) fn force_from_dep_node_inner<'tcx, C: QueryCache, const FLAGS: QueryFlags>( query: SemiDynamicQueryDispatcher<'tcx, C, FLAGS>, tcx: TyCtxt<'tcx>, dep_node: DepNode, @@ -527,49 +530,6 @@ fn force_from_dep_node<'tcx, C: QueryCache, const FLAGS: QueryFlags>( } } -pub(crate) fn make_dep_kind_vtable_for_query< - 'tcx, - Q, - C: QueryCache + 'tcx, - const FLAGS: QueryFlags, ->( - is_eval_always: bool, -) -> DepKindVTable<'tcx> -where - Q: QueryDispatcherUnerased<'tcx, C, FLAGS>, -{ - let is_anon = FLAGS.is_anon; - let fingerprint_style = if is_anon { - FingerprintStyle::Opaque - } else { - >>::fingerprint_style() - }; - - if is_anon || !fingerprint_style.reconstructible() { - return DepKindVTable { - is_anon, - is_eval_always, - fingerprint_style, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: Q::NAME, - }; - } - - DepKindVTable { - is_anon, - is_eval_always, - fingerprint_style, - force_from_dep_node: Some(|tcx, dep_node, _| { - force_from_dep_node(Q::query_dispatcher(tcx), tcx, dep_node) - }), - try_load_from_on_disk_cache: Some(|tcx, dep_node| { - try_load_from_on_disk_cache(Q::query_dispatcher(tcx), tcx, dep_node) - }), - name: Q::NAME, - } -} - // NOTE: `$V` isn't used here, but we still need to match on it so it can be passed to other macros // invoked by `rustc_with_all_queries`. macro_rules! define_queries { @@ -882,119 +842,20 @@ macro_rules! define_queries { for<'tcx> fn(TyCtxt<'tcx>) ] = &[$(query_impl::$name::query_key_hash_verify),*]; - /// Module containing a named function for each dep kind (including queries) - /// that creates a `DepKindVTable`. - /// - /// Consumed via `make_dep_kind_array!` to create a list of vtables. - #[expect(non_snake_case)] - mod _dep_kind_vtable_ctors { - use super::*; - use rustc_middle::bug; - use rustc_query_system::dep_graph::FingerprintStyle; - - // We use this for most things when incr. comp. is turned off. - pub(crate) fn Null<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)), - try_load_from_on_disk_cache: None, - name: &"Null", - } - } - - // We use this for the forever-red node. - pub(crate) fn Red<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)), - try_load_from_on_disk_cache: None, - name: &"Red", - } - } + /// Declares a dep-kind vtable constructor for each query. + mod _dep_kind_vtable_ctors_for_queries { + use ::rustc_middle::dep_graph::DepKindVTable; + use $crate::dep_kind_vtables::make_dep_kind_vtable_for_query; - pub(crate) fn SideEffect<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: Some(|tcx, _, prev_index| { - tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index); - true - }), - try_load_from_on_disk_cache: None, - name: &"SideEffect", - } - } - - pub(crate) fn AnonZeroDeps<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: true, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Opaque, - force_from_dep_node: Some(|_, _, _| bug!("cannot force an anon node")), - try_load_from_on_disk_cache: None, - name: &"AnonZeroDeps", - } - } - - pub(crate) fn TraitSelect<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: true, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"TraitSelect", - } - } - - pub(crate) fn CompileCodegenUnit<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Opaque, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"CompileCodegenUnit", - } - } - - pub(crate) fn CompileMonoItem<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Opaque, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"CompileMonoItem", - } - } - - pub(crate) fn Metadata<'tcx>() -> DepKindVTable<'tcx> { - DepKindVTable { - is_anon: false, - is_eval_always: false, - fingerprint_style: FingerprintStyle::Unit, - force_from_dep_node: None, - try_load_from_on_disk_cache: None, - name: &"Metadata", + $( + /// `DepKindVTable` constructor for this query. + pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { + use $crate::query_impl::$name::QueryType; + make_dep_kind_vtable_for_query::, _, _>( + is_eval_always!([$($modifiers)*]), + ) } - } - - $(pub(crate) fn $name<'tcx>() -> DepKindVTable<'tcx> { - use $crate::query_impl::$name::QueryType; - $crate::plumbing::make_dep_kind_vtable_for_query::, _, _>( - is_eval_always!([$($modifiers)*]), - ) - })* - } - - pub fn make_dep_kind_vtables<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindVTable<'tcx>] { - arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(_dep_kind_vtable_ctors)) + )* } } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9a88f74b5b179..ac6188c2c1523 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1425,14 +1425,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // a note about editions let note = if let Some(did) = did { let requires_note = !did.is_local() - && this.tcx.get_attrs(did, sym::rustc_diagnostic_item).any( - |attr| { - [sym::TryInto, sym::TryFrom, sym::FromIterator] - .map(|x| Some(x)) - .contains(&attr.value_str()) - }, + && find_attr!( + this.tcx.get_all_attrs(did), + AttributeKind::RustcDiagnosticItem( + sym::TryInto | sym::TryFrom | sym::FromIterator + ) ); - requires_note.then(|| { format!( "'{}' is included in the prelude starting in Edition 2021", diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 95f0d3e67ef2d..ec577a1aea83f 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -21,7 +21,7 @@ use rustc_hir::attrs::AttributeKind; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, MacroKinds}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; -use rustc_hir::{MissingLifetimeKind, PrimTy}; +use rustc_hir::{MissingLifetimeKind, PrimTy, find_attr}; use rustc_middle::ty; use rustc_session::{Session, lint}; use rustc_span::edit_distance::{edit_distance, find_best_match_for_name}; @@ -2446,10 +2446,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .iter() .filter_map(|candidate| candidate.did) .find(|did| { - self.r - .tcx - .get_attrs(*did, sym::rustc_diagnostic_item) - .any(|attr| attr.value_str() == Some(sym::Default)) + find_attr!( + self.r.tcx.get_all_attrs(*did), + AttributeKind::RustcDiagnosticItem(sym::Default) + ) }); let Some(default_trait) = default_trait else { return; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 1399f9933ad4e..fc863c84f0990 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -15,7 +15,6 @@ #![feature(const_default)] #![feature(const_trait_impl)] #![feature(control_flow_into_value)] -#![feature(decl_macro)] #![feature(default_field_values)] #![feature(if_let_guard)] #![feature(iter_intersperse)] diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 842068a4fc046..f4c7e5519536b 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -3,7 +3,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::internal)] -#![cfg_attr(test, feature(test))] #![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] #![feature(core_intrinsics)] #![feature(min_specialization)] diff --git a/compiler/rustc_thread_pool/src/sleep/README.md b/compiler/rustc_thread_pool/src/sleep/README.md index 1e11da55f4a4e..948c2922a4340 100644 --- a/compiler/rustc_thread_pool/src/sleep/README.md +++ b/compiler/rustc_thread_pool/src/sleep/README.md @@ -32,7 +32,7 @@ There are three main thread states: waiting to be awoken. We sometimes refer to the final two states collectively as **inactive**. -Threads begin as idle but transition to idle and finally sleeping when +Threads begin as active but transition to idle and finally sleeping when they're unable to find work to do. ## Sleepy threads @@ -160,7 +160,7 @@ not complete. It is possible -- if unlikely -- that enough activity occurs for Thread A to observe the same JEC value that it saw when getting sleepy. If the new work being published came from *inside* the thread-pool, then this race condition isn't too harmful. It means that we have fewer workers processing the -work then we should, but we won't deadlock. This seems like an acceptable risk +work than we should, but we won't deadlock. This seems like an acceptable risk given that this is unlikely in practice. However, if the work was posted as an *external* job, that is a problem. In that diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 81cca3dd67ac6..2ba2254c274e0 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -252,10 +252,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { SubregionOrigin::RelateParamBound(span, ty, opt_span) => { RegionOriginNote::WithName { span, - msg: inline_fluent!("...so that the type `{$name}` will meet its required lifetime bounds{$continues -> -[true] ... -*[false] {\"\"} -}"), + msg: inline_fluent!( + "...so that the type `{$name}` will meet its required lifetime bounds{$continues -> + [true] ... + *[false] {\"\"} + }" + ), name: &self.ty_to_string(ty), continues: opt_span.is_some(), } diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 0b19a470b726e..03364e412f002 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -102,10 +102,16 @@ pub struct NegativePositiveConflict<'tcx> { impl Diagnostic<'_, G> for NegativePositiveConflict<'_> { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, inline_fluent!("found both positive and negative implementation of trait `{$trait_desc}`{$self_desc -> -[none] {\"\"} -*[default] {\" \"}for type `{$self_desc}` -}:")); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!( + "found both positive and negative implementation of trait `{$trait_desc}`{$self_desc -> + [none] {\"\"} + *[default] {\" \"}for type `{$self_desc}` + }:" + ), + ); diag.arg("trait_desc", self.trait_desc.print_only_trait_path().to_string()); diag.arg("self_desc", self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string())); diag.span(self.impl_span); @@ -157,9 +163,9 @@ impl Subdiagnostic for AdjustSignatureBorrow { diag.multipart_suggestion_verbose( inline_fluent!( "consider adjusting the signature so it borrows its {$borrow_len -> -[one] argument -*[other] arguments -}" + [one] argument + *[other] arguments + }" ), to_borrow, Applicability::MaybeIncorrect, @@ -170,9 +176,9 @@ impl Subdiagnostic for AdjustSignatureBorrow { diag.multipart_suggestion_verbose( inline_fluent!( "consider adjusting the signature so it does not borrow its {$remove_borrow_len -> -[one] argument -*[other] arguments -}" + [one] argument + *[other] arguments + }" ), remove_borrow, Applicability::MaybeIncorrect, @@ -505,18 +511,18 @@ impl Subdiagnostic for RegionOriginNote<'_> { span, inline_fluent!( "...so that the {$requirement -> -[method_compat] method type is compatible with trait -[type_compat] associated type is compatible with trait -[const_compat] const is compatible with trait -[expr_assignable] expression is assignable -[if_else_different] `if` and `else` have incompatible types -[no_else] `if` missing an `else` returns `()` -[fn_main_correct_type] `main` function has the correct type -[fn_lang_correct_type] lang item function has the correct type -[intrinsic_correct_type] intrinsic has the correct type -[method_correct_type] method receiver has the correct type -*[other] types are compatible -}" + [method_compat] method type is compatible with trait + [type_compat] associated type is compatible with trait + [const_compat] const is compatible with trait + [expr_assignable] expression is assignable + [if_else_different] `if` and `else` have incompatible types + [no_else] `if` missing an `else` returns `()` + [fn_main_correct_type] `main` function has the correct type + [fn_lang_correct_type] lang item function has the correct type + [intrinsic_correct_type] intrinsic has the correct type + [method_correct_type] method receiver has the correct type + *[other] types are compatible + }" ), ); diag.arg("requirement", requirement); @@ -531,18 +537,18 @@ impl Subdiagnostic for RegionOriginNote<'_> { span, inline_fluent!( "...so that {$requirement -> -[method_compat] method type is compatible with trait -[type_compat] associated type is compatible with trait -[const_compat] const is compatible with trait -[expr_assignable] expression is assignable -[if_else_different] `if` and `else` have incompatible types -[no_else] `if` missing an `else` returns `()` -[fn_main_correct_type] `main` function has the correct type -[fn_lang_correct_type] lang item function has the correct type -[intrinsic_correct_type] intrinsic has the correct type -[method_correct_type] method receiver has the correct type -*[other] types are compatible -}" + [method_compat] method type is compatible with trait + [type_compat] associated type is compatible with trait + [const_compat] const is compatible with trait + [expr_assignable] expression is assignable + [if_else_different] `if` and `else` have incompatible types + [no_else] `if` missing an `else` returns `()` + [fn_main_correct_type] `main` function has the correct type + [fn_lang_correct_type] lang item function has the correct type + [intrinsic_correct_type] intrinsic has the correct type + [method_correct_type] method receiver has the correct type + *[other] types are compatible + }" ), ); diag.arg("requirement", requirement); @@ -578,9 +584,9 @@ impl Subdiagnostic for LifetimeMismatchLabels { span, inline_fluent!( "...but data{$label_var1_exists -> -[true] {\" \"}from `{$label_var1}` -*[false] {\"\"} -} is returned here" + [true] {\" \"}from `{$label_var1}` + *[false] {\"\"} + } is returned here" ), ); diag.arg("label_var1_exists", label_var1.is_some()); @@ -614,12 +620,12 @@ impl Subdiagnostic for LifetimeMismatchLabels { span, inline_fluent!( "...but data{$label_var1_exists -> -[true] {\" \"}from `{$label_var1}` -*[false] {\"\"} -} flows{$label_var2_exists -> -[true] {\" \"}into `{$label_var2}` -*[false] {\"\"} -} here" + [true] {\" \"}from `{$label_var1}` + *[false] {\"\"} + } flows{$label_var2_exists -> + [true] {\" \"}into `{$label_var2}` + *[false] {\"\"} + } here" ), ); diag.arg("label_var1_exists", label_var1.is_some()); @@ -789,12 +795,12 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> { diag.multipart_suggestion_verbose( inline_fluent!( "consider {$is_reuse -> -[true] reusing -*[false] introducing -} a named lifetime parameter{$is_impl -> -[true] {\" \"}and update trait if needed -*[false] {\"\"} -}" + [true] reusing + *[false] introducing + } a named lifetime parameter{$is_impl -> + [true] {\" \"}and update trait if needed + *[false] {\"\"} + }" ), visitor.suggestions, Applicability::MaybeIncorrect, diff --git a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs index 8e86b8fae1577..6a7e1d2528060 100644 --- a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs @@ -171,37 +171,37 @@ impl Subdiagnostic for RegionExplanation<'_> { let msg = diag.eagerly_translate(inline_fluent!( "{$pref_kind -> -*[should_not_happen] [{$pref_kind}] -[ref_valid_for] ...the reference is valid for -[content_valid_for] ...but the borrowed content is only valid for -[type_obj_valid_for] object type is valid for -[source_pointer_valid_for] source pointer is only valid for -[type_satisfy] type must satisfy -[type_outlive] type must outlive -[lf_param_instantiated_with] lifetime parameter instantiated with -[lf_param_must_outlive] but lifetime parameter must outlive -[lf_instantiated_with] lifetime instantiated with -[lf_must_outlive] but lifetime must outlive -[pointer_valid_for] the pointer is valid for -[data_valid_for] but the referenced data is only valid for -[empty] {\"\"} -}{$pref_kind -> -[empty] {\"\"} -*[other] {\" \"} -}{$desc_kind -> -*[should_not_happen] [{$desc_kind}] -[restatic] the static lifetime -[revar] lifetime {$desc_arg} -[as_defined] the lifetime `{$desc_arg}` as defined here -[as_defined_anon] the anonymous lifetime as defined here -[defined_here] the anonymous lifetime defined here -[defined_here_reg] the lifetime `{$desc_arg}` as defined here -}{$suff_kind -> -*[should_not_happen] [{$suff_kind}] -[empty]{\"\"} -[continues] ... -[req_by_binding] {\" \"}as required by this binding -}" + *[should_not_happen] [{$pref_kind}] + [ref_valid_for] ...the reference is valid for + [content_valid_for] ...but the borrowed content is only valid for + [type_obj_valid_for] object type is valid for + [source_pointer_valid_for] source pointer is only valid for + [type_satisfy] type must satisfy + [type_outlive] type must outlive + [lf_param_instantiated_with] lifetime parameter instantiated with + [lf_param_must_outlive] but lifetime parameter must outlive + [lf_instantiated_with] lifetime instantiated with + [lf_must_outlive] but lifetime must outlive + [pointer_valid_for] the pointer is valid for + [data_valid_for] but the referenced data is only valid for + [empty] {\"\"} + }{$pref_kind -> + [empty] {\"\"} + *[other] {\" \"} + }{$desc_kind -> + *[should_not_happen] [{$desc_kind}] + [restatic] the static lifetime + [revar] lifetime {$desc_arg} + [as_defined] the lifetime `{$desc_arg}` as defined here + [as_defined_anon] the anonymous lifetime as defined here + [defined_here] the anonymous lifetime defined here + [defined_here_reg] the lifetime `{$desc_arg}` as defined here + }{$suff_kind -> + *[should_not_happen] [{$suff_kind}] + [empty]{\"\"} + [continues] ... + [req_by_binding] {\" \"}as required by this binding + }" )); diag.restore_args(); if let Some(span) = self.desc.span { diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index bd48068eb579f..825c06883a546 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -430,7 +430,16 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( } }; - prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap() + prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap_or_else(|| { + // This can happen if the trait hierarchy is malformed (e.g., due to + // missing generics on a supertrait bound). There should already be an error + // emitted for this, so we just delay the ICE. + tcx.dcx().delayed_bug(format!( + "could not find the supertrait vtable slot for `{}` -> `{}`", + source, target + )); + None + }) } pub(super) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index dc286ee7f625c..3d9fc7f5c998d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -5,10 +5,7 @@ #![allow(rustc::usage_of_type_ir_inherent)] #![allow(rustc::usage_of_type_ir_traits)] #![cfg_attr(feature = "nightly", allow(internal_features))] -#![cfg_attr( - feature = "nightly", - feature(associated_type_defaults, never_type, rustc_attrs, negative_impls) -)] +#![cfg_attr(feature = "nightly", feature(associated_type_defaults, rustc_attrs, negative_impls))] // tidy-alphabetical-end extern crate self as rustc_type_ir; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 0844239826bf5..6391a6977b61a 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1514,7 +1514,7 @@ impl Box { /// Recreate a `Box` which was previously converted to a `NonNull` pointer /// using [`Box::into_non_null_with_allocator`]: /// ``` - /// #![feature(allocator_api, box_vec_non_null)] + /// #![feature(allocator_api)] /// /// use std::alloc::System; /// @@ -1524,7 +1524,7 @@ impl Box { /// ``` /// Manually create a `Box` from scratch by using the system allocator: /// ``` - /// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)] + /// #![feature(allocator_api)] /// /// use std::alloc::{Allocator, Layout, System}; /// @@ -1629,7 +1629,7 @@ impl Box { /// Converting the `NonNull` pointer back into a `Box` with /// [`Box::from_non_null_in`] for automatic cleanup: /// ``` - /// #![feature(allocator_api, box_vec_non_null)] + /// #![feature(allocator_api)] /// /// use std::alloc::System; /// @@ -1640,7 +1640,7 @@ impl Box { /// Manual cleanup by explicitly running the destructor and deallocating /// the memory: /// ``` - /// #![feature(allocator_api, box_vec_non_null)] + /// #![feature(allocator_api)] /// /// use std::alloc::{Allocator, Layout, System}; /// diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 0e0c2fcd8b996..3d94554281d44 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -56,6 +56,7 @@ //! [`Rc`]: rc //! [`RefCell`]: core::cell +#![allow(unused_features)] #![allow(incomplete_features)] #![allow(unused_attributes)] #![stable(feature = "alloc", since = "1.36.0")] @@ -85,13 +86,11 @@ // // Library features: // tidy-alphabetical-start -#![cfg_attr(not(no_global_oom_handling), feature(string_replace_in_place))] #![feature(allocator_api)] #![feature(array_into_iter_constructors)] #![feature(ascii_char)] #![feature(async_fn_traits)] #![feature(async_iterator)] -#![feature(box_vec_non_null)] #![feature(bstr)] #![feature(bstr_internals)] #![feature(cast_maybe_uninit)] @@ -148,7 +147,6 @@ #![feature(slice_ptr_get)] #![feature(slice_range)] #![feature(std_internals)] -#![feature(str_internals)] #![feature(temporary_niche_types)] #![feature(transmutability)] #![feature(trivial_clone)] @@ -158,7 +156,6 @@ #![feature(try_blocks)] #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -#![feature(try_with_capacity)] #![feature(tuple_trait)] #![feature(ub_checks)] #![feature(unicode_internals)] @@ -176,10 +173,8 @@ #![feature(const_trait_impl)] #![feature(coroutine_trait)] #![feature(decl_macro)] -#![feature(derive_const)] #![feature(dropck_eyepatch)] #![feature(fundamental)] -#![feature(hashmap_internals)] #![feature(intrinsics)] #![feature(lang_items)] #![feature(min_specialization)] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 6cbe89d9da4f2..11a498d09d3fb 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1238,7 +1238,7 @@ impl Vec { /// # Examples /// /// ``` - /// #![feature(allocator_api, box_vec_non_null)] + /// #![feature(allocator_api)] /// /// use std::alloc::System; /// @@ -1265,7 +1265,7 @@ impl Vec { /// Using memory that was allocated elsewhere: /// /// ```rust - /// #![feature(allocator_api, box_vec_non_null)] + /// #![feature(allocator_api)] /// /// use std::alloc::{AllocError, Allocator, Global, Layout}; /// @@ -1365,7 +1365,7 @@ impl Vec { /// # Examples /// /// ``` - /// #![feature(allocator_api, box_vec_non_null)] + /// #![feature(allocator_api)] /// /// use std::alloc::System; /// diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 296f76d7c073d..e09d8495fdeac 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -16,7 +16,6 @@ // tidy-alphabetical-start #![feature(allocator_api)] #![feature(array_into_iter_constructors)] -#![feature(box_vec_non_null)] #![feature(char_internals)] #![feature(const_alloc_error)] #![feature(const_cmp)] @@ -55,16 +54,12 @@ // // Language features: // tidy-alphabetical-start -#![feature(cfg_sanitize)] #![feature(const_trait_impl)] #![feature(dropck_eyepatch)] -#![feature(lang_items)] #![feature(min_specialization)] -#![feature(negative_impls)] #![feature(never_type)] #![feature(optimize_attribute)] #![feature(prelude_import)] -#![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] #![feature(staged_api)] #![feature(test)] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index b7b8336ee4294..699a5010282b0 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -3,7 +3,6 @@ #![feature(const_heap)] #![feature(deque_extend_front)] #![feature(iter_array_chunks)] -#![feature(wtf8_internals)] #![feature(cow_is_borrowed)] #![feature(core_intrinsics)] #![feature(downcast_unchecked)] @@ -30,8 +29,6 @@ #![feature(string_remove_matches)] #![feature(const_btree_len)] #![feature(const_trait_impl)] -#![feature(panic_update_hook)] -#![feature(pointer_is_aligned_to)] #![feature(test)] #![feature(thin_box)] #![feature(drain_keep_rest)] diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index d77fafed2039b..ec3e551056fee 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -878,7 +878,7 @@ impl AsciiChar { /// # Examples /// /// ``` - /// #![feature(ascii_char, ascii_char_variants, is_ascii_octdigit)] + /// #![feature(ascii_char, ascii_char_variants)] /// /// use std::ascii; /// diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index a9e7c49515c7f..28c3db6985369 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -774,7 +774,6 @@ impl Cell<[T; N]> { /// following is unsound: /// /// ```rust -/// #![feature(cell_get_cloned)] /// # use std::cell::Cell; /// /// #[derive(Copy, Debug)] diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 6e82e3356410c..03650615e25a6 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -219,6 +219,7 @@ impl_float_from_bool!( f16; doctest_prefix: // rustdoc doesn't remove the conventional space after the `///` + ///# #![allow(unused_features)] ///#![feature(f16)] ///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// @@ -230,6 +231,7 @@ impl_float_from_bool!(f64); impl_float_from_bool!( f128; doctest_prefix: + ///# #![allow(unused_features)] ///#![feature(f128)] ///# #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index aaa919ece6a58..dfa1236c2a2c9 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -87,6 +87,7 @@ #![allow(incomplete_features)] #![warn(multiple_supertrait_upcastable)] #![allow(internal_features)] +#![allow(unused_features)] #![deny(ffi_unwind_calls)] #![warn(unreachable_pub)] // Do not check link redundancy on bootstrapping phase @@ -95,9 +96,7 @@ // // Library features: // tidy-alphabetical-start -#![feature(array_ptr_get)] #![feature(asm_experimental_arch)] -#![feature(bstr)] #![feature(bstr_internals)] #![feature(cfg_select)] #![feature(cfg_target_has_reliable_f16_f128)] @@ -106,31 +105,15 @@ #![feature(const_destruct)] #![feature(const_eval_select)] #![feature(const_select_unpredictable)] -#![feature(const_unsigned_bigint_helpers)] #![feature(core_intrinsics)] #![feature(coverage_attribute)] #![feature(disjoint_bitor)] #![feature(internal_impls_macro)] -#![feature(ip)] -#![feature(is_ascii_octdigit)] #![feature(link_cfg)] #![feature(offset_of_enum)] #![feature(panic_internals)] #![feature(pattern_type_macro)] -#![feature(ptr_alignment_type)] -#![feature(ptr_metadata)] -#![feature(set_ptr_value)] -#![feature(signed_bigint_helpers)] -#![feature(slice_ptr_get)] -#![feature(str_internals)] -#![feature(str_split_inclusive_remainder)] -#![feature(str_split_remainder)] -#![feature(type_info)] #![feature(ub_checks)] -#![feature(unsafe_pinned)] -#![feature(utf16_extra)] -#![feature(variant_count)] -#![feature(widening_mul)] // tidy-alphabetical-end // // Language features: @@ -175,7 +158,6 @@ #![feature(optimize_attribute)] #![feature(pattern_types)] #![feature(prelude_import)] -#![feature(reborrow)] #![feature(repr_simd)] #![feature(rustc_allow_const_fn_unstable)] #![feature(rustc_attrs)] diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 140b955259ab8..d114b821655bf 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -148,7 +148,10 @@ pub mod consts { pub const LN_10: f128 = 2.30258509299404568401799145468436420760110148862877297603333_f128; } -#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), allow(internal_features))))] +#[doc(test(attr( + feature(cfg_target_has_reliable_f16_f128), + allow(internal_features, unused_features) +)))] impl f128 { /// The radix or base of the internal representation of `f128`. #[unstable(feature = "f128", issue = "116909")] @@ -1470,7 +1473,11 @@ impl f128 { // Functions in this module fall into `core_float_math` // #[unstable(feature = "core_float_math", issue = "137578")] #[cfg(not(test))] -#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))] +#[doc(test(attr( + feature(cfg_target_has_reliable_f16_f128), + expect(internal_features), + allow(unused_features) +)))] impl f128 { /// Returns the largest integer less than or equal to `self`. /// diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 463f07da91b28..373225c5806c1 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -142,7 +142,10 @@ pub mod consts { pub const LN_10: f16 = 2.30258509299404568401799145468436421_f16; } -#[doc(test(attr(feature(cfg_target_has_reliable_f16_f128), allow(internal_features))))] +#[doc(test(attr( + feature(cfg_target_has_reliable_f16_f128), + allow(internal_features, unused_features) +)))] impl f16 { /// The radix or base of the internal representation of `f16`. #[unstable(feature = "f16", issue = "116909")] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index be908cb3894b7..f3c7961931a1d 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1821,6 +1821,7 @@ pub mod math { /// # Examples /// /// ``` + /// # #![allow(unused_features)] /// #![feature(core_float_math)] /// /// # // FIXME(#140515): mingw has an incorrect fma diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 73b20a50ff8ee..a6fd3b1cb5d07 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1819,6 +1819,7 @@ pub mod math { /// # Examples /// /// ``` + /// # #![allow(unused_features)] /// #![feature(core_float_math)] /// /// # // FIXME(#140515): mingw has an incorrect fma diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 5c263ea845cc2..8475cc71a7e04 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3072,7 +3072,6 @@ macro_rules! uint_impl { /// implementing it for wider-than-native types. /// /// ``` - /// #![feature(const_unsigned_bigint_helpers)] /// fn scalar_mul_eq(little_endian_digits: &mut Vec, multiplicand: u16) { /// let mut carry = 0; /// for d in little_endian_digits.iter_mut() { @@ -3097,6 +3096,7 @@ macro_rules! uint_impl { /// except that it gives the value of the overflow instead of just whether one happened: /// /// ``` + /// # #![allow(unused_features)] /// #![feature(const_unsigned_bigint_helpers)] /// let r = u8::carrying_mul(7, 13, 0); /// assert_eq!((r.0, r.1 != 0), u8::overflowing_mul(7, 13)); @@ -3109,6 +3109,7 @@ macro_rules! uint_impl { /// [`wrapping_add`](Self::wrapping_add) methods: /// /// ``` + /// # #![allow(unused_features)] /// #![feature(const_unsigned_bigint_helpers)] /// assert_eq!( /// 789_u16.carrying_mul(456, 123).0, diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index b27930de4e666..b106314f14d12 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -112,7 +112,6 @@ impl Alignment { /// /// ``` /// #![feature(ptr_alignment_type)] - /// #![feature(layout_for_ptr)] /// use std::ptr::Alignment; /// /// assert_eq!(unsafe { Alignment::of_val_raw(&5i32) }.as_usize(), 4); diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 02e12d56fa659..f19a5d02b98df 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1800,7 +1800,6 @@ impl *mut [T] { /// /// ``` /// #![feature(raw_slice_split)] - /// #![feature(slice_ptr_get)] /// /// let mut v = [1, 0, 3, 0, 5, 6]; /// let ptr = &mut v as *mut [_]; diff --git a/library/core/src/time.rs b/library/core/src/time.rs index b4efc09684e7f..a5b654033ba14 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -690,7 +690,6 @@ impl Duration { /// # Examples /// /// ``` - /// #![feature(duration_constants)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 0).saturating_add(Duration::new(0, 1)), Duration::new(0, 1)); @@ -801,7 +800,6 @@ impl Duration { /// # Examples /// /// ``` - /// #![feature(duration_constants)] /// use std::time::Duration; /// /// assert_eq!(Duration::new(0, 500_000_001).saturating_mul(2), Duration::new(1, 2)); diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 5923328655524..3a30b6b7edcc8 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -13,7 +13,6 @@ #![feature(cfg_target_has_reliable_f16_f128)] #![feature(char_internals)] #![feature(char_max_len)] -#![feature(clamp_magnitude)] #![feature(clone_to_uninit)] #![feature(const_array)] #![feature(const_bool)] @@ -35,7 +34,6 @@ #![feature(const_trait_impl)] #![feature(const_unsigned_bigint_helpers)] #![feature(control_flow_ok)] -#![feature(core_float_math)] #![feature(core_intrinsics)] #![feature(core_intrinsics_fallbacks)] #![feature(core_io_borrowed_buf)] @@ -47,7 +45,6 @@ #![feature(drop_guard)] #![feature(duration_constants)] #![feature(duration_constructors)] -#![feature(error_generic_member_access)] #![feature(exact_div)] #![feature(exact_size_is_empty)] #![feature(extend_one)] @@ -55,7 +52,6 @@ #![feature(f16)] #![feature(f128)] #![feature(float_algebraic)] -#![feature(float_gamma)] #![feature(float_minimum_maximum)] #![feature(flt2dec)] #![feature(fmt_internals)] @@ -94,7 +90,6 @@ #![feature(nonzero_from_str_radix)] #![feature(numfmt)] #![feature(one_sided_range)] -#![feature(option_reduce)] #![feature(pattern)] #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] @@ -114,7 +109,6 @@ #![feature(step_trait)] #![feature(str_internals)] #![feature(strict_provenance_lints)] -#![feature(test)] #![feature(trusted_len)] #![feature(trusted_random_access)] #![feature(try_blocks)] diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 1be19913f260f..83f2a3b2c53f4 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -17,7 +17,6 @@ #![feature(cfg_emscripten_wasm_eh)] #![feature(cfg_select)] #![feature(core_intrinsics)] -#![feature(lang_items)] #![feature(panic_unwind)] #![feature(staged_api)] #![feature(std_internals)] @@ -25,6 +24,7 @@ #![panic_runtime] #![feature(panic_runtime)] #![allow(internal_features)] +#![allow(unused_features)] #![warn(unreachable_pub)] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/library/std/src/num/f128.rs b/library/std/src/num/f128.rs index 6f1fd2975b714..2c8898a6aa86a 100644 --- a/library/std/src/num/f128.rs +++ b/library/std/src/num/f128.rs @@ -16,6 +16,7 @@ use crate::intrinsics; use crate::sys::cmath; #[cfg(not(test))] +#[doc(test(attr(allow(unused_features))))] impl f128 { /// Raises a number to a floating point power. /// diff --git a/library/std/src/num/f16.rs b/library/std/src/num/f16.rs index 20d0b4e1e552b..318a0b3af86a2 100644 --- a/library/std/src/num/f16.rs +++ b/library/std/src/num/f16.rs @@ -916,7 +916,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// #![feature(float_gamma)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -952,7 +951,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// #![feature(float_gamma)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// @@ -988,7 +986,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// #![feature(float_erf)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// /// The error function relates what percent of a normal distribution lies @@ -1028,7 +1025,6 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// #![feature(float_erf)] /// # #[cfg(not(miri))] /// # #[cfg(target_has_reliable_f16_math)] { /// let x: f16 = 0.123; diff --git a/library/std/tests/floats/lib.rs b/library/std/tests/floats/lib.rs index 8bb8eb4bfc1ae..012349350b0b8 100644 --- a/library/std/tests/floats/lib.rs +++ b/library/std/tests/floats/lib.rs @@ -1,4 +1,4 @@ -#![feature(f16, f128, float_gamma, float_minimum_maximum, cfg_target_has_reliable_f16_f128)] +#![feature(f16, f128, float_gamma, cfg_target_has_reliable_f16_f128)] #![expect(internal_features)] // for reliable_f16_f128 use std::fmt; diff --git a/library/std/tests/volatile-fat-ptr.rs b/library/std/tests/volatile-fat-ptr.rs index b005c12c6187b..b00277e7a4113 100644 --- a/library/std/tests/volatile-fat-ptr.rs +++ b/library/std/tests/volatile-fat-ptr.rs @@ -1,5 +1,4 @@ #![allow(stable_features)] -#![feature(volatile)] use std::ptr::{read_volatile, write_volatile}; diff --git a/library/std_detect/tests/cpu-detection.rs b/library/std_detect/tests/cpu-detection.rs index 196abfdb7c4dd..0aad088af7de5 100644 --- a/library/std_detect/tests/cpu-detection.rs +++ b/library/std_detect/tests/cpu-detection.rs @@ -1,4 +1,4 @@ -#![allow(internal_features)] +#![allow(internal_features, unused_features)] #![feature(stdarch_internal)] #![cfg_attr(target_arch = "arm", feature(stdarch_arm_feature_detection))] #![cfg_attr( diff --git a/library/std_detect/tests/macro_trailing_commas.rs b/library/std_detect/tests/macro_trailing_commas.rs index 29bd3f1162a42..a60b34acb872f 100644 --- a/library/std_detect/tests/macro_trailing_commas.rs +++ b/library/std_detect/tests/macro_trailing_commas.rs @@ -1,4 +1,4 @@ -#![allow(internal_features)] +#![allow(internal_features, unused_features)] #![cfg_attr( any( target_arch = "arm", diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index d554807bbde70..f3dbd3d0556ab 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -24,7 +24,7 @@ #![feature(staged_api)] #![feature(process_exitcode_internals)] #![feature(panic_can_unwind)] -#![feature(test)] +#![cfg_attr(test, feature(test))] #![feature(thread_spawn_hook)] #![allow(internal_features)] #![warn(rustdoc::unescaped_backticks)] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index cff2aa7b08b93..f2e0cfd32ed67 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -4,12 +4,12 @@ #![feature(cfg_select)] #![feature(link_cfg)] #![feature(staged_api)] -#![cfg_attr(not(target_env = "msvc"), feature(libc))] #![cfg_attr( all(target_family = "wasm", any(not(target_os = "emscripten"), emscripten_wasm_eh)), feature(link_llvm_intrinsics, simd_wasm64) )] #![allow(internal_features)] +#![allow(unused_features)] #![deny(unsafe_op_in_unsafe_fn)] // Force libc to be included even if unused. This is required by many platforms. diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index e46fed7c426ab..ef2de9b37ed0f 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -175,8 +175,8 @@ When you use bootstrap, you'll call it through the entry point script (`x`, `x.ps1`, or `x.py`). However, most of the code lives in `src/bootstrap`. `bootstrap` has a difficult problem: it is written in Rust, but yet it is run before the Rust compiler is built! To work around this, there are two components -of bootstrap: the main one written in rust, and `bootstrap.py`. `bootstrap.py` -is what gets run by entry point script. It takes care of downloading the prebuilt +of bootstrap: the main one written in Rust, and `bootstrap.py`. `bootstrap.py` +is what gets run by the entry point script. It takes care of downloading the prebuilt stage 0 compiler, std and Cargo binaries, which are then used to build the bootstrap binary. diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 366fa8e150f8f..db7c7b69cba94 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -479,7 +479,7 @@ def default_build_triple(verbose): @contextlib.contextmanager def output(filepath): tmp = filepath + ".tmp" - with open(tmp, "w") as f: + with open(tmp, "w", encoding="utf-8") as f: yield f try: if os.path.exists(filepath): @@ -778,7 +778,7 @@ def get_answer(): # Use `/etc/os-release` instead of `/etc/NIXOS`. # The latter one does not exist on NixOS when using tmpfs as root. try: - with open("/etc/os-release", "r") as f: + with open("/etc/os-release", "r", encoding="utf-8") as f: is_nixos = any( ln.strip() in ("ID=nixos", "ID='nixos'", 'ID="nixos"') for ln in f @@ -863,7 +863,8 @@ def fix_bin_or_dylib(self, fname): if ".so" not in fname: # Finally, set the correct .interp for binaries with open( - "{}/nix-support/dynamic-linker".format(nix_deps_dir) + "{}/nix-support/dynamic-linker".format(nix_deps_dir), + encoding="utf-8", ) as dynamic_linker: patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()] @@ -888,7 +889,7 @@ def program_out_of_date(self, stamp_path, key): """Check if the given program stamp is out of date""" if not os.path.exists(stamp_path) or self.clean: return True - with open(stamp_path, "r") as stamp: + with open(stamp_path, "r", encoding="utf-8") as stamp: return key != stamp.read() def bin_root(self): @@ -1276,7 +1277,7 @@ def parse_args(args): def parse_stage0_file(path): result = {} - with open(path, "r") as file: + with open(path, "r", encoding="utf-8") as file: for line in file: line = line.strip() if line and not line.startswith("#"): @@ -1346,7 +1347,7 @@ def bootstrap(args): # HACK: This works because `self.get_toml()` returns the first match it finds for a # specific key, so appending our defaults at the end allows the user to override them - with open(include_path) as included_toml: + with open(include_path, encoding="utf-8") as included_toml: config_toml += os.linesep + included_toml.read() # Configure initial bootstrap @@ -1384,7 +1385,9 @@ def main(): if len(sys.argv) == 1 or sys.argv[1] in ["-h", "--help"]: try: with open( - os.path.join(os.path.dirname(__file__), "../etc/xhelp"), "r" + os.path.join(os.path.dirname(__file__), "../etc/xhelp"), + "r", + encoding="utf-8", ) as f: # The file from bootstrap func already has newline. print(f.read(), end="") diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 4ee02e9bf0055..5d3a74edc9959 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -48,7 +48,7 @@ Refer to the [dev guide](https://rustc-dev-guide.rust-lang.org/tests/docker.html ## Docker Toolbox on Windows For Windows before Windows 10, the docker images can be run on Windows via -[Docker Toolbox]. There are several preparation needs to be made before running +[Docker Toolbox]. There are several preparations that need to be made before running a Docker image. 1. Stop the virtual machine from the terminal with `docker-machine stop` @@ -92,7 +92,7 @@ To run the image, A number of these images take quite a long time to compile as they're building whole gcc toolchains to do cross builds with. Much of this is relatively self-explanatory but some images use [crosstool-ng] which isn't quite as self -explanatory. Below is a description of where these `*.defconfig` files come form, +explanatory. Below is a description of where these `*.defconfig` files come from, how to generate them, and how the existing ones were generated. [crosstool-ng]: https://github.com/crosstool-ng/crosstool-ng diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 158539b47f300..a8b2111a901e4 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -189,6 +189,7 @@ target | std | notes [`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) +[`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39) [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | ✓ |RISC-V Linux (kernel 4.20+, musl 1.2.5) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) [`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | Bare RISC-V (RV64IM ISA) @@ -406,7 +407,6 @@ target | std | host | notes [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 [`riscv64gc-unknown-redox`](platform-support/redox.md) | ✓ | | RISC-V 64bit Redox OS [`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX -[`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39) [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.5) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 6259f8bd15385..6ce3345fc607d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -6,12 +6,10 @@ )] #![feature(ascii_char)] #![feature(ascii_char_variants)] -#![feature(box_into_inner)] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(formatting_options)] #![feature(if_let_guard)] -#![feature(iter_advance_by)] #![feature(iter_intersperse)] #![feature(iter_order_by)] #![feature(rustc_private)] diff --git a/tests/crashes/135845.rs b/tests/crashes/135845.rs deleted file mode 100644 index ed038d8a1f187..0000000000000 --- a/tests/crashes/135845.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: #135845 -struct S<'a, T: ?Sized>(&'a T); - -fn b<'a>() -> S<'static, _> { - S::<'a>(&0) -} diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs index 22963b6438c0e..d06ea7a10c745 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs @@ -4,9 +4,10 @@ fn foo() { [0; size_of::<*mut T>()]; - //~^ ERROR: tuple constructor with invalid base path + //~^ ERROR: complex const arguments must be placed inside of a `const` block [0; const { size_of::<*mut T>() }]; //~^ ERROR: generic parameters may not be used in const operations + [0; const { size_of::<*mut i32>() }]; } fn main() {} diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr index 6d8d3b4054d34..61e934380c360 100644 --- a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr @@ -1,4 +1,4 @@ -error: tuple constructor with invalid base path +error: complex const arguments must be placed inside of a `const` block --> $DIR/size-of-generic-ptr-in-array-len.rs:6:9 | LL | [0; size_of::<*mut T>()]; diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs index 95ee42d93d739..43d0d21fb7361 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs @@ -32,7 +32,7 @@ fn test_errors() { //~| ERROR tuple constructor with invalid base path accepts_point::<{ non_ctor(N, N) }>(); - //~^ ERROR tuple constructor with invalid base path + //~^ ERROR complex const arguments must be placed inside of a `const` block accepts_point::<{ CONST_ITEM(N, N) }>(); //~^ ERROR tuple constructor with invalid base path diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr index dc6a700a8e126..ce210b2b3e39a 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr @@ -27,7 +27,7 @@ error: tuple constructor with invalid base path LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); | ^^^^^^^^^^^^^^^^^^^^^ -error: tuple constructor with invalid base path +error: complex const arguments must be placed inside of a `const` block --> $DIR/tuple_ctor_erroneous.rs:34:23 | LL | accepts_point::<{ non_ctor(N, N) }>(); diff --git a/tests/ui/const-generics/mgca/type-const-ctor-148953.rs b/tests/ui/const-generics/mgca/type-const-ctor-148953.rs new file mode 100644 index 0000000000000..bdd3dcf8618fc --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-ctor-148953.rs @@ -0,0 +1,31 @@ +//! Regression test for +//! +//! Unit struct constructors used as the RHS of a `type const` associated +//! const used to ICE during normalization because they were lowered as +//! `Const::new_unevaluated` with a Ctor def_id. Fixed by adding proper const +//! constructor support that produces a concrete ValTree value instead. + +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +struct S; + +impl S { + type const N: S = S; +} + +#[derive(ConstParamTy, PartialEq, Eq)] +enum E { + V, +} + +impl E { + type const M: E = { E::V }; +} + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-deprecated_safe.rs b/tests/ui/feature-gates/feature-gate-deprecated_safe.rs deleted file mode 100644 index d5f4a4705b972..0000000000000 --- a/tests/ui/feature-gates/feature-gate-deprecated_safe.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[deprecated_safe(since = "TBD", note = "...")] //~ ERROR: the `#[deprecated_safe]` attribute is an experimental feature -unsafe fn deprecated_safe_fn() {} - -#[deprecated_safe(since = "TBD", note = "...")] //~ ERROR: the `#[deprecated_safe]` attribute is an experimental feature -unsafe trait DeprecatedSafeTrait {} - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-deprecated_safe.stderr b/tests/ui/feature-gates/feature-gate-deprecated_safe.stderr deleted file mode 100644 index 415d54463d1a4..0000000000000 --- a/tests/ui/feature-gates/feature-gate-deprecated_safe.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0658]: the `#[deprecated_safe]` attribute is an experimental feature - --> $DIR/feature-gate-deprecated_safe.rs:1:1 - | -LL | #[deprecated_safe(since = "TBD", note = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #94978 for more information - = help: add `#![feature(deprecated_safe)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: the `#[deprecated_safe]` attribute is an experimental feature - --> $DIR/feature-gate-deprecated_safe.rs:4:1 - | -LL | #[deprecated_safe(since = "TBD", note = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #94978 for more information - = help: add `#![feature(deprecated_safe)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs new file mode 100644 index 0000000000000..acce49b1af72f --- /dev/null +++ b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs @@ -0,0 +1,11 @@ +// Regression test for #135845. + +use std::marker::PhantomData; + +fn b<'a>() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + let _: PhantomData<&'a ()> = PhantomData; + 0 +} + +fn main() {} diff --git a/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr new file mode 100644 index 0000000000000..9f3695e88f828 --- /dev/null +++ b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/recover-infer-ret-ty-issue-135845.rs:5:15 + | +LL | fn b<'a>() -> _ { + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn b<'a>() -> _ { +LL + fn b<'a>() -> i32 { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/traits/next-solver/opaques/eventually-constrained-region.rs b/tests/ui/traits/next-solver/opaques/eventually-constrained-region.rs new file mode 100644 index 0000000000000..997bcd6ed9b44 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/eventually-constrained-region.rs @@ -0,0 +1,21 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Regression test for trait-system-refactor-initiative#264. +// +// Some defining uses of opaque types can't constrain captured regions to universals. +// Previouly, we eagerly report error in this case. +// Now we report error only if there's no fully defining use from all bodies of the typeck root. + +struct Inv<'a>(*mut &'a ()); + +fn mk_static() -> Inv<'static> { todo!() } + +fn guide_closure_sig<'a>(f: impl FnOnce() -> Inv<'a>) {} + +fn unconstrained_in_closure() -> impl Sized { + guide_closure_sig(|| unconstrained_in_closure()); + mk_static() +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.rs b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.rs new file mode 100644 index 0000000000000..61823c1e300db --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -Znext-solver + +// Just for diagnostics completeness. +// This is probably unimportant as we only report one error for such case in HIR typeck. + +#![feature(type_alias_impl_trait)] + +struct Invar<'a>(*mut &'a ()); + +fn mk_invar<'a>(a: &'a i32) -> Invar<'a> { + todo!() +} + +type MultiUse = impl Sized; + +#[define_opaque(MultiUse)] +fn capture_different_universals_not_on_bounds<'a, 'b, 'c>(a: &'a i32, b: &'b i32, c: &'c i32) { + let _ = || -> MultiUse { + //~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700] + mk_invar(a) + }; + let _ = || -> MultiUse { + //~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700] + mk_invar(b) + }; + let _ = || { + let _ = || -> MultiUse { + //~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700] + mk_invar(c) + }; + }; +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.stderr b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.stderr new file mode 100644 index 0000000000000..28d9da3d4666d --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.stderr @@ -0,0 +1,36 @@ +error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds + --> $DIR/report-all-unexpected-hidden-errors.rs:18:19 + | +LL | type MultiUse = impl Sized; + | ---------- opaque type defined here +... +LL | let _ = || -> MultiUse { + | ^^^^^^^^ + | + = note: hidden type `Invar<'_>` captures lifetime `'_` + +error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds + --> $DIR/report-all-unexpected-hidden-errors.rs:22:19 + | +LL | type MultiUse = impl Sized; + | ---------- opaque type defined here +... +LL | let _ = || -> MultiUse { + | ^^^^^^^^ + | + = note: hidden type `Invar<'_>` captures lifetime `'_` + +error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds + --> $DIR/report-all-unexpected-hidden-errors.rs:27:23 + | +LL | type MultiUse = impl Sized; + | ---------- opaque type defined here +... +LL | let _ = || -> MultiUse { + | ^^^^^^^^ + | + = note: hidden type `Invar<'_>` captures lifetime `'_` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/traits/vtable/missing-generics-issue-151330.rs b/tests/ui/traits/vtable/missing-generics-issue-151330.rs new file mode 100644 index 0000000000000..352ad7be3d3a7 --- /dev/null +++ b/tests/ui/traits/vtable/missing-generics-issue-151330.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Znext-solver=globally +// Regression test for issue https://github.com/rust-lang/rust/issues/151330 + +trait Supertrait {} + +trait Trait

: Supertrait {} +//~^ ERROR missing generics for trait `Supertrait` +//~| ERROR missing generics for trait `Supertrait` +//~| ERROR missing generics for trait `Supertrait` + +impl

Trait

for () {} + +const fn upcast

(x: &dyn Trait

) -> &dyn Trait

{ + x +} + +const fn foo() -> &'static dyn Supertrait<()> { + upcast::<()>(&()) +} + +const _: &'static dyn Supertrait<()> = foo(); + +fn main() {} diff --git a/tests/ui/traits/vtable/missing-generics-issue-151330.stderr b/tests/ui/traits/vtable/missing-generics-issue-151330.stderr new file mode 100644 index 0000000000000..65ef08cad32a9 --- /dev/null +++ b/tests/ui/traits/vtable/missing-generics-issue-151330.stderr @@ -0,0 +1,53 @@ +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

: Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - +help: add missing generic argument + | +LL | trait Trait

: Supertrait {} + | +++ + +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

: Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | trait Trait

: Supertrait {} + | +++ + +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

: Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | trait Trait

: Supertrait {} + | +++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/triagebot.toml b/triagebot.toml index 2a98b1d43b99e..bc90371393b60 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -76,9 +76,9 @@ add-labels = ["beta-nominated"] [ping.windows] message = """\ -Hey Windows Group! This bug has been identified as a good "Windows candidate". +Hey Windows Group! This issue has been identified as a good "Windows candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/windows.html @@ -87,9 +87,9 @@ label = "O-windows" [ping.arm] message = """\ -Hey ARM Group! This bug has been identified as a good "ARM candidate". +Hey ARM Group! This issue has been identified as a good "ARM candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/arm.html @@ -98,9 +98,9 @@ label = "O-ARM" [ping.loongarch] message = """\ -Hey LoongArch Group! This bug has been identified as a good "LoongArch candidate". +Hey LoongArch Group! This issue has been identified as a good "LoongArch candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/loongarch.html @@ -109,9 +109,9 @@ label = "O-loongarch" [ping.risc-v] message = """\ -Hey RISC-V Group! This bug has been identified as a good "RISC-V candidate". +Hey RISC-V Group! This issue has been identified as a good "RISC-V candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/risc-v.html