diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index f96c9fe8e3273..1b91c33742d8b 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -112,7 +112,8 @@ ast_lowering_invalid_register = invalid register `{$reg}`: {$error} ast_lowering_invalid_register_class = - invalid register class `{$reg_class}`: {$error} + invalid register class `{$reg_class}`: unknown register class + .note = the following register classes are supported on this target: {$supported_register_classes} ast_lowering_match_arm_with_no_body = `match` arm with no body diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 2f1f1269ece57..96c230ec243a2 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -152,11 +152,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { InlineAsmRegOrRegClass::RegClass(reg_class) => { asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch { asm::InlineAsmRegClass::parse(asm_arch, reg_class).unwrap_or_else( - |error| { + |supported_register_classes| { + let mut register_classes = + format!("`{}`", supported_register_classes[0]); + for m in &supported_register_classes[1..] { + let _ = write!(register_classes, ", `{m}`"); + } self.dcx().emit_err(InvalidRegisterClass { op_span: *op_sp, reg_class, - error, + supported_register_classes: register_classes, }); asm::InlineAsmRegClass::Err }, diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 9f69387b7b715..f31e2db051d81 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -197,12 +197,13 @@ pub(crate) struct InvalidRegister<'a> { } #[derive(Diagnostic)] +#[note] #[diag(ast_lowering_invalid_register_class)] -pub(crate) struct InvalidRegisterClass<'a> { +pub(crate) struct InvalidRegisterClass { #[primary_span] pub op_span: Span, pub reg_class: Symbol, - pub error: &'a str, + pub supported_register_classes: String, } #[derive(Diagnostic)] diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index 4a1db8d662a9f..f3552d9b12fcb 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -400,7 +400,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { conv: Conv::C, can_unwind: false, }; - fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false }).unwrap(); + fn_abi.adjust_for_foreign_abi(self.cx, ExternAbi::C { unwind: false }); let ret_indirect = matches!(fn_abi.ret.mode, PassMode::Indirect { .. }); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 8df9877cabca2..c08495c012f83 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -16,7 +16,6 @@ use rustc_middle::mir::interpret::{ }; use rustc_middle::ty::{self, Mutability, Ty}; use rustc_span::{Span, Symbol}; -use rustc_target::callconv::AdjustForForeignAbiError; use crate::interpret::InternKind; @@ -936,9 +935,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { InvalidProgramInfo::TooGeneric => const_eval_too_generic, InvalidProgramInfo::AlreadyReported(_) => const_eval_already_reported, InvalidProgramInfo::Layout(e) => e.diagnostic_message(), - InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => { - rustc_middle::error::middle_adjust_for_foreign_abi_error - } } } fn add_args(self, diag: &mut Diag<'_, G>) { @@ -953,12 +949,6 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { } dummy_diag.cancel(); } - InvalidProgramInfo::FnAbiAdjustForForeignAbi( - AdjustForForeignAbiError::Unsupported { arch, abi }, - ) => { - diag.arg("arch", arch); - diag.arg("abi", abi.name()); - } } } } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 95a72d3cbc1d7..66a75113652f1 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -106,9 +106,6 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { ) -> InterpErrorKind<'tcx> { match err { FnAbiError::Layout(err) => err_inval!(Layout(err)), - FnAbiError::AdjustForForeignAbi(err) => { - err_inval!(FnAbiAdjustForForeignAbi(err)) - } } } } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index d179396398f01..14baf7554bcf6 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -108,13 +108,13 @@ impl IntoDiagArg for rustc_type_ir::ExistentialTrait } impl IntoDiagArg for rustc_type_ir::UnevaluatedConst { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self) -> DiagArgValue { format!("{self:?}").into_diag_arg() } } impl IntoDiagArg for rustc_type_ir::FnSig { - fn into_diag_arg(self) -> rustc_errors::DiagArgValue { + fn into_diag_arg(self) -> DiagArgValue { format!("{self:?}").into_diag_arg() } } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 4df4624971df1..83c7bb0f52f4a 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -10,11 +10,10 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::intravisit::Visitor; use rustc_hir::*; use rustc_hir_pretty as pprust_hir; -use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym, with_metavar_spans}; -use crate::hir::ModuleItems; +use crate::hir::{ModuleItems, nested_filter}; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; use crate::query::LocalCrate; use crate::ty::TyCtxt; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 77a7da2c74bc2..93bbf6d7fa4ff 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -13,7 +13,6 @@ use rustc_feature::GateIssue; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_hir::{self as hir, HirId}; use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic}; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::Session; use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE}; use rustc_session::lint::{BuiltinLintDiag, DeprecatedSinceKind, Level, Lint, LintBuffer}; @@ -23,6 +22,7 @@ use tracing::debug; pub use self::StabilityLevel::*; use crate::ty::TyCtxt; +use crate::ty::print::with_no_trimmed_paths; #[derive(PartialEq, Clone, Copy, Debug)] pub enum StabilityLevel { diff --git a/compiler/rustc_middle/src/mir/generic_graph.rs b/compiler/rustc_middle/src/mir/generic_graph.rs index a52ec58a1ee69..3fd73712b0968 100644 --- a/compiler/rustc_middle/src/mir/generic_graph.rs +++ b/compiler/rustc_middle/src/mir/generic_graph.rs @@ -1,5 +1,6 @@ use gsgdt::{Edge, Graph, Node, NodeStyle}; -use rustc_middle::mir::*; + +use crate::mir::*; /// Convert an MIR function into a gsgdt Graph pub(crate) fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph { diff --git a/compiler/rustc_middle/src/mir/generic_graphviz.rs b/compiler/rustc_middle/src/mir/generic_graphviz.rs index e1c3d8156d83e..bce7beb521da4 100644 --- a/compiler/rustc_middle/src/mir/generic_graphviz.rs +++ b/compiler/rustc_middle/src/mir/generic_graphviz.rs @@ -2,7 +2,8 @@ use std::io::{self, Write}; use rustc_data_structures::graph::{self, iterate}; use rustc_graphviz as dot; -use rustc_middle::ty::TyCtxt; + +use crate::ty::TyCtxt; pub struct GraphvizWriter< 'a, diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs index 7bb41193d5c9c..a64b122fbc9e5 100644 --- a/compiler/rustc_middle/src/mir/graphviz.rs +++ b/compiler/rustc_middle/src/mir/graphviz.rs @@ -2,10 +2,10 @@ use std::io::{self, Write}; use gsgdt::GraphvizSettings; use rustc_graphviz as dot; -use rustc_middle::mir::*; use super::generic_graph::mir_fn_to_generic_graph; use super::pretty::dump_mir_def_ids; +use crate::mir::*; /// Write a graphviz DOT graph of a list of MIRs. pub fn write_mir_graphviz(tcx: TyCtxt<'_>, single: Option, w: &mut W) -> io::Result<()> diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 1222ba052cceb..8861e31b0991c 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -216,10 +216,6 @@ pub enum InvalidProgramInfo<'tcx> { AlreadyReported(ReportedErrorInfo), /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), - /// An error occurred during FnAbi computation: the passed --target lacks FFI support - /// (which unfortunately typeck does not reject). - /// Not using `FnAbiError` as that contains a nested `LayoutError`. - FnAbiAdjustForForeignAbi(rustc_target::callconv::AdjustForForeignAbiError), } /// Details of why a pointer had to be in-bounds. diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 45c862e0d34bf..c48cfffa05cc4 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -20,7 +20,6 @@ use rustc_data_structures::sync::{AtomicU64, Lock}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_serialize::{Decodable, Encodable}; use tracing::{debug, trace}; // Also make the error macros available from this module. @@ -46,6 +45,7 @@ pub use self::pointer::{CtfeProvenance, Pointer, PointerArithmetic, Provenance}; pub use self::value::Scalar; use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; +use crate::ty::print::with_no_trimmed_paths; use crate::ty::{self, Instance, Ty, TyCtxt}; /// Uniquely identifies one of the following: diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index 18c48d99b81ce..748797fbb8d5c 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -1,6 +1,7 @@ -use rustc_middle::mir::*; use tracing::debug; +use crate::mir::*; + /// This struct represents a patch to MIR, which can add /// new statements and basic blocks and patch over block /// terminators. diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 11ebbbe807db7..b0df6c71014a3 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -5,17 +5,16 @@ use std::{fs, io}; use rustc_abi::Size; use rustc_ast::InlineAsmTemplatePiece; -use rustc_middle::mir::interpret::{ - AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer, Provenance, alloc_range, - read_target_uint, -}; -use rustc_middle::mir::visit::Visitor; -use rustc_middle::mir::*; use tracing::trace; use ty::print::PrettyPrinter; use super::graphviz::write_mir_fn_graphviz; -use crate::mir::interpret::ConstAllocation; +use crate::mir::interpret::{ + AllocBytes, AllocId, Allocation, ConstAllocation, GlobalAlloc, Pointer, Provenance, + alloc_range, read_target_uint, +}; +use crate::mir::visit::Visitor; +use crate::mir::*; const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 14f871cbbdcbc..cbd60920bc572 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -101,9 +101,9 @@ impl EraseType for Result<&'_ T, &'_ ty::layout::FnAbiError<'_>> { type Result = [u8; size_of::>>()]; } -impl EraseType for Result<(&'_ T, rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed> { +impl EraseType for Result<(&'_ T, crate::thir::ExprId), rustc_errors::ErrorGuaranteed> { type Result = [u8; size_of::< - Result<(&'static (), rustc_middle::thir::ExprId), rustc_errors::ErrorGuaranteed>, + Result<(&'static (), crate::thir::ExprId), rustc_errors::ErrorGuaranteed>, >()]; } diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index 3247bdbf1050c..d9035efaf56d0 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -11,12 +11,6 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, Stab use rustc_hir::definitions::DefPathHash; use rustc_index::{Idx, IndexVec}; use rustc_macros::{Decodable, Encodable}; -use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; -use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; -use rustc_middle::mir::mono::MonoItem; -use rustc_middle::mir::{self, interpret}; -use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; -use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_query_system::query::QuerySideEffects; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -30,6 +24,13 @@ use rustc_span::{ SpanDecoder, SpanEncoder, StableSourceFileId, Symbol, }; +use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; +use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; +use crate::mir::mono::MonoItem; +use crate::mir::{self, interpret}; +use crate::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; +use crate::ty::{self, Ty, TyCtxt}; + const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; // A normal span encoded with both location information and a `SyntaxContext` @@ -563,7 +564,7 @@ impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> { } } -rustc_middle::implement_ty_decoder!(CacheDecoder<'a, 'tcx>); +crate::implement_ty_decoder!(CacheDecoder<'a, 'tcx>); // This ensures that the `Decodable::decode` specialization for `Vec` is used // when a `CacheDecoder` is passed to `Decodable::decode`. Unfortunately, we have to manually opt diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 4dc8f27955358..2ab8750f727c0 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -20,20 +20,21 @@ use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::{IndexVec, newtype_index}; use rustc_macros::{HashStable, TypeVisitable}; -use rustc_middle::middle::region; -use rustc_middle::mir::interpret::AllocId; -use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; -use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::{ - self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, List, Ty, - TyCtxt, UpvarArgs, -}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span, Symbol}; use rustc_target::asm::InlineAsmRegOrRegClass; use tracing::instrument; +use crate::middle::region; +use crate::mir::interpret::AllocId; +use crate::mir::{self, BinOp, BorrowKind, FakeReadCause, UnOp}; +use crate::ty::adjustment::PointerCoercion; +use crate::ty::layout::IntegerExt; +use crate::ty::{ + self, AdtDef, CanonicalUserType, CanonicalUserTypeAnnotation, FnSig, GenericArgsRef, List, Ty, + TyCtxt, UpvarArgs, +}; + pub mod visit; macro_rules! thir_with_elements { diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs index b1316ceef5ac7..10f7d58963623 100644 --- a/compiler/rustc_middle/src/ty/cast.rs +++ b/compiler/rustc_middle/src/ty/cast.rs @@ -2,8 +2,8 @@ // typeck and codegen. use rustc_macros::{HashStable, TyDecodable, TyEncodable}; -use rustc_middle::mir; +use crate::mir; use crate::ty::{self, Ty}; /// Types that are represented as ints. diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 94bf1aa4f0356..6b6e0ffc65646 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -13,8 +13,6 @@ use std::marker::DiscriminantKind; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::LocalDefId; -use rustc_middle::mir::mono::MonoItem; -use rustc_middle::ty::TyCtxt; use rustc_serialize::{Decodable, Encodable}; use rustc_span::Span; use rustc_span::source_map::Spanned; @@ -23,9 +21,10 @@ pub use rustc_type_ir::{TyDecoder, TyEncoder}; use crate::arena::ArenaAllocatable; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use crate::mir::interpret::{AllocId, ConstAllocation, CtfeProvenance}; +use crate::mir::mono::MonoItem; use crate::mir::{self}; use crate::traits; -use crate::ty::{self, AdtDef, GenericArgsRef, Ty}; +use crate::ty::{self, AdtDef, GenericArgsRef, Ty, TyCtxt}; /// The shorthand encoding uses an enum's variant index `usize` /// and is offset by this value so it never matches a real variant. diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index b7a648aae3f19..e9c19331e4a0b 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -10,13 +10,13 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::FiniteBitSet; use rustc_macros::{Decodable, Encodable, HashStable, Lift, TyDecodable, TyEncodable}; -use rustc_middle::ty::normalize_erasing_regions::NormalizationError; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, Span, Symbol}; use tracing::{debug, instrument}; use crate::error; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::print::{FmtPrinter, Printer, shrunk_instance_name}; use crate::ty::{ self, EarlyBinder, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index e5015ea3c3d1f..4b3e29b7c6cc8 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -24,7 +24,6 @@ use rustc_target::spec::{ use tracing::debug; use {rustc_abi as abi, rustc_hir as hir}; -use crate::error::UnsupportedFnAbi; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::TyCtxtAt; use crate::ty::normalize_erasing_regions::NormalizationError; @@ -1275,18 +1274,12 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: ExternAbi) pub enum FnAbiError<'tcx> { /// Error produced by a `layout_of` call, while computing `FnAbi` initially. Layout(LayoutError<'tcx>), - - /// Error produced by attempting to adjust a `FnAbi`, for a "foreign" ABI. - AdjustForForeignAbi(rustc_target::callconv::AdjustForForeignAbiError), } impl<'a, 'b, G: EmissionGuarantee> Diagnostic<'a, G> for FnAbiError<'b> { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { match self { Self::Layout(e) => e.into_diagnostic().into_diag(dcx, level), - Self::AdjustForForeignAbi( - rustc_target::callconv::AdjustForForeignAbiError::Unsupported { arch, abi }, - ) => UnsupportedFnAbi { arch, abi: abi.name() }.into_diag(dcx, level), } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index feae8ea312eaa..343aabd7bbb36 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1512,7 +1512,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ExprKind::Binop(op) => { let (_, _, c1, c2) = expr.binop_args(); - let precedence = |binop: rustc_middle::mir::BinOp| { + let precedence = |binop: crate::mir::BinOp| { use rustc_ast::util::parser::AssocOp; AssocOp::from_ast_binop(binop.to_hir_binop()).precedence() }; @@ -1558,7 +1558,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::ExprKind::UnOp(op) => { let (_, ct) = expr.unop_args(); - use rustc_middle::mir::UnOp; + use crate::mir::UnOp; let formatted_op = match op { UnOp::Not => "!", UnOp::Neg => "-", diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 49bdb5e9dc318..1b5b791bb24ae 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -14,13 +14,13 @@ use rustc_hir::{ }; use rustc_index::IndexVec; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -use rustc_middle::mir::FakeReadCause; use rustc_session::Session; use rustc_span::Span; use super::RvalueScopes; use crate::hir::place::Place as HirPlace; use crate::infer::canonical::Canonical; +use crate::mir::FakeReadCause; use crate::traits::ObligationCause; use crate::ty::{ self, BoundVar, CanonicalPolyFnSig, ClosureSizeProfileData, GenericArgKind, GenericArgs, diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs index 8c875007b7fb9..85519fb0a7d2c 100644 --- a/compiler/rustc_middle/src/util/mod.rs +++ b/compiler/rustc_middle/src/util/mod.rs @@ -2,9 +2,9 @@ pub mod bug; #[derive(Default, Copy, Clone)] pub struct Providers { - pub queries: rustc_middle::query::Providers, - pub extern_queries: rustc_middle::query::ExternProviders, - pub hooks: rustc_middle::hooks::Providers, + pub queries: crate::query::Providers, + pub extern_queries: crate::query::ExternProviders, + pub hooks: crate::hooks::Providers, } /// Backwards compatibility hack to keep the diff small. This @@ -17,7 +17,7 @@ impl std::ops::DerefMut for Providers { } impl std::ops::Deref for Providers { - type Target = rustc_middle::query::Providers; + type Target = crate::query::Providers; fn deref(&self) -> &Self::Target { &self.queries diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 867f8f639698c..433f7542bd704 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -7,7 +7,6 @@ use rustc_errors::codes::*; use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_query_system::Value; use rustc_query_system::query::{CycleError, report_cycle}; use rustc_span::def_id::LocalDefId; @@ -15,6 +14,7 @@ use rustc_span::{ErrorGuaranteed, Span}; use crate::dep_graph::dep_kinds; use crate::query::plumbing::CyclePlaceholder; +use crate::ty::{self, Representability, Ty, TyCtxt}; impl<'tcx> Value> for Ty<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self { diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs deleted file mode 100644 index 63257df66fb9b..0000000000000 --- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs +++ /dev/null @@ -1,195 +0,0 @@ -//! This pass finds basic blocks that are completely equal, -//! and replaces all uses with just one of them. - -use std::collections::hash_map::Entry; -use std::hash::{Hash, Hasher}; -use std::iter; - -use rustc_data_structures::fx::FxHashMap; -use rustc_middle::mir::visit::MutVisitor; -use rustc_middle::mir::*; -use rustc_middle::ty::TyCtxt; -use tracing::debug; - -use super::simplify::simplify_cfg; - -pub(super) struct DeduplicateBlocks; - -impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks { - fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() >= 4 - } - - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - debug!("Running DeduplicateBlocks on `{:?}`", body.source); - let duplicates = find_duplicates(body); - let has_opts_to_apply = !duplicates.is_empty(); - - if has_opts_to_apply { - let mut opt_applier = OptApplier { tcx, duplicates }; - opt_applier.visit_body(body); - simplify_cfg(body); - } - } - - fn is_required(&self) -> bool { - false - } -} - -struct OptApplier<'tcx> { - tcx: TyCtxt<'tcx>, - duplicates: FxHashMap, -} - -impl<'tcx> MutVisitor<'tcx> for OptApplier<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { - for target in terminator.successors_mut() { - if let Some(replacement) = self.duplicates.get(target) { - debug!("SUCCESS: Replacing: `{:?}` with `{:?}`", target, replacement); - *target = *replacement; - } - } - - self.super_terminator(terminator, location); - } -} - -fn find_duplicates(body: &Body<'_>) -> FxHashMap { - let mut duplicates = FxHashMap::default(); - - let bbs_to_go_through = - body.basic_blocks.iter_enumerated().filter(|(_, bbd)| !bbd.is_cleanup).count(); - - let mut same_hashes = - FxHashMap::with_capacity_and_hasher(bbs_to_go_through, Default::default()); - - // Go through the basic blocks backwards. This means that in case of duplicates, - // we can use the basic block with the highest index as the replacement for all lower ones. - // For example, if bb1, bb2 and bb3 are duplicates, we will first insert bb3 in same_hashes. - // Then we will see that bb2 is a duplicate of bb3, - // and insert bb2 with the replacement bb3 in the duplicates list. - // When we see bb1, we see that it is a duplicate of bb3, and therefore insert it in the - // duplicates list with replacement bb3. - // When the duplicates are removed, we will end up with only bb3. - for (bb, bbd) in body.basic_blocks.iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) { - // Basic blocks can get really big, so to avoid checking for duplicates in basic blocks - // that are unlikely to have duplicates, we stop early. The early bail number has been - // found experimentally by eprintln while compiling the crates in the rustc-perf suite. - if bbd.statements.len() > 10 { - continue; - } - - let to_hash = BasicBlockHashable { basic_block_data: bbd }; - let entry = same_hashes.entry(to_hash); - match entry { - Entry::Occupied(occupied) => { - // The basic block was already in the hashmap, which means we have a duplicate - let value = *occupied.get(); - debug!("Inserting {:?} -> {:?}", bb, value); - duplicates.try_insert(bb, value).expect("key was already inserted"); - } - Entry::Vacant(vacant) => { - vacant.insert(bb); - } - } - } - - duplicates -} - -struct BasicBlockHashable<'a, 'tcx> { - basic_block_data: &'a BasicBlockData<'tcx>, -} - -impl Hash for BasicBlockHashable<'_, '_> { - fn hash(&self, state: &mut H) { - hash_statements(state, self.basic_block_data.statements.iter()); - // Note that since we only hash the kind, we lose span information if we deduplicate the - // blocks. - self.basic_block_data.terminator().kind.hash(state); - } -} - -impl Eq for BasicBlockHashable<'_, '_> {} - -impl PartialEq for BasicBlockHashable<'_, '_> { - fn eq(&self, other: &Self) -> bool { - self.basic_block_data.statements.len() == other.basic_block_data.statements.len() - && &self.basic_block_data.terminator().kind == &other.basic_block_data.terminator().kind - && iter::zip(&self.basic_block_data.statements, &other.basic_block_data.statements) - .all(|(x, y)| statement_eq(&x.kind, &y.kind)) - } -} - -fn hash_statements<'a, 'tcx, H: Hasher>( - hasher: &mut H, - iter: impl Iterator>, -) where - 'tcx: 'a, -{ - for stmt in iter { - statement_hash(hasher, &stmt.kind); - } -} - -fn statement_hash(hasher: &mut H, stmt: &StatementKind<'_>) { - match stmt { - StatementKind::Assign(box (place, rvalue)) => { - place.hash(hasher); - rvalue_hash(hasher, rvalue) - } - x => x.hash(hasher), - }; -} - -fn rvalue_hash(hasher: &mut H, rvalue: &Rvalue<'_>) { - match rvalue { - Rvalue::Use(op) => operand_hash(hasher, op), - x => x.hash(hasher), - }; -} - -fn operand_hash(hasher: &mut H, operand: &Operand<'_>) { - match operand { - Operand::Constant(box ConstOperand { user_ty: _, const_, span: _ }) => const_.hash(hasher), - x => x.hash(hasher), - }; -} - -fn statement_eq<'tcx>(lhs: &StatementKind<'tcx>, rhs: &StatementKind<'tcx>) -> bool { - let res = match (lhs, rhs) { - ( - StatementKind::Assign(box (place, rvalue)), - StatementKind::Assign(box (place2, rvalue2)), - ) => place == place2 && rvalue_eq(rvalue, rvalue2), - (x, y) => x == y, - }; - debug!("statement_eq lhs: `{:?}` rhs: `{:?}` result: {:?}", lhs, rhs, res); - res -} - -fn rvalue_eq<'tcx>(lhs: &Rvalue<'tcx>, rhs: &Rvalue<'tcx>) -> bool { - let res = match (lhs, rhs) { - (Rvalue::Use(op1), Rvalue::Use(op2)) => operand_eq(op1, op2), - (x, y) => x == y, - }; - debug!("rvalue_eq lhs: `{:?}` rhs: `{:?}` result: {:?}", lhs, rhs, res); - res -} - -fn operand_eq<'tcx>(lhs: &Operand<'tcx>, rhs: &Operand<'tcx>) -> bool { - let res = match (lhs, rhs) { - ( - Operand::Constant(box ConstOperand { user_ty: _, const_, span: _ }), - Operand::Constant(box ConstOperand { user_ty: _, const_: const2, span: _ }), - ) => const_ == const2, - (x, y) => x == y, - }; - debug!("operand_eq lhs: `{:?}` rhs: `{:?}` result: {:?}", lhs, rhs, res); - res -} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b572f6ca0b36a..397d21a857f00 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -135,7 +135,6 @@ declare_passes! { Initial, Final }; - mod deduplicate_blocks : DeduplicateBlocks; mod deref_separator : Derefer; mod dest_prop : DestinationPropagation; pub mod dump_mir : Marker; @@ -700,7 +699,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &nrvo::RenameReturnPlace, &simplify::SimplifyLocals::Final, &multiple_return_terminators::MultipleReturnTerminators, - &deduplicate_blocks::DeduplicateBlocks, &large_enums::EnumSizeOpt { discrepancy: 128 }, // Some cleanup necessary at least for LLVM and potentially other codegen backends. &add_call_guards::CriticalCallEdges, diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 4601bb87b76f9..671b7d7ad76cf 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -46,15 +46,6 @@ fn unwrap_fn_abi<'tcx>( span: tcx.def_span(item_def_id), }); } - Err(FnAbiError::AdjustForForeignAbi(e)) => { - // Sadly there seems to be no `into_diagnostic` for this case... and I am not sure if - // this can even be reached. Anyway this is a perma-unstable debug attribute, an ICE - // isn't the worst thing. Also this matches what codegen does. - span_bug!( - tcx.def_span(item_def_id), - "error computing fn_abi_of_instance, cannot adjust for foreign ABI: {e:?}", - ) - } } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 8d42b478647dc..5db6f83f3ee51 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1127,7 +1127,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }); // Make sure error reporting is deterministic. - suggestions.sort_by(|a, b| a.candidate.as_str().partial_cmp(b.candidate.as_str()).unwrap()); + suggestions.sort_by(|a, b| a.candidate.as_str().cmp(b.candidate.as_str())); match find_best_match_for_name( &suggestions.iter().map(|suggestion| suggestion.candidate).collect::>(), @@ -2256,14 +2256,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { mut path: Vec, parent_scope: &ParentScope<'ra>, ) -> Option<(Vec, Option)> { - match (path.get(0), path.get(1)) { + match path[..] { // `{{root}}::ident::...` on both editions. // On 2015 `{{root}}` is usually added implicitly. - (Some(fst), Some(snd)) - if fst.ident.name == kw::PathRoot && !snd.ident.is_path_segment_keyword() => {} + [first, second, ..] + if first.ident.name == kw::PathRoot && !second.ident.is_path_segment_keyword() => {} // `ident::...` on 2018. - (Some(fst), _) - if fst.ident.span.at_least_rust_2018() && !fst.ident.is_path_segment_keyword() => + [first, ..] + if first.ident.span.at_least_rust_2018() + && !first.ident.is_path_segment_keyword() => { // Insert a placeholder that's later replaced by `self`/`super`/etc. path.insert(0, Segment::from_ident(Ident::empty())); @@ -2374,7 +2375,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // 2) `std` suggestions before `core` suggestions. let mut extern_crate_names = self.extern_prelude.keys().map(|ident| ident.name).collect::>(); - extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap()); + extern_crate_names.sort_by(|a, b| b.as_str().cmp(a.as_str())); for name in extern_crate_names.into_iter() { // Replace first ident with a crate name and check if that is valid. diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 4762281c329a7..aa9ebdd9cead4 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -9,7 +9,7 @@ //! //! ## Adding a new cfg //! -//! Adding a new feature requires two new symbols one for the cfg it-self +//! Adding a new feature requires two new symbols one for the cfg itself //! and the second one for the unstable feature gate, those are defined in //! `rustc_span::symbol`. //! diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 0a4ffb152195e..9f791603c723c 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -39,12 +39,12 @@ macro_rules! def_reg_class { } } - pub fn parse(name: rustc_span::Symbol) -> Result { + pub fn parse(name: rustc_span::Symbol) -> Result { match name { $( rustc_span::sym::$class => Ok(Self::$class), )* - _ => Err("unknown register class"), + _ => Err(&[$(rustc_span::sym::$class),*]), } } } @@ -635,7 +635,7 @@ impl InlineAsmRegClass { } } - pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result { + pub fn parse(arch: InlineAsmArch, name: Symbol) -> Result { Ok(match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { Self::X86(X86InlineAsmRegClass::parse(name)?) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 50ac6c8fcde16..b49dd2588692d 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -6,7 +6,6 @@ use rustc_abi::{ Size, TyAbiInterface, TyAndLayout, }; use rustc_macros::HashStable_Generic; -use rustc_span::Symbol; use crate::spec::{HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, WasmCAbi}; @@ -623,19 +622,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for FnAbi<'a, Ty> { } } -/// Error produced by attempting to adjust a `FnAbi`, for a "foreign" ABI. -#[derive(Copy, Clone, Debug, HashStable_Generic)] -pub enum AdjustForForeignAbiError { - /// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs. - Unsupported { arch: Symbol, abi: ExternAbi }, -} - impl<'a, Ty> FnAbi<'a, Ty> { - pub fn adjust_for_foreign_abi( - &mut self, - cx: &C, - abi: ExternAbi, - ) -> Result<(), AdjustForForeignAbiError> + pub fn adjust_for_foreign_abi(&mut self, cx: &C, abi: ExternAbi) where Ty: TyAbiInterface<'a, C> + Copy, C: HasDataLayout + HasTargetSpec + HasWasmCAbiOpt + HasX86AbiOpt, @@ -644,7 +632,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { if let Some(arg) = self.args.first_mut() { arg.pass_by_stack_offset(None); } - return Ok(()); + return; } let spec = cx.target_spec(); @@ -719,15 +707,8 @@ impl<'a, Ty> FnAbi<'a, Ty> { } "wasm64" => wasm::compute_c_abi_info(cx, self), "bpf" => bpf::compute_abi_info(self), - arch => { - return Err(AdjustForForeignAbiError::Unsupported { - arch: Symbol::intern(arch), - abi, - }); - } + arch => panic!("no lowering implemented for {arch}"), } - - Ok(()) } pub fn adjust_for_rust_abi(&mut self, cx: &C, abi: ExternAbi) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 169f3a78c26a7..332b00e8423bb 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -650,7 +650,7 @@ fn fn_abi_new_uncached<'tcx>( conv, can_unwind: fn_can_unwind(cx.tcx(), fn_def_id, sig.abi), }; - fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi, fn_def_id)?; + fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi, fn_def_id); debug!("fn_abi_new_uncached = {:?}", fn_abi); fn_abi_sanity_check(cx, &fn_abi, sig.abi); Ok(tcx.arena.alloc(fn_abi)) @@ -662,7 +662,7 @@ fn fn_abi_adjust_for_abi<'tcx>( fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>, abi: ExternAbi, fn_def_id: Option, -) -> Result<(), &'tcx FnAbiError<'tcx>> { +) { if abi == ExternAbi::Unadjusted { // The "unadjusted" ABI passes aggregates in "direct" mode. That's fragile but needed for // some LLVM intrinsics. @@ -682,7 +682,7 @@ fn fn_abi_adjust_for_abi<'tcx>( for arg in fn_abi.args.iter_mut() { unadjust(arg); } - return Ok(()); + return; } let tcx = cx.tcx(); @@ -723,12 +723,8 @@ fn fn_abi_adjust_for_abi<'tcx>( } } } else { - fn_abi - .adjust_for_foreign_abi(cx, abi) - .map_err(|err| &*tcx.arena.alloc(FnAbiError::AdjustForForeignAbi(err)))?; + fn_abi.adjust_for_foreign_abi(cx, abi); } - - Ok(()) } #[tracing::instrument(level = "debug", skip(cx))] diff --git a/compiler/rustc_type_ir/src/relate/solver_relating.rs b/compiler/rustc_type_ir/src/relate/solver_relating.rs index dc2312b2da3a5..e42639c68075a 100644 --- a/compiler/rustc_type_ir/src/relate/solver_relating.rs +++ b/compiler/rustc_type_ir/src/relate/solver_relating.rs @@ -1,10 +1,10 @@ -pub use rustc_type_ir::relate::*; -use rustc_type_ir::solve::Goal; -use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; use tracing::{debug, instrument}; use self::combine::{PredicateEmittingRelation, super_combine_consts, super_combine_tys}; use crate::data_structures::DelayedSet; +pub use crate::relate::*; +use crate::solve::Goal; +use crate::{self as ty, InferCtxtLike, Interner}; pub trait RelateExt: InferCtxtLike { fn relate>( diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 17d9455592787..f90de1f5ced40 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -610,6 +610,101 @@ impl dyn Any + Send + Sync { /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth /// noting that the hashes and ordering will vary between Rust releases. Beware /// of relying on them inside of your code! +/// +/// # Danger of Improper Variance +/// +/// You might think that subtyping is impossible between two static types, +/// but this is false; there exists a static type with a static subtype. +/// To wit, `fn(&str)`, which is short for `for<'any> fn(&'any str)`, and +/// `fn(&'static str)`, are two distinct, static types, and yet, +/// `fn(&str)` is a subtype of `fn(&'static str)`, since any value of type +/// `fn(&str)` can be used where a value of type `fn(&'static str)` is needed. +/// +/// This means that abstractions around `TypeId`, despite its +/// `'static` bound on arguments, still need to worry about unnecessary +/// and improper variance: it is advisable to strive for invariance +/// first. The usability impact will be negligible, while the reduction +/// in the risk of unsoundness will be most welcome. +/// +/// ## Examples +/// +/// Suppose `SubType` is a subtype of `SuperType`, that is, +/// a value of type `SubType` can be used wherever +/// a value of type `SuperType` is expected. +/// Suppose also that `CoVar` is a generic type, which is covariant over `T` +/// (like many other types, including `PhantomData` and `Vec`). +/// +/// Then, by covariance, `CoVar` is a subtype of `CoVar`, +/// that is, a value of type `CoVar` can be used wherever +/// a value of type `CoVar` is expected. +/// +/// Then if `CoVar` relies on `TypeId::of::()` to uphold any invariants, +/// those invariants may be broken because a value of type `CoVar` can be created +/// without going through any of its methods, like so: +/// ``` +/// type SubType = fn(&()); +/// type SuperType = fn(&'static ()); +/// type CoVar = Vec; // imagine something more complicated +/// +/// let sub: CoVar = CoVar::new(); +/// // we have a `CoVar` instance without +/// // *ever* having called `CoVar::::new()`! +/// let fake_super: CoVar = sub; +/// ``` +/// +/// The following is an example program that tries to use `TypeId::of` to +/// implement a generic type `Unique` that guarantees unique instances for each `Unique`, +/// that is, and for each type `T` there can be at most one value of type `Unique` at any time. +/// +/// ``` +/// mod unique { +/// use std::any::TypeId; +/// use std::collections::BTreeSet; +/// use std::marker::PhantomData; +/// use std::sync::Mutex; +/// +/// static ID_SET: Mutex> = Mutex::new(BTreeSet::new()); +/// +/// // TypeId has only covariant uses, which makes Unique covariant over TypeAsId 🚨 +/// #[derive(Debug, PartialEq)] +/// pub struct Unique( +/// // private field prevents creation without `new` outside this module +/// PhantomData, +/// ); +/// +/// impl Unique { +/// pub fn new() -> Option { +/// let mut set = ID_SET.lock().unwrap(); +/// (set.insert(TypeId::of::())).then(|| Self(PhantomData)) +/// } +/// } +/// +/// impl Drop for Unique { +/// fn drop(&mut self) { +/// let mut set = ID_SET.lock().unwrap(); +/// (!set.remove(&TypeId::of::())).then(|| panic!("duplicity detected")); +/// } +/// } +/// } +/// +/// use unique::Unique; +/// +/// // `OtherRing` is a subtype of `TheOneRing`. Both are 'static, and thus have a TypeId. +/// type TheOneRing = fn(&'static ()); +/// type OtherRing = fn(&()); +/// +/// fn main() { +/// let the_one_ring: Unique = Unique::new().unwrap(); +/// assert_eq!(Unique::::new(), None); +/// +/// let other_ring: Unique = Unique::new().unwrap(); +/// // Use that `Unique` is a subtype of `Unique` 🚨 +/// let fake_one_ring: Unique = other_ring; +/// assert_eq!(fake_one_ring, the_one_ring); +/// +/// std::mem::forget(fake_one_ring); +/// } +/// ``` #[derive(Clone, Copy, Eq, PartialOrd, Ord)] #[stable(feature = "rust1", since = "1.0.0")] pub struct TypeId { @@ -627,8 +722,7 @@ impl PartialEq for TypeId { } impl TypeId { - /// Returns the `TypeId` of the type this generic function has been - /// instantiated with. + /// Returns the `TypeId` of the generic type parameter. /// /// # Examples /// diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 1d26bf37f4d28..825a89fc7f2c9 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -651,16 +651,24 @@ mod if_keyword {} #[doc(keyword = "impl")] // -/// Implement some functionality for a type. +/// Implementations of functionality for a type, or a type implementing some functionality. +/// +/// There are two uses of the keyword `impl`: +/// * An `impl` block is an item that is used to implement some functionality for a type. +/// * An `impl Trait` in a type-position can be used to designate a type that implements a trait called `Trait`. +/// +/// # Implementing Functionality for a Type /// /// The `impl` keyword is primarily used to define implementations on types. Inherent /// implementations are standalone, while trait implementations are used to implement traits for /// types, or other traits. /// -/// Functions and consts can both be defined in an implementation. A function defined in an -/// `impl` block can be standalone, meaning it would be called like `Foo::bar()`. If the function +/// An implementation consists of definitions of functions and consts. A function defined in an +/// `impl` block can be standalone, meaning it would be called like `Vec::new()`. If the function /// takes `self`, `&self`, or `&mut self` as its first argument, it can also be called using -/// method-call syntax, a familiar feature to any object oriented programmer, like `foo.bar()`. +/// method-call syntax, a familiar feature to any object-oriented programmer, like `vec.len()`. +/// +/// ## Inherent Implementations /// /// ```rust /// struct Example { @@ -680,6 +688,17 @@ mod if_keyword {} /// self.number /// } /// } +/// ``` +/// +/// It matters little where an inherent implementation is defined; +/// its functionality is in scope wherever its implementing type is. +/// +/// ## Trait Implementations +/// +/// ```rust +/// struct Example { +/// number: i32, +/// } /// /// trait Thingy { /// fn do_thingy(&self); @@ -692,11 +711,19 @@ mod if_keyword {} /// } /// ``` /// +/// It matters little where a trait implementation is defined; +/// its functionality can be brought into scope by importing the trait it implements. +/// /// For more information on implementations, see the [Rust book][book1] or the [Reference]. /// -/// The other use of the `impl` keyword is in `impl Trait` syntax, which can be seen as a shorthand -/// for "a concrete type that implements this trait". Its primary use is working with closures, -/// which have type definitions generated at compile time that can't be simply typed out. +/// # Designating a Type that Implements Some Functionality +/// +/// The other use of the `impl` keyword is in `impl Trait` syntax, which can be understood to mean +/// "any (or some) concrete type that implements Trait". +/// It can be used as the type of a variable declaration, +/// in [argument position](https://rust-lang.github.io/rfcs/1951-expand-impl-trait.html) +/// or in [return position](https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html). +/// One pertinent use case is in working with closures, which have unnameable types. /// /// ```rust /// fn thing_returning_closure() -> impl Fn(i32) -> bool { diff --git a/src/doc/rustc/src/check-cfg.md b/src/doc/rustc/src/check-cfg.md index c62ca9fd9ad6b..00add2651ae8b 100644 --- a/src/doc/rustc/src/check-cfg.md +++ b/src/doc/rustc/src/check-cfg.md @@ -135,7 +135,7 @@ As of `2025-01-02T`, the list of known names is as follows: - `windows` > Starting with 1.85.0, the `test` cfg is consider to be a "userspace" config -> despite being also set by `rustc` and should be managed by the build-system it-self. +> despite being also set by `rustc` and should be managed by the build system itself. Like with `values(any())`, well known names checking can be disabled by passing `cfg(any())` as argument to `--check-cfg`. diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs index fa7737bc14386..7f5c7da363422 100644 --- a/src/librustdoc/passes/strip_aliased_non_local.rs +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -26,7 +26,7 @@ impl DocFolder for AliasedNonLocalStripper<'_> { Some(match i.kind { clean::TypeAliasItem(..) => { let mut stripper = NonLocalStripper { tcx: self.tcx }; - // don't call `fold_item` as that could strip the type-alias it-self + // don't call `fold_item` as that could strip the type alias itself // which we don't want to strip out stripper.fold_item_recur(i) } diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff deleted file mode 100644 index 60742ef0e9a90..0000000000000 --- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-abort.diff +++ /dev/null @@ -1,100 +0,0 @@ -- // MIR for `is_line_doc_comment_2` before DeduplicateBlocks -+ // MIR for `is_line_doc_comment_2` after DeduplicateBlocks - - fn is_line_doc_comment_2(_1: &str) -> bool { - debug s => _1; - let mut _0: bool; - let mut _2: &[u8]; - let mut _3: &str; - let mut _4: usize; - let mut _5: usize; - let mut _6: bool; - let mut _7: usize; - let mut _8: usize; - let mut _9: bool; - - bb0: { - StorageLive(_2); - StorageLive(_3); - _3 = &(*_1); - _2 = core::str::::as_bytes(move _3) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_3); - _4 = Len((*_2)); - _5 = const 4_usize; - _6 = Ge(move _4, move _5); - switchInt(move _6) -> [0: bb2, otherwise: bb3]; - } - - bb2: { - _7 = Len((*_2)); - _8 = const 3_usize; - _9 = Ge(move _7, move _8); -- switchInt(move _9) -> [0: bb7, otherwise: bb8]; -+ switchInt(move _9) -> [0: bb11, otherwise: bb7]; - } - - bb3: { - switchInt(copy (*_2)[0 of 4]) -> [47: bb4, otherwise: bb2]; - } - - bb4: { - switchInt(copy (*_2)[1 of 4]) -> [47: bb5, otherwise: bb2]; - } - - bb5: { - switchInt(copy (*_2)[2 of 4]) -> [47: bb6, otherwise: bb2]; - } - - bb6: { -- switchInt(copy (*_2)[3 of 4]) -> [47: bb13, otherwise: bb2]; -+ switchInt(copy (*_2)[3 of 4]) -> [47: bb11, otherwise: bb2]; - } - - bb7: { -- _0 = const false; -- goto -> bb14; -+ switchInt(copy (*_2)[0 of 3]) -> [47: bb8, otherwise: bb11]; - } - - bb8: { -- switchInt(copy (*_2)[0 of 3]) -> [47: bb9, otherwise: bb7]; -+ switchInt(copy (*_2)[1 of 3]) -> [47: bb9, otherwise: bb11]; - } - - bb9: { -- switchInt(copy (*_2)[1 of 3]) -> [47: bb10, otherwise: bb7]; -+ switchInt(copy (*_2)[2 of 3]) -> [47: bb10, 33: bb10, otherwise: bb11]; - } - - bb10: { -- switchInt(copy (*_2)[2 of 3]) -> [47: bb12, 33: bb11, otherwise: bb7]; -- } -- -- bb11: { - _0 = const true; -- goto -> bb14; -+ goto -> bb12; - } - -- bb12: { -- _0 = const true; -- goto -> bb14; -- } -- -- bb13: { -+ bb11: { - _0 = const false; -- goto -> bb14; -+ goto -> bb12; - } - -- bb14: { -+ bb12: { - StorageDead(_2); - return; - } - } - diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff deleted file mode 100644 index 7337a32f525f9..0000000000000 --- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.panic-unwind.diff +++ /dev/null @@ -1,100 +0,0 @@ -- // MIR for `is_line_doc_comment_2` before DeduplicateBlocks -+ // MIR for `is_line_doc_comment_2` after DeduplicateBlocks - - fn is_line_doc_comment_2(_1: &str) -> bool { - debug s => _1; - let mut _0: bool; - let mut _2: &[u8]; - let mut _3: &str; - let mut _4: usize; - let mut _5: usize; - let mut _6: bool; - let mut _7: usize; - let mut _8: usize; - let mut _9: bool; - - bb0: { - StorageLive(_2); - StorageLive(_3); - _3 = &(*_1); - _2 = core::str::::as_bytes(move _3) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_3); - _4 = Len((*_2)); - _5 = const 4_usize; - _6 = Ge(move _4, move _5); - switchInt(move _6) -> [0: bb2, otherwise: bb3]; - } - - bb2: { - _7 = Len((*_2)); - _8 = const 3_usize; - _9 = Ge(move _7, move _8); -- switchInt(move _9) -> [0: bb7, otherwise: bb8]; -+ switchInt(move _9) -> [0: bb11, otherwise: bb7]; - } - - bb3: { - switchInt(copy (*_2)[0 of 4]) -> [47: bb4, otherwise: bb2]; - } - - bb4: { - switchInt(copy (*_2)[1 of 4]) -> [47: bb5, otherwise: bb2]; - } - - bb5: { - switchInt(copy (*_2)[2 of 4]) -> [47: bb6, otherwise: bb2]; - } - - bb6: { -- switchInt(copy (*_2)[3 of 4]) -> [47: bb13, otherwise: bb2]; -+ switchInt(copy (*_2)[3 of 4]) -> [47: bb11, otherwise: bb2]; - } - - bb7: { -- _0 = const false; -- goto -> bb14; -+ switchInt(copy (*_2)[0 of 3]) -> [47: bb8, otherwise: bb11]; - } - - bb8: { -- switchInt(copy (*_2)[0 of 3]) -> [47: bb9, otherwise: bb7]; -+ switchInt(copy (*_2)[1 of 3]) -> [47: bb9, otherwise: bb11]; - } - - bb9: { -- switchInt(copy (*_2)[1 of 3]) -> [47: bb10, otherwise: bb7]; -+ switchInt(copy (*_2)[2 of 3]) -> [47: bb10, 33: bb10, otherwise: bb11]; - } - - bb10: { -- switchInt(copy (*_2)[2 of 3]) -> [47: bb12, 33: bb11, otherwise: bb7]; -- } -- -- bb11: { - _0 = const true; -- goto -> bb14; -+ goto -> bb12; - } - -- bb12: { -- _0 = const true; -- goto -> bb14; -- } -- -- bb13: { -+ bb11: { - _0 = const false; -- goto -> bb14; -+ goto -> bb12; - } - -- bb14: { -+ bb12: { - StorageDead(_2); - return; - } - } - diff --git a/tests/mir-opt/deduplicate_blocks.rs b/tests/mir-opt/deduplicate_blocks.rs deleted file mode 100644 index 3a164cb09a094..0000000000000 --- a/tests/mir-opt/deduplicate_blocks.rs +++ /dev/null @@ -1,17 +0,0 @@ -// skip-filecheck -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//@ test-mir-pass: DeduplicateBlocks - -// EMIT_MIR deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff -pub const fn is_line_doc_comment_2(s: &str) -> bool { - match s.as_bytes() { - [b'/', b'/', b'/', b'/', ..] => false, - [b'/', b'/', b'/', ..] => true, - [b'/', b'/', b'!', ..] => true, - _ => false, - } -} - -fn main() { - is_line_doc_comment_2("asd"); -} diff --git a/tests/ui/asm/aarch64/bad-reg.stderr b/tests/ui/asm/aarch64/bad-reg.stderr index 370752ad0f11c..c76722f32a74e 100644 --- a/tests/ui/asm/aarch64/bad-reg.stderr +++ b/tests/ui/asm/aarch64/bad-reg.stderr @@ -3,6 +3,8 @@ error: invalid register class `foo`: unknown register class | LL | asm!("{}", in(foo) foo); | ^^^^^^^^^^^ + | + = note: the following register classes are supported on this target: `reg`, `vreg`, `vreg_low16`, `preg` error: invalid register `foo`: unknown register --> $DIR/bad-reg.rs:14:18 diff --git a/tests/ui/asm/x86_64/bad-reg.stderr b/tests/ui/asm/x86_64/bad-reg.stderr index 3df1f7b220869..6a02957210bb9 100644 --- a/tests/ui/asm/x86_64/bad-reg.stderr +++ b/tests/ui/asm/x86_64/bad-reg.stderr @@ -3,6 +3,8 @@ error: invalid register class `foo`: unknown register class | LL | asm!("{}", in(foo) foo); | ^^^^^^^^^^^ + | + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` error: invalid register `foo`: unknown register --> $DIR/bad-reg.rs:14:18 diff --git a/tests/ui/asm/x86_64/issue-82869.stderr b/tests/ui/asm/x86_64/issue-82869.stderr index 3cf9d6d1c1c00..56e4909956913 100644 --- a/tests/ui/asm/x86_64/issue-82869.stderr +++ b/tests/ui/asm/x86_64/issue-82869.stderr @@ -3,12 +3,16 @@ error: invalid register class `vreg`: unknown register class | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^^ + | + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` error: invalid register class `vreg`: unknown register class --> $DIR/issue-82869.rs:11:45 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^ + | + = note: the following register classes are supported on this target: `reg`, `reg_abcd`, `reg_byte`, `xmm_reg`, `ymm_reg`, `zmm_reg`, `kreg`, `kreg0`, `mmx_reg`, `x87_reg`, `tmm_reg` error: invalid register `d0`: unknown register --> $DIR/issue-82869.rs:11:57