diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 8217b6df5b470..8279c66836c0f 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -38,7 +38,6 @@ impl<'a> State<'a> { self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs); } ast::ForeignItemKind::Static(box ast::StaticItem { ty, mutability, expr, safety }) => { - self.print_safety(*safety); self.print_item_const( ident, Some(*mutability), @@ -46,6 +45,7 @@ impl<'a> State<'a> { ty, expr.as_deref(), vis, + *safety, ast::Defaultness::Final, ) } @@ -84,10 +84,12 @@ impl<'a> State<'a> { ty: &ast::Ty, body: Option<&ast::Expr>, vis: &ast::Visibility, + safety: ast::Safety, defaultness: ast::Defaultness, ) { self.head(""); self.print_visibility(vis); + self.print_safety(safety); self.print_defaultness(defaultness); let leading = match mutbl { None => "const", @@ -181,6 +183,7 @@ impl<'a> State<'a> { ty, body.as_deref(), &item.vis, + ast::Safety::Default, ast::Defaultness::Final, ); } @@ -192,6 +195,7 @@ impl<'a> State<'a> { ty, expr.as_deref(), &item.vis, + ast::Safety::Default, *defaultness, ); } @@ -549,6 +553,7 @@ impl<'a> State<'a> { ty, expr.as_deref(), vis, + ast::Safety::Default, *defaultness, ); } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index e412417a9e95f..537d8e045311c 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -619,11 +619,11 @@ pub fn eval_condition( // we can't use `try_gate_cfg` as symbols don't differentiate between `r#true` // and `true`, and we want to keep the former working without feature gate gate_cfg( - &(( + &( if *b { kw::True } else { kw::False }, sym::cfg_boolean_literals, |features: &Features| features.cfg_boolean_literals(), - )), + ), cfg.span(), sess, features, diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 2437a43bd5a36..2fa752384a161 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -65,6 +65,7 @@ impl<'tcx> UniverseInfo<'tcx> { UniverseInfoInner::RelateTys { expected, found } => { let err = mbcx.infcx.err_ctxt().report_mismatched_types( &cause, + mbcx.param_env, expected, found, TypeError::RegionsPlaceholderMismatch, @@ -480,12 +481,11 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>( .try_report_from_nll() .or_else(|| { if let SubregionOrigin::Subtype(trace) = cause { - Some( - infcx.err_ctxt().report_and_explain_type_error( - *trace, - TypeError::RegionsPlaceholderMismatch, - ), - ) + Some(infcx.err_ctxt().report_and_explain_type_error( + *trace, + infcx.tcx.param_env(generic_param_scope), + TypeError::RegionsPlaceholderMismatch, + )) } else { None } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index a5f3298b02cc2..315851729b1e0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -959,13 +959,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { None } } - hir::ExprKind::MethodCall(_, _, args, span) => { - if let Some(def_id) = typeck_results.type_dependent_def_id(*hir_id) { - Some((def_id, *span, *args)) - } else { - None - } - } + hir::ExprKind::MethodCall(_, _, args, span) => typeck_results + .type_dependent_def_id(*hir_id) + .map(|def_id| (def_id, *span, *args)), _ => None, } }; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index a16c1931a552b..abce98265b3cb 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -360,6 +360,7 @@ fn check_opaque_type_well_formed<'tcx>( .err_ctxt() .report_mismatched_types( &ObligationCause::misc(definition_span, def_id), + param_env, opaque_ty, definition_ty, err, diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 9fc0318df5dc0..42c7f5f0dc692 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -47,12 +47,12 @@ impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} impl, U: ?Sized> DispatchFromDyn> for Box {} -#[lang = "receiver"] -pub trait Receiver {} +#[lang = "legacy_receiver"] +pub trait LegacyReceiver {} -impl Receiver for &T {} -impl Receiver for &mut T {} -impl Receiver for Box {} +impl LegacyReceiver for &T {} +impl LegacyReceiver for &mut T {} +impl LegacyReceiver for Box {} #[lang = "copy"] pub unsafe trait Copy {} diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index f47bfdad13128..0576b64ef6fa5 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -44,12 +44,12 @@ impl, U: ?Sized> DispatchFromDyn<*const U> for *const T {} impl, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {} impl, U: ?Sized> DispatchFromDyn> for Box {} -#[lang = "receiver"] -pub trait Receiver {} +#[lang = "legacy_receiver"] +pub trait LegacyReceiver {} -impl Receiver for &T {} -impl Receiver for &mut T {} -impl Receiver for Box {} +impl LegacyReceiver for &T {} +impl LegacyReceiver for &mut T {} +impl LegacyReceiver for Box {} #[lang = "copy"] pub unsafe trait Copy {} diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index 90f7dd733ca18..feac97f3e2b62 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -1,11 +1,9 @@ -use rustc_middle::mir::coverage::{ - ConditionInfo, CounterId, CovTerm, DecisionInfo, ExpressionId, MappingKind, SourceRegion, -}; +use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId, SourceRegion}; /// Must match the layout of `LLVMRustCounterKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] -pub enum CounterKind { +pub(crate) enum CounterKind { Zero = 0, CounterValueReference = 1, Expression = 2, @@ -25,9 +23,9 @@ pub enum CounterKind { /// Must match the layout of `LLVMRustCounter`. #[derive(Copy, Clone, Debug)] #[repr(C)] -pub struct Counter { +pub(crate) struct Counter { // Important: The layout (order and types of fields) must match its C++ counterpart. - pub kind: CounterKind, + pub(crate) kind: CounterKind, id: u32, } @@ -36,7 +34,7 @@ impl Counter { pub(crate) const ZERO: Self = Self { kind: CounterKind::Zero, id: 0 }; /// Constructs a new `Counter` of kind `CounterValueReference`. - pub fn counter_value_reference(counter_id: CounterId) -> Self { + pub(crate) fn counter_value_reference(counter_id: CounterId) -> Self { Self { kind: CounterKind::CounterValueReference, id: counter_id.as_u32() } } @@ -59,7 +57,7 @@ impl Counter { /// Must match the layout of `LLVMRustCounterExprKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] -pub enum ExprKind { +pub(crate) enum ExprKind { Subtract = 0, Add = 1, } @@ -69,48 +67,13 @@ pub enum ExprKind { /// Must match the layout of `LLVMRustCounterExpression`. #[derive(Copy, Clone, Debug)] #[repr(C)] -pub struct CounterExpression { - pub kind: ExprKind, - pub lhs: Counter, - pub rhs: Counter, +pub(crate) struct CounterExpression { + pub(crate) kind: ExprKind, + pub(crate) lhs: Counter, + pub(crate) rhs: Counter, } -/// Corresponds to enum `llvm::coverage::CounterMappingRegion::RegionKind`. -/// -/// Must match the layout of `LLVMRustCounterMappingRegionKind`. -#[derive(Copy, Clone, Debug)] -#[repr(C)] -enum RegionKind { - /// A CodeRegion associates some code with a counter - CodeRegion = 0, - - /// An ExpansionRegion represents a file expansion region that associates - /// a source range with the expansion of a virtual source file, such as - /// for a macro instantiation or #include file. - ExpansionRegion = 1, - - /// A SkippedRegion represents a source range with code that was skipped - /// by a preprocessor or similar means. - SkippedRegion = 2, - - /// A GapRegion is like a CodeRegion, but its count is only set as the - /// line execution count when its the only region in the line. - GapRegion = 3, - - /// A BranchRegion represents leaf-level boolean expressions and is - /// associated with two counters, each representing the number of times the - /// expression evaluates to true or false. - BranchRegion = 4, - - /// A DecisionRegion represents a top-level boolean expression and is - /// associated with a variable length bitmap index and condition number. - MCDCDecisionRegion = 5, - - /// A Branch Region can be extended to include IDs to facilitate MC/DC. - MCDCBranchRegion = 6, -} - -mod mcdc { +pub(crate) mod mcdc { use rustc_middle::mir::coverage::{ConditionId, ConditionInfo, DecisionInfo}; /// Must match the layout of `LLVMRustMCDCDecisionParameters`. @@ -121,8 +84,6 @@ mod mcdc { num_conditions: u16, } - // ConditionId in llvm is `unsigned int` at 18 while `int16_t` at - // [19](https://github.com/llvm/llvm-project/pull/81257). type LLVMConditionId = i16; /// Must match the layout of `LLVMRustMCDCBranchParameters`. @@ -133,38 +94,6 @@ mod mcdc { condition_ids: [LLVMConditionId; 2], } - #[repr(C)] - #[derive(Clone, Copy, Debug)] - enum ParameterTag { - None = 0, - Decision = 1, - Branch = 2, - } - /// Same layout with `LLVMRustMCDCParameters` - #[repr(C)] - #[derive(Clone, Copy, Debug)] - pub(crate) struct Parameters { - tag: ParameterTag, - decision_params: DecisionParameters, - branch_params: BranchParameters, - } - - impl Parameters { - pub(crate) fn none() -> Self { - Self { - tag: ParameterTag::None, - decision_params: Default::default(), - branch_params: Default::default(), - } - } - pub(crate) fn decision(decision_params: DecisionParameters) -> Self { - Self { tag: ParameterTag::Decision, decision_params, branch_params: Default::default() } - } - pub(crate) fn branch(branch_params: BranchParameters) -> Self { - Self { tag: ParameterTag::Branch, decision_params: Default::default(), branch_params } - } - } - impl From for BranchParameters { fn from(value: ConditionInfo) -> Self { let to_llvm_cond_id = |cond_id: Option| { @@ -186,267 +115,68 @@ mod mcdc { } } -/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the -/// coverage map, in accordance with the -/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format). -/// The struct composes fields representing the `Counter` type and value(s) (injected counter -/// ID, or expression type and operands), the source file (an indirect index into a "filenames -/// array", encoded separately), and source location (start and end positions of the represented -/// code region). +/// A span of source code coordinates to be embedded in coverage metadata. /// -/// Corresponds to struct `llvm::coverage::CounterMappingRegion`. -/// -/// Must match the layout of `LLVMRustCounterMappingRegion`. -#[derive(Copy, Clone, Debug)] +/// Must match the layout of `LLVMRustCoverageSpan`. +#[derive(Clone, Debug)] #[repr(C)] -pub struct CounterMappingRegion { - /// The counter type and type-dependent counter data, if any. - counter: Counter, - - /// If the `RegionKind` is a `BranchRegion`, this represents the counter - /// for the false branch of the region. - false_counter: Counter, - - mcdc_params: mcdc::Parameters, - /// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the - /// file_id is an index into a function-specific `virtual_file_mapping` array of indexes - /// that, in turn, are used to look up the filename for this region. +pub(crate) struct CoverageSpan { + /// Local index into the function's local-to-global file ID table. + /// The value at that index is itself an index into the coverage filename + /// table in the CGU's `__llvm_covmap` section. file_id: u32, - /// If the `RegionKind` is an `ExpansionRegion`, the `expanded_file_id` can be used to find - /// the mapping regions created as a result of macro expansion, by checking if their file id - /// matches the expanded file id. - expanded_file_id: u32, - - /// 1-based starting line of the mapping region. + /// 1-based starting line of the source code span. start_line: u32, - - /// 1-based starting column of the mapping region. + /// 1-based starting column of the source code span. start_col: u32, - - /// 1-based ending line of the mapping region. + /// 1-based ending line of the source code span. end_line: u32, - - /// 1-based ending column of the mapping region. If the high bit is set, the current - /// mapping region is a gap area. + /// 1-based ending column of the source code span. High bit must be unset. end_col: u32, - - kind: RegionKind, } -impl CounterMappingRegion { - pub(crate) fn from_mapping( - mapping_kind: &MappingKind, - local_file_id: u32, - source_region: &SourceRegion, - ) -> Self { - let &SourceRegion { file_name: _, start_line, start_col, end_line, end_col } = - source_region; - match *mapping_kind { - MappingKind::Code(term) => Self::code_region( - Counter::from_term(term), - local_file_id, - start_line, - start_col, - end_line, - end_col, - ), - MappingKind::Branch { true_term, false_term } => Self::branch_region( - Counter::from_term(true_term), - Counter::from_term(false_term), - local_file_id, - start_line, - start_col, - end_line, - end_col, - ), - MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => { - Self::mcdc_branch_region( - Counter::from_term(true_term), - Counter::from_term(false_term), - mcdc_params, - local_file_id, - start_line, - start_col, - end_line, - end_col, - ) - } - MappingKind::MCDCDecision(decision_info) => Self::decision_region( - decision_info, - local_file_id, - start_line, - start_col, - end_line, - end_col, - ), - } - } - - pub(crate) fn code_region( - counter: Counter, - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter, - false_counter: Counter::ZERO, - mcdc_params: mcdc::Parameters::none(), - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::CodeRegion, - } +impl CoverageSpan { + pub(crate) fn from_source_region(file_id: u32, code_region: &SourceRegion) -> Self { + let &SourceRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region; + // Internally, LLVM uses the high bit of `end_col` to distinguish between + // code regions and gap regions, so it can't be used by the column number. + assert!(end_col & (1u32 << 31) == 0, "high bit of `end_col` must be unset: {end_col:#X}"); + Self { file_id, start_line, start_col, end_line, end_col } } +} - pub(crate) fn branch_region( - counter: Counter, - false_counter: Counter, - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter, - false_counter, - mcdc_params: mcdc::Parameters::none(), - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::BranchRegion, - } - } - - pub(crate) fn mcdc_branch_region( - counter: Counter, - false_counter: Counter, - condition_info: ConditionInfo, - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter, - false_counter, - mcdc_params: mcdc::Parameters::branch(condition_info.into()), - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::MCDCBranchRegion, - } - } - - pub(crate) fn decision_region( - decision_info: DecisionInfo, - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - let mcdc_params = mcdc::Parameters::decision(decision_info.into()); - - Self { - counter: Counter::ZERO, - false_counter: Counter::ZERO, - mcdc_params, - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::MCDCDecisionRegion, - } - } +/// Must match the layout of `LLVMRustCoverageCodeRegion`. +#[derive(Clone, Debug)] +#[repr(C)] +pub(crate) struct CodeRegion { + pub(crate) span: CoverageSpan, + pub(crate) counter: Counter, +} - // This function might be used in the future; the LLVM API is still evolving, as is coverage - // support. - #[allow(dead_code)] - pub(crate) fn expansion_region( - file_id: u32, - expanded_file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter: Counter::ZERO, - false_counter: Counter::ZERO, - mcdc_params: mcdc::Parameters::none(), - file_id, - expanded_file_id, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::ExpansionRegion, - } - } +/// Must match the layout of `LLVMRustCoverageBranchRegion`. +#[derive(Clone, Debug)] +#[repr(C)] +pub(crate) struct BranchRegion { + pub(crate) span: CoverageSpan, + pub(crate) true_counter: Counter, + pub(crate) false_counter: Counter, +} - // This function might be used in the future; the LLVM API is still evolving, as is coverage - // support. - #[allow(dead_code)] - pub(crate) fn skipped_region( - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter: Counter::ZERO, - false_counter: Counter::ZERO, - mcdc_params: mcdc::Parameters::none(), - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col, - kind: RegionKind::SkippedRegion, - } - } +/// Must match the layout of `LLVMRustCoverageMCDCBranchRegion`. +#[derive(Clone, Debug)] +#[repr(C)] +pub(crate) struct MCDCBranchRegion { + pub(crate) span: CoverageSpan, + pub(crate) true_counter: Counter, + pub(crate) false_counter: Counter, + pub(crate) mcdc_branch_params: mcdc::BranchParameters, +} - // This function might be used in the future; the LLVM API is still evolving, as is coverage - // support. - #[allow(dead_code)] - pub(crate) fn gap_region( - counter: Counter, - file_id: u32, - start_line: u32, - start_col: u32, - end_line: u32, - end_col: u32, - ) -> Self { - Self { - counter, - false_counter: Counter::ZERO, - mcdc_params: mcdc::Parameters::none(), - file_id, - expanded_file_id: 0, - start_line, - start_col, - end_line, - end_col: (1_u32 << 31) | end_col, - kind: RegionKind::GapRegion, - } - } +/// Must match the layout of `LLVMRustCoverageMCDCDecisionRegion`. +#[derive(Clone, Debug)] +#[repr(C)] +pub(crate) struct MCDCDecisionRegion { + pub(crate) span: CoverageSpan, + pub(crate) mcdc_decision_params: mcdc::DecisionParameters, } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index cee704a9c220b..61e474031bb08 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -5,6 +5,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::IndexVec; +use rustc_middle::mir::coverage::MappingKind; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_span::Symbol; @@ -12,7 +13,7 @@ use rustc_span::def_id::DefIdSet; use tracing::debug; use crate::common::CodegenCx; -use crate::coverageinfo::ffi::CounterMappingRegion; +use crate::coverageinfo::ffi; use crate::coverageinfo::map_data::{FunctionCoverage, FunctionCoverageCollector}; use crate::{coverageinfo, llvm}; @@ -237,7 +238,10 @@ fn encode_mappings_for_function( let expressions = function_coverage.counter_expressions().collect::>(); let mut virtual_file_mapping = VirtualFileMapping::default(); - let mut mapping_regions = Vec::with_capacity(counter_regions.len()); + let mut code_regions = vec![]; + let mut branch_regions = vec![]; + let mut mcdc_branch_regions = vec![]; + let mut mcdc_decision_regions = vec![]; // Group mappings into runs with the same filename, preserving the order // yielded by `FunctionCoverage`. @@ -257,11 +261,36 @@ fn encode_mappings_for_function( // form suitable for FFI. for (mapping_kind, region) in counter_regions_for_file { debug!("Adding counter {mapping_kind:?} to map for {region:?}"); - mapping_regions.push(CounterMappingRegion::from_mapping( - &mapping_kind, - local_file_id.as_u32(), - region, - )); + let span = ffi::CoverageSpan::from_source_region(local_file_id.as_u32(), region); + match mapping_kind { + MappingKind::Code(term) => { + code_regions + .push(ffi::CodeRegion { span, counter: ffi::Counter::from_term(term) }); + } + MappingKind::Branch { true_term, false_term } => { + branch_regions.push(ffi::BranchRegion { + span, + true_counter: ffi::Counter::from_term(true_term), + false_counter: ffi::Counter::from_term(false_term), + }); + } + MappingKind::MCDCBranch { true_term, false_term, mcdc_params } => { + mcdc_branch_regions.push(ffi::MCDCBranchRegion { + span, + true_counter: ffi::Counter::from_term(true_term), + false_counter: ffi::Counter::from_term(false_term), + mcdc_branch_params: ffi::mcdc::BranchParameters::from(mcdc_params), + }); + } + MappingKind::MCDCDecision(mcdc_decision_params) => { + mcdc_decision_regions.push(ffi::MCDCDecisionRegion { + span, + mcdc_decision_params: ffi::mcdc::DecisionParameters::from( + mcdc_decision_params, + ), + }); + } + } } } @@ -270,7 +299,10 @@ fn encode_mappings_for_function( coverageinfo::write_mapping_to_buffer( virtual_file_mapping.into_vec(), expressions, - mapping_regions, + &code_regions, + &branch_regions, + &mcdc_branch_regions, + &mcdc_decision_regions, buffer, ); }) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 484a4d00c13ee..b2956945911b1 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -18,7 +18,6 @@ use tracing::{debug, instrument}; use crate::builder::Builder; use crate::common::CodegenCx; -use crate::coverageinfo::ffi::{CounterExpression, CounterMappingRegion}; use crate::coverageinfo::map_data::FunctionCoverageCollector; use crate::llvm; @@ -257,8 +256,11 @@ pub(crate) fn write_filenames_section_to_buffer<'a>( pub(crate) fn write_mapping_to_buffer( virtual_file_mapping: Vec, - expressions: Vec, - mapping_regions: Vec, + expressions: Vec, + code_regions: &[ffi::CodeRegion], + branch_regions: &[ffi::BranchRegion], + mcdc_branch_regions: &[ffi::MCDCBranchRegion], + mcdc_decision_regions: &[ffi::MCDCDecisionRegion], buffer: &RustString, ) { unsafe { @@ -267,8 +269,14 @@ pub(crate) fn write_mapping_to_buffer( virtual_file_mapping.len() as c_uint, expressions.as_ptr(), expressions.len() as c_uint, - mapping_regions.as_ptr(), - mapping_regions.len() as c_uint, + code_regions.as_ptr(), + code_regions.len() as c_uint, + branch_regions.as_ptr(), + branch_regions.len() as c_uint, + mcdc_branch_regions.as_ptr(), + mcdc_branch_regions.len() as c_uint, + mcdc_decision_regions.as_ptr(), + mcdc_decision_regions.len() as c_uint, buffer, ); } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index d0034de06c726..50e6c1494a8d6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1744,7 +1744,7 @@ unsafe extern "C" { ) -> bool; #[allow(improper_ctypes)] - pub fn LLVMRustCoverageWriteFilenamesSectionToBuffer( + pub(crate) fn LLVMRustCoverageWriteFilenamesSectionToBuffer( Filenames: *const *const c_char, FilenamesLen: size_t, Lengths: *const size_t, @@ -1753,33 +1753,39 @@ unsafe extern "C" { ); #[allow(improper_ctypes)] - pub fn LLVMRustCoverageWriteMappingToBuffer( + pub(crate) fn LLVMRustCoverageWriteMappingToBuffer( VirtualFileMappingIDs: *const c_uint, NumVirtualFileMappingIDs: c_uint, Expressions: *const crate::coverageinfo::ffi::CounterExpression, NumExpressions: c_uint, - MappingRegions: *const crate::coverageinfo::ffi::CounterMappingRegion, - NumMappingRegions: c_uint, + CodeRegions: *const crate::coverageinfo::ffi::CodeRegion, + NumCodeRegions: c_uint, + BranchRegions: *const crate::coverageinfo::ffi::BranchRegion, + NumBranchRegions: c_uint, + MCDCBranchRegions: *const crate::coverageinfo::ffi::MCDCBranchRegion, + NumMCDCBranchRegions: c_uint, + MCDCDecisionRegions: *const crate::coverageinfo::ffi::MCDCDecisionRegion, + NumMCDCDecisionRegions: c_uint, BufferOut: &RustString, ); - pub fn LLVMRustCoverageCreatePGOFuncNameVar( + pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar( F: &Value, FuncName: *const c_char, FuncNameLen: size_t, ) -> &Value; - pub fn LLVMRustCoverageHashByteArray(Bytes: *const c_char, NumBytes: size_t) -> u64; + pub(crate) fn LLVMRustCoverageHashByteArray(Bytes: *const c_char, NumBytes: size_t) -> u64; #[allow(improper_ctypes)] - pub fn LLVMRustCoverageWriteMapSectionNameToString(M: &Module, Str: &RustString); + pub(crate) fn LLVMRustCoverageWriteMapSectionNameToString(M: &Module, Str: &RustString); #[allow(improper_ctypes)] - pub fn LLVMRustCoverageWriteFuncSectionNameToString(M: &Module, Str: &RustString); + pub(crate) fn LLVMRustCoverageWriteFuncSectionNameToString(M: &Module, Str: &RustString); #[allow(improper_ctypes)] - pub fn LLVMRustCoverageWriteMappingVarNameToString(Str: &RustString); + pub(crate) fn LLVMRustCoverageWriteMappingVarNameToString(Str: &RustString); - pub fn LLVMRustCoverageMappingVersion() -> u32; + pub(crate) fn LLVMRustCoverageMappingVersion() -> u32; pub fn LLVMRustDebugMetadataVersion() -> u32; pub fn LLVMRustVersionMajor() -> u32; pub fn LLVMRustVersionMinor() -> u32; diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index b161e6ba0fa51..ae046c09ebea3 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -241,7 +241,7 @@ language_item_table! { DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0); DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0); DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None; - Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None; + LegacyReceiver, sym::legacy_receiver, legacy_receiver_trait, Target::Trait, GenericRequirement::None; Fn, kw::Fn, fn_trait, Target::Trait, GenericRequirement::Exact(1); FnMut, sym::fn_mut, fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index fc5ec31cda80c..7a56b3784f8b3 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -282,6 +282,7 @@ fn compare_method_predicate_entailment<'tcx>( let emitted = report_trait_method_mismatch( infcx, cause, + param_env, terr, (trait_m, trait_sig), (impl_m, impl_sig), @@ -575,10 +576,10 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( hir.get_if_local(impl_m.def_id) .and_then(|node| node.fn_decl()) .map(|decl| (decl.output.span(), Cow::from("return type in trait"), false)), - Some(infer::ValuePairs::Terms(ExpectedFound { + Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound { expected: trait_return_ty.into(), found: impl_return_ty.into(), - })), + }))), terr, false, ); @@ -602,6 +603,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( let emitted = report_trait_method_mismatch( infcx, cause, + param_env, terr, (trait_m, trait_sig), (impl_m, impl_sig), @@ -915,6 +917,7 @@ impl<'tcx> ty::FallibleTypeFolder> for RemapHiddenTyRegions<'tcx> { fn report_trait_method_mismatch<'tcx>( infcx: &InferCtxt<'tcx>, mut cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, terr: TypeError<'tcx>, (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>), (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>), @@ -1000,10 +1003,10 @@ fn report_trait_method_mismatch<'tcx>( &mut diag, &cause, trait_err_span.map(|sp| (sp, Cow::from("type in trait"), false)), - Some(infer::ValuePairs::PolySigs(ExpectedFound { + Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { expected: ty::Binder::dummy(trait_sig), found: ty::Binder::dummy(impl_sig), - })), + }))), terr, false, ); @@ -1797,10 +1800,10 @@ fn compare_const_predicate_entailment<'tcx>( &mut diag, &cause, trait_c_span.map(|span| (span, Cow::from("type in trait"), false)), - Some(infer::ValuePairs::Terms(ExpectedFound { + Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound { expected: trait_ty.into(), found: impl_ty.into(), - })), + }))), terr, false, ); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 959b17b2d4073..f2f9c69e49f70 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -646,10 +646,10 @@ pub fn check_function_signature<'tcx>( &mut diag, &cause, None, - Some(infer::ValuePairs::PolySigs(ExpectedFound { + Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { expected: expected_sig, found: actual_sig, - })), + }))), err, false, ); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 3170c0ac9907d..d70e8673c5203 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1801,7 +1801,7 @@ fn receiver_is_valid<'tcx>( autoderef = autoderef.include_raw_pointers(); } - let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span)); + let receiver_trait_def_id = tcx.require_lang_item(LangItem::LegacyReceiver, Some(span)); // Keep dereferencing `receiver_ty` until we get to `self_ty`. while let Some((potential_self_ty, _)) = autoderef.next() { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 76c75d976ee0f..b4f6b5a9dd24f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -364,6 +364,7 @@ pub(crate) fn coerce_unsized_info<'tcx>( .err_ctxt() .report_mismatched_types( &cause, + param_env, mk_ptr(mt_b.ty), target, ty::error::TypeError::Mutability, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index fa6a86c691188..06e2a5e349340 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -862,7 +862,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Err(e) => { // FIXME(effects): better diagnostic - self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit(); + self.err_ctxt() + .report_mismatched_consts(&cause, self.param_env, effect, param, e) + .emit(); } } } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index f7306063c1603..483a8d1d9a9dc 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -876,20 +876,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { // A + SrcAuto> -> B + DstAuto>. need to make sure // - `Src` and `Dst` traits are the same // - traits have the same generic arguments - // - `SrcAuto` is a superset of `DstAuto` - (Some(src_principal), Some(dst_principal)) => { + // - projections are the same + // - `SrcAuto` (+auto traits implied by `Src`) is a superset of `DstAuto` + // + // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) + // and is unaffected by this check. + (Some(src_principal), Some(_)) => { let tcx = fcx.tcx; - // Check that the traits are actually the same. - // The `dyn Src = dyn Dst` check below would suffice, - // but this may produce a better diagnostic. - // - // Note that trait upcasting goes through a different mechanism (`coerce_unsized`) - // and is unaffected by this check. - if src_principal.def_id() != dst_principal.def_id() { - return Err(CastError::DifferingKinds { src_kind, dst_kind }); - } - // We need to reconstruct trait object types. // `m_src` and `m_dst` won't work for us here because they will potentially // contain wrappers, which we do not care about. @@ -912,8 +906,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { ty::Dyn, )); - // `dyn Src = dyn Dst`, this checks for matching traits/generics - // This is `demand_eqtype`, but inlined to give a better error. + // `dyn Src = dyn Dst`, this checks for matching traits/generics/projections + // This is `fcx.demand_eqtype`, but inlined to give a better error. let cause = fcx.misc(self.span); if fcx .at(&cause, fcx.param_env) @@ -965,8 +959,35 @@ impl<'a, 'tcx> CastCheck<'tcx> { // dyn Auto -> dyn Auto'? ok. (None, None) => Ok(CastKind::PtrPtrCast), - // dyn Trait -> dyn Auto? should be ok, but we used to not allow it. - // FIXME: allow this + // dyn Trait -> dyn Auto? not ok (for now). + // + // Although dropping the principal is already allowed for unsizing coercions + // (e.g. `*const (dyn Trait + Auto)` to `*const dyn Auto`), dropping it is + // currently **NOT** allowed for (non-coercion) ptr-to-ptr casts (e.g + // `*const Foo` to `*const Bar` where `Foo` has a `dyn Trait + Auto` tail + // and `Bar` has a `dyn Auto` tail), because the underlying MIR operations + // currently work very differently: + // + // * A MIR unsizing coercion on raw pointers to trait objects (`*const dyn Src` + // to `*const dyn Dst`) is currently equivalent to downcasting the source to + // the concrete sized type that it was originally unsized from first (via a + // ptr-to-ptr cast from `*const Src` to `*const T` with `T: Sized`) and then + // unsizing this thin pointer to the target type (unsizing `*const T` to + // `*const Dst`). In particular, this means that the pointer's metadata + // (vtable) will semantically change, e.g. for const eval and miri, even + // though the vtables will always be merged for codegen. + // + // * A MIR ptr-to-ptr cast is currently equivalent to a transmute and does not + // change the pointer metadata (vtable) at all. + // + // In addition to this potentially surprising difference between coercion and + // non-coercion casts, casting away the principal with a MIR ptr-to-ptr cast + // is currently considered undefined behavior: + // + // As a validity invariant of pointers to trait objects, we currently require + // that the principal of the vtable in the pointer metadata exactly matches + // the principal of the pointee type, where "no principal" is also considered + // a kind of principal. (Some(_), None) => Err(CastError::DifferingKinds { src_kind, dst_kind }), // dyn Auto -> dyn Trait? not ok. diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index de80ccf790c1b..6fa958d949602 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1723,6 +1723,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { }) => { err = fcx.err_ctxt().report_mismatched_types( cause, + fcx.param_env, expected, found, coercion_error, @@ -1752,6 +1753,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { }) => { err = fcx.err_ctxt().report_mismatched_types( cause, + fcx.param_env, expected, found, coercion_error, @@ -1787,6 +1789,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { _ => { err = fcx.err_ctxt().report_mismatched_types( cause, + fcx.param_env, expected, found, coercion_error, @@ -1897,7 +1900,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { block_or_return_id: hir::HirId, expression: Option<&'tcx hir::Expr<'tcx>>, ) -> Diag<'infcx> { - let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err); + let mut err = + fcx.err_ctxt().report_mismatched_types(cause, fcx.param_env, expected, found, ty_err); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 777248ff873de..3399a9fe88078 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -191,7 +191,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.at(cause, self.param_env) .sup(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) - .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e)) + .map_err(|e| { + self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e) + }) } pub(crate) fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { @@ -218,7 +220,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.at(cause, self.param_env) .eq(DefineOpaqueTypes::Yes, expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) - .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e)) + .map_err(|e| { + self.err_ctxt().report_mismatched_types(cause, self.param_env, expected, actual, e) + }) } pub(crate) fn demand_coerce( @@ -271,7 +275,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expr = expr.peel_drop_temps(); let cause = self.misc(expr.span); let expr_ty = self.resolve_vars_if_possible(checked_ty); - let mut err = self.err_ctxt().report_mismatched_types(&cause, expected, expr_ty, e); + let mut err = + self.err_ctxt().report_mismatched_types(&cause, self.param_env, expected, expr_ty, e); self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e)); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index f29d6199a875e..a6c249da103f3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -827,6 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { formal_and_expected_inputs[mismatch_idx.into()], provided_arg_tys[mismatch_idx.into()].0, ), + self.param_env, terr, ); err.span_label( @@ -912,7 +913,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty); if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308) { - let mut err = self.err_ctxt().report_and_explain_type_error(trace, *e); + let mut err = + self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *e); suggest_confusable(&mut err); reported = Some(err.emit()); return false; @@ -940,7 +942,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx]; let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx]; let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty); - let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err); + let mut err = + self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *err); self.emit_coerce_suggestions( &mut err, provided_args[*provided_idx], @@ -1113,7 +1116,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &mut err, &trace.cause, None, - Some(trace.values), + Some(self.param_env.and(trace.values)), e, true, ); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index f4685725dd30f..96784fcb61b2c 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -538,7 +538,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // to the feature, like the self type can't reference method args. if self.tcx.features().arbitrary_self_types() { self.err_ctxt() - .report_mismatched_types(&cause, method_self_ty, self_ty, terr) + .report_mismatched_types( + &cause, + self.param_env, + method_self_ty, + self_ty, + terr, + ) .emit(); } else { // This has/will have errored in wfcheck, which we cannot depend on from here, as typeck on functions diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 9dd5954114860..eaf40a193a634 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -537,7 +537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && binding_id != self.binding_id { if self.check_and_add_sugg_binding(LetStmt { - ty_hir_id_opt: if let Some(ty) = ty { Some(ty.hir_id) } else { None }, + ty_hir_id_opt: ty.map(|ty| ty.hir_id), binding_id, span: pat.span, init_hir_id: init.hir_id, diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 779ce976becc0..2086483b94a71 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -187,10 +187,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> { value_count: usize, ) -> (Range, Vec) { let range = TyVid::from_usize(value_count)..TyVid::from_usize(self.num_vars()); - ( - range.start..range.end, - (range.start..range.end).map(|index| self.var_origin(index)).collect(), - ) + (range.clone(), range.map(|index| self.var_origin(index)).collect()) } /// Returns indices of all variables that are not yet diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index cda81d4a9b5b2..b32af5e5e75cc 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -33,45 +33,6 @@ static coverage::Counter fromRust(LLVMRustCounter Counter) { report_fatal_error("Bad LLVMRustCounterKind!"); } -// FFI equivalent of enum `llvm::coverage::CounterMappingRegion::RegionKind` -// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L213-L234 -enum class LLVMRustCounterMappingRegionKind { - CodeRegion = 0, - ExpansionRegion = 1, - SkippedRegion = 2, - GapRegion = 3, - BranchRegion = 4, - MCDCDecisionRegion = 5, - MCDCBranchRegion = 6 -}; - -static coverage::CounterMappingRegion::RegionKind -fromRust(LLVMRustCounterMappingRegionKind Kind) { - switch (Kind) { - case LLVMRustCounterMappingRegionKind::CodeRegion: - return coverage::CounterMappingRegion::CodeRegion; - case LLVMRustCounterMappingRegionKind::ExpansionRegion: - return coverage::CounterMappingRegion::ExpansionRegion; - case LLVMRustCounterMappingRegionKind::SkippedRegion: - return coverage::CounterMappingRegion::SkippedRegion; - case LLVMRustCounterMappingRegionKind::GapRegion: - return coverage::CounterMappingRegion::GapRegion; - case LLVMRustCounterMappingRegionKind::BranchRegion: - return coverage::CounterMappingRegion::BranchRegion; - case LLVMRustCounterMappingRegionKind::MCDCDecisionRegion: - return coverage::CounterMappingRegion::MCDCDecisionRegion; - case LLVMRustCounterMappingRegionKind::MCDCBranchRegion: - return coverage::CounterMappingRegion::MCDCBranchRegion; - } - report_fatal_error("Bad LLVMRustCounterMappingRegionKind!"); -} - -enum LLVMRustMCDCParametersTag { - None = 0, - Decision = 1, - Branch = 2, -}; - struct LLVMRustMCDCDecisionParameters { uint32_t BitmapIdx; uint16_t NumConditions; @@ -82,47 +43,58 @@ struct LLVMRustMCDCBranchParameters { int16_t ConditionIDs[2]; }; -struct LLVMRustMCDCParameters { - LLVMRustMCDCParametersTag Tag; - LLVMRustMCDCDecisionParameters DecisionParameters; - LLVMRustMCDCBranchParameters BranchParameters; -}; - #if LLVM_VERSION_GE(19, 0) -static coverage::mcdc::Parameters fromRust(LLVMRustMCDCParameters Params) { - switch (Params.Tag) { - case LLVMRustMCDCParametersTag::None: - return std::monostate(); - case LLVMRustMCDCParametersTag::Decision: - return coverage::mcdc::DecisionParameters( - Params.DecisionParameters.BitmapIdx, - Params.DecisionParameters.NumConditions); - case LLVMRustMCDCParametersTag::Branch: - return coverage::mcdc::BranchParameters( - static_cast( - Params.BranchParameters.ConditionID), - {static_cast( - Params.BranchParameters.ConditionIDs[0]), - static_cast( - Params.BranchParameters.ConditionIDs[1])}); - } - report_fatal_error("Bad LLVMRustMCDCParametersTag!"); +static coverage::mcdc::BranchParameters +fromRust(LLVMRustMCDCBranchParameters Params) { + return coverage::mcdc::BranchParameters( + Params.ConditionID, {Params.ConditionIDs[0], Params.ConditionIDs[1]}); +} + +static coverage::mcdc::DecisionParameters +fromRust(LLVMRustMCDCDecisionParameters Params) { + return coverage::mcdc::DecisionParameters(Params.BitmapIdx, + Params.NumConditions); } #endif -// FFI equivalent of struct `llvm::coverage::CounterMappingRegion` -// https://github.com/rust-lang/llvm-project/blob/ea6fa9c2/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L211-L304 -struct LLVMRustCounterMappingRegion { - LLVMRustCounter Count; - LLVMRustCounter FalseCount; - LLVMRustMCDCParameters MCDCParameters; +// Must match the layout of +// `rustc_codegen_llvm::coverageinfo::ffi::CoverageSpan`. +struct LLVMRustCoverageSpan { uint32_t FileID; - uint32_t ExpandedFileID; uint32_t LineStart; uint32_t ColumnStart; uint32_t LineEnd; uint32_t ColumnEnd; - LLVMRustCounterMappingRegionKind Kind; +}; + +// Must match the layout of `rustc_codegen_llvm::coverageinfo::ffi::CodeRegion`. +struct LLVMRustCoverageCodeRegion { + LLVMRustCoverageSpan Span; + LLVMRustCounter Count; +}; + +// Must match the layout of +// `rustc_codegen_llvm::coverageinfo::ffi::BranchRegion`. +struct LLVMRustCoverageBranchRegion { + LLVMRustCoverageSpan Span; + LLVMRustCounter TrueCount; + LLVMRustCounter FalseCount; +}; + +// Must match the layout of +// `rustc_codegen_llvm::coverageinfo::ffi::MCDCBranchRegion`. +struct LLVMRustCoverageMCDCBranchRegion { + LLVMRustCoverageSpan Span; + LLVMRustCounter TrueCount; + LLVMRustCounter FalseCount; + LLVMRustMCDCBranchParameters MCDCBranchParams; +}; + +// Must match the layout of +// `rustc_codegen_llvm::coverageinfo::ffi::MCDCDecisionRegion`. +struct LLVMRustCoverageMCDCDecisionRegion { + LLVMRustCoverageSpan Span; + LLVMRustMCDCDecisionParameters MCDCDecisionParams; }; // FFI equivalent of enum `llvm::coverage::CounterExpression::ExprKind` @@ -174,28 +146,16 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( extern "C" void LLVMRustCoverageWriteMappingToBuffer( const unsigned *VirtualFileMappingIDs, unsigned NumVirtualFileMappingIDs, const LLVMRustCounterExpression *RustExpressions, unsigned NumExpressions, - const LLVMRustCounterMappingRegion *RustMappingRegions, - unsigned NumMappingRegions, RustStringRef BufferOut) { + const LLVMRustCoverageCodeRegion *CodeRegions, unsigned NumCodeRegions, + const LLVMRustCoverageBranchRegion *BranchRegions, + unsigned NumBranchRegions, + const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions, + unsigned NumMCDCBranchRegions, + const LLVMRustCoverageMCDCDecisionRegion *MCDCDecisionRegions, + unsigned NumMCDCDecisionRegions, RustStringRef BufferOut) { // Convert from FFI representation to LLVM representation. - SmallVector MappingRegions; - MappingRegions.reserve(NumMappingRegions); - for (const auto &Region : ArrayRef( - RustMappingRegions, NumMappingRegions)) { - MappingRegions.emplace_back( - fromRust(Region.Count), fromRust(Region.FalseCount), -#if LLVM_VERSION_LT(19, 0) - coverage::CounterMappingRegion::MCDCParameters{}, -#endif - Region.FileID, Region.ExpandedFileID, // File IDs, then region info. - Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd, - fromRust(Region.Kind) -#if LLVM_VERSION_GE(19, 0) - , - fromRust(Region.MCDCParameters) -#endif - ); - } + // Expressions: std::vector Expressions; Expressions.reserve(NumExpressions); for (const auto &Expression : @@ -205,6 +165,46 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer( fromRust(Expression.RHS)); } + std::vector MappingRegions; + MappingRegions.reserve(NumCodeRegions + NumBranchRegions + + NumMCDCBranchRegions + NumMCDCDecisionRegions); + + // Code regions: + for (const auto &Region : ArrayRef(CodeRegions, NumCodeRegions)) { + MappingRegions.push_back(coverage::CounterMappingRegion::makeRegion( + fromRust(Region.Count), Region.Span.FileID, Region.Span.LineStart, + Region.Span.ColumnStart, Region.Span.LineEnd, Region.Span.ColumnEnd)); + } + + // Branch regions: + for (const auto &Region : ArrayRef(BranchRegions, NumBranchRegions)) { + MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion( + fromRust(Region.TrueCount), fromRust(Region.FalseCount), + Region.Span.FileID, Region.Span.LineStart, Region.Span.ColumnStart, + Region.Span.LineEnd, Region.Span.ColumnEnd)); + } + +#if LLVM_VERSION_GE(19, 0) + // MC/DC branch regions: + for (const auto &Region : ArrayRef(MCDCBranchRegions, NumMCDCBranchRegions)) { + MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion( + fromRust(Region.TrueCount), fromRust(Region.FalseCount), + Region.Span.FileID, Region.Span.LineStart, Region.Span.ColumnStart, + Region.Span.LineEnd, Region.Span.ColumnEnd, + fromRust(Region.MCDCBranchParams))); + } + + // MC/DC decision regions: + for (const auto &Region : + ArrayRef(MCDCDecisionRegions, NumMCDCDecisionRegions)) { + MappingRegions.push_back(coverage::CounterMappingRegion::makeDecisionRegion( + fromRust(Region.MCDCDecisionParams), Region.Span.FileID, + Region.Span.LineStart, Region.Span.ColumnStart, Region.Span.LineEnd, + Region.Span.ColumnEnd)); + } +#endif + + // Write the converted expressions and mappings to a byte buffer. auto CoverageMappingWriter = coverage::CoverageMappingWriter( ArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), Expressions, MappingRegions); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 2a3a070a6e715..faa022b50ef13 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -277,9 +277,9 @@ pub fn create_dump_file<'tcx>( ) })?; } - Ok(fs::File::create_buffered(&file_path).map_err(|e| { + fs::File::create_buffered(&file_path).map_err(|e| { io::Error::new(e.kind(), format!("IO error creating MIR dump file: {file_path:?}; {e}")) - })?) + }) } /////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 5faefe2f25f41..e282345647731 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -281,7 +281,14 @@ impl<'tcx> Cx<'tcx> { .unwrap_or_else(|e| panic!("could not compute layout for {param_env_ty:?}: {e:?}")) .size; - let lit = ScalarInt::try_from_uint(discr_offset as u128, size).unwrap(); + let (lit, overflowing) = ScalarInt::truncate_from_uint(discr_offset as u128, size); + if overflowing { + // An erroneous enum with too many variants for its repr will emit E0081 and E0370 + self.tcx.dcx().span_delayed_bug( + source.span, + "overflowing enum wasn't rejected by hir analysis", + ); + } let kind = ExprKind::NonHirLiteral { lit, user_ty: None }; let offset = self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind }); diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index bc86ae22a0dbd..2db7c6cf1d6fd 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -363,7 +363,7 @@ fn calc_test_vectors_index(conditions: &mut Vec) -> usize { let ConditionInfo { condition_id, true_next_id, false_next_id } = branch.condition_info; [true_next_id, false_next_id] .into_iter() - .filter_map(std::convert::identity) + .flatten() .for_each(|next_id| indegree_stats[next_id] += 1); (condition_id, branch) }) diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index da7d20cf19a68..085c738f1f9fc 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -87,7 +87,7 @@ fn remove_unwanted_expansion_spans(covspans: &mut Vec) { covspans.retain(|covspan| { match covspan.expn_kind { // Retain only the first await-related or macro-expanded covspan with this span. - Some(ExpnKind::Desugaring(kind)) if kind == DesugaringKind::Await => { + Some(ExpnKind::Desugaring(DesugaringKind::Await)) => { deduplicated_spans.insert(covspan.span) } Some(ExpnKind::Macro(MacroKind::Bang, _)) => deduplicated_spans.insert(covspan.span), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8644284482385..61e196bdebe66 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2300,10 +2300,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &mut diag, &cause, None, - Some(ValuePairs::PolySigs(ExpectedFound { + Some(param_env.and(ValuePairs::PolySigs(ExpectedFound { expected: ty::Binder::dummy(expected_sig), found: ty::Binder::dummy(sig), - })), + }))), terr, false, ); diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 29a28b10a068e..0665401df8e84 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -111,13 +111,8 @@ impl<'a> HashStable> for SourceFile { impl<'tcx> HashStable> for rustc_feature::Features { fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { // Unfortunately we cannot exhaustively list fields here, since the - // struct is macro generated. + // struct has private fields (to ensure its invariant is maintained) self.enabled_lang_features().hash_stable(hcx, hasher); self.enabled_lib_features().hash_stable(hcx, hasher); - - // FIXME: why do we hash something that is a compile-time constant? - for feature in rustc_feature::UNSTABLE_LANG_FEATURES.iter() { - feature.name.hash_stable(hcx, hasher); - } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 3ab482072b8f4..aa05b88ea0c40 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1133,6 +1133,7 @@ symbols! { lazy_normalization_consts, lazy_type_alias, le, + legacy_receiver, len, let_chains, let_else, @@ -1573,7 +1574,6 @@ symbols! { readonly, realloc, reason, - receiver, recursion_limit, reexport_test_harness_main, ref_pat_eat_one_layer_2024, diff --git a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs index 2519b935c03a7..7648f81fd4d9a 100644 --- a/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs @@ -21,6 +21,7 @@ pub(crate) fn target() -> Target { "-Vgcc_ntox86_cxx", ]), env: "nto70".into(), + vendor: "pc".into(), stack_probes: StackProbeType::Inline, ..base::nto_qnx::opts() }, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs index 1aa82494a499e..245a5f0676547 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs @@ -21,6 +21,7 @@ pub(crate) fn target() -> Target { "-Vgcc_ntox86_64_cxx", ]), env: "nto71".into(), + vendor: "pc".into(), ..base::nto_qnx::opts() }, } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index df5800ab58a66..b9a569d25e324 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -75,6 +75,7 @@ use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags}; use crate::infer; use crate::infer::relate::{self, RelateResult, TypeRelation}; use crate::infer::{InferCtxt, TypeTrace, ValuePairs}; +use crate::solve::deeply_normalize_for_diagnostics; use crate::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, }; @@ -145,21 +146,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn report_mismatched_types( &self, cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, err: TypeError<'tcx>, ) -> Diag<'a> { - self.report_and_explain_type_error(TypeTrace::types(cause, true, expected, actual), err) + self.report_and_explain_type_error( + TypeTrace::types(cause, true, expected, actual), + param_env, + err, + ) } pub fn report_mismatched_consts( &self, cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, expected: ty::Const<'tcx>, actual: ty::Const<'tcx>, err: TypeError<'tcx>, ) -> Diag<'a> { - self.report_and_explain_type_error(TypeTrace::consts(cause, true, expected, actual), err) + self.report_and_explain_type_error( + TypeTrace::consts(cause, true, expected, actual), + param_env, + err, + ) } pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option> { @@ -1133,7 +1144,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { diag: &mut Diag<'_>, cause: &ObligationCause<'tcx>, secondary_span: Option<(Span, Cow<'static, str>, bool)>, - mut values: Option>, + mut values: Option>>, terr: TypeError<'tcx>, prefer_label: bool, ) { @@ -1241,8 +1252,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } let (expected_found, exp_found, is_simple_error, values) = match values { None => (None, Mismatch::Fixed("type"), false, None), - Some(values) => { - let values = self.resolve_vars_if_possible(values); + Some(ty::ParamEnvAnd { param_env, value: values }) => { + let mut values = self.resolve_vars_if_possible(values); + if self.next_trait_solver() { + values = deeply_normalize_for_diagnostics(self, param_env, values); + } let (is_simple_error, exp_found) = match values { ValuePairs::Terms(ExpectedFound { expected, found }) => { match (expected.unpack(), found.unpack()) { @@ -1773,6 +1787,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { pub fn report_and_explain_type_error( &self, trace: TypeTrace<'tcx>, + param_env: ty::ParamEnv<'tcx>, terr: TypeError<'tcx>, ) -> Diag<'a> { debug!("report_and_explain_type_error(trace={:?}, terr={:?})", trace, terr); @@ -1784,7 +1799,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.type_error_additional_suggestions(&trace, terr), ); let mut diag = self.dcx().create_err(failure_code); - self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false); + self.note_type_err( + &mut diag, + &trace.cause, + None, + Some(param_env.and(trace.values)), + terr, + false, + ); diag } 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 94610a9e0e653..833358b2e14d2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -295,7 +295,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut err = match origin { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); - let mut err = self.report_and_explain_type_error(trace, terr); + let mut err = self.report_and_explain_type_error( + trace, + self.tcx.param_env(generic_param_scope), + terr, + ); match (*sub, *sup) { (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} (ty::RePlaceholder(_), _) => { @@ -646,7 +650,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } infer::Subtype(box trace) => { let terr = TypeError::RegionsPlaceholderMismatch; - return self.report_and_explain_type_error(trace, terr); + return self.report_and_explain_type_error( + trace, + self.tcx.param_env(generic_param_scope), + terr, + ); } _ => { return self.report_concrete_failure( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 9ee4963a3603b..6ef64c3ed80a8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1290,7 +1290,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ( Some(( data.projection_term, - false, self.resolve_vars_if_possible(normalized_term), data.term, )), @@ -1335,7 +1334,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { derive_better_type_error(lhs, rhs) { ( - Some((lhs, true, self.resolve_vars_if_possible(expected_term), rhs)), + Some((lhs, self.resolve_vars_if_possible(expected_term), rhs)), better_type_err, ) } else if let Some(rhs) = rhs.to_alias_term() @@ -1343,7 +1342,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { derive_better_type_error(rhs, lhs) { ( - Some((rhs, true, self.resolve_vars_if_possible(expected_term), lhs)), + Some((rhs, self.resolve_vars_if_possible(expected_term), lhs)), better_type_err, ) } else { @@ -1354,7 +1353,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let msg = values - .and_then(|(predicate, _, normalized_term, expected_term)| { + .and_then(|(predicate, normalized_term, expected_term)| { self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term) }) .unwrap_or_else(|| { @@ -1431,8 +1430,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &mut diag, &obligation.cause, secondary_span, - values.map(|(_, _, normalized_ty, expected_ty)| { - infer::ValuePairs::Terms(ExpectedFound::new(true, expected_ty, normalized_ty)) + values.map(|(_, normalized_ty, expected_ty)| { + obligation.param_env.and(infer::ValuePairs::Terms(ExpectedFound::new( + true, + expected_ty, + normalized_ty, + ))) }), err, false, @@ -2654,6 +2657,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; self.report_and_explain_type_error( TypeTrace::trait_refs(&cause, true, expected_trait_ref, found_trait_ref), + obligation.param_env, terr, ) } @@ -2744,6 +2748,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { { return Ok(self.report_and_explain_type_error( TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref), + obligation.param_env, ty::error::TypeError::Mismatch, )); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index ba57909fc23a6..ca23f7765819f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -287,6 +287,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { FulfillmentErrorCode::Subtype(ref expected_found, ref err) => self .report_mismatched_types( &error.obligation.cause, + error.obligation.param_env, expected_found.expected, expected_found.found, *err, @@ -295,6 +296,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { FulfillmentErrorCode::ConstEquate(ref expected_found, ref err) => { let mut diag = self.report_mismatched_consts( &error.obligation.cause, + error.obligation.param_env, expected_found.expected, expected_found.found, *err, diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 3e791416820ef..bc354650a8ebc 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -196,7 +196,7 @@ use core::marker::{Tuple, Unsize}; use core::mem::{self, SizedTypeProperties}; use core::ops::{ AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, - DerefPure, DispatchFromDyn, Receiver, + DerefPure, DispatchFromDyn, LegacyReceiver, }; use core::pin::{Pin, PinCoerceUnsized}; use core::ptr::{self, NonNull, Unique}; @@ -2378,8 +2378,8 @@ impl DerefMut for Box { #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Box {} -#[unstable(feature = "receiver_trait", issue = "none")] -impl Receiver for Box {} +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for Box {} #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Box { diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 50a5f3c5b1e04..dd9dfa3f5e26d 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -129,6 +129,7 @@ #![feature(iter_advance_by)] #![feature(iter_next_chunk)] #![feature(layout_for_ptr)] +#![feature(legacy_receiver_trait)] #![feature(local_waker)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array_transpose)] @@ -138,7 +139,6 @@ #![feature(ptr_internals)] #![feature(ptr_metadata)] #![feature(ptr_sub_ptr)] -#![feature(receiver_trait)] #![feature(set_ptr_value)] #![feature(sized_type_properties)] #![feature(slice_from_ptr_range)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 582d850e14b6d..128503284cd83 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -252,7 +252,7 @@ use core::intrinsics::abort; use core::iter; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; -use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver}; +use core::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; use core::panic::{RefUnwindSafe, UnwindSafe}; #[cfg(not(no_global_oom_handling))] use core::pin::Pin; @@ -2222,8 +2222,8 @@ unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Rc {} -#[unstable(feature = "receiver_trait", issue = "none")] -impl Receiver for Rc {} +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for Rc {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 13677245e98c2..220b79eaf8aec 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -18,7 +18,7 @@ use core::intrinsics::abort; use core::iter; use core::marker::{PhantomData, Unsize}; use core::mem::{self, ManuallyDrop, align_of_val_raw}; -use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, Receiver}; +use core::ops::{CoerceUnsized, Deref, DerefPure, DispatchFromDyn, LegacyReceiver}; use core::panic::{RefUnwindSafe, UnwindSafe}; use core::pin::{Pin, PinCoerceUnsized}; use core::ptr::{self, NonNull}; @@ -2189,8 +2189,8 @@ unsafe impl PinCoerceUnsized for Weak {} #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Arc {} -#[unstable(feature = "receiver_trait", issue = "none")] -impl Receiver for Arc {} +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for Arc {} #[cfg(not(no_global_oom_handling))] impl Arc { diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index f0d2c761ef35b..49b380e45749b 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -297,15 +297,21 @@ unsafe impl DerefPure for &mut T {} /// Indicates that a struct can be used as a method receiver, without the /// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box`, /// `Rc`, `&T`, and `Pin

`. -#[lang = "receiver"] -#[unstable(feature = "receiver_trait", issue = "none")] +/// +/// This trait will shortly be removed and replaced with a more generic +/// facility based around the current "arbitrary self types" unstable feature. +/// That new facility will use a replacement trait called `Receiver` which is +/// why this is now named `LegacyReceiver`. +#[cfg_attr(bootstrap, lang = "receiver")] +#[cfg_attr(not(bootstrap), lang = "legacy_receiver")] +#[unstable(feature = "legacy_receiver_trait", issue = "none")] #[doc(hidden)] -pub trait Receiver { +pub trait LegacyReceiver { // Empty. } -#[unstable(feature = "receiver_trait", issue = "none")] -impl Receiver for &T {} +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for &T {} -#[unstable(feature = "receiver_trait", issue = "none")] -impl Receiver for &mut T {} +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for &mut T {} diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs index 5464bf645d978..c9f47e5daadd6 100644 --- a/library/core/src/ops/mod.rs +++ b/library/core/src/ops/mod.rs @@ -168,8 +168,8 @@ pub use self::control_flow::ControlFlow; pub use self::coroutine::{Coroutine, CoroutineState}; #[unstable(feature = "deref_pure_trait", issue = "87121")] pub use self::deref::DerefPure; -#[unstable(feature = "receiver_trait", issue = "none")] -pub use self::deref::Receiver; +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +pub use self::deref::LegacyReceiver; #[stable(feature = "rust1", since = "1.0.0")] pub use self::deref::{Deref, DerefMut}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 5d5733d38fca1..254b306fcaafe 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -921,7 +921,7 @@ #![stable(feature = "pin", since = "1.33.0")] use crate::hash::{Hash, Hasher}; -use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, Receiver}; +use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn, LegacyReceiver}; #[allow(unused_imports)] use crate::{ cell::{RefCell, UnsafeCell}, @@ -1692,8 +1692,8 @@ impl> DerefMut for Pin { #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for Pin {} -#[unstable(feature = "receiver_trait", issue = "none")] -impl Receiver for Pin {} +#[unstable(feature = "legacy_receiver_trait", issue = "none")] +impl LegacyReceiver for Pin {} #[stable(feature = "pin", since = "1.33.0")] impl fmt::Debug for Pin { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 5070f016d3c62..69ac4644941d9 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -376,6 +376,7 @@ pub struct Config { pub only_modified: bool, pub target_cfgs: OnceLock, + pub builtin_cfg_names: OnceLock>, pub nocapture: bool, @@ -443,6 +444,11 @@ impl Config { self.target_cfg().panic == PanicStrategy::Unwind } + /// Get the list of builtin, 'well known' cfg names + pub fn builtin_cfg_names(&self) -> &HashSet { + self.builtin_cfg_names.get_or_init(|| builtin_cfg_names(self)) + } + pub fn has_threads(&self) -> bool { // Wasm targets don't have threads unless `-threads` is in the target // name, such as `wasm32-wasip1-threads`. @@ -654,6 +660,18 @@ pub enum Endian { Big, } +fn builtin_cfg_names(config: &Config) -> HashSet { + rustc_output( + config, + &["--print=check-cfg", "-Zunstable-options", "--check-cfg=cfg()"], + Default::default(), + ) + .lines() + .map(|l| if let Some((name, _)) = l.split_once('=') { name.to_string() } else { l.to_string() }) + .chain(std::iter::once(String::from("test"))) + .collect() +} + fn rustc_output(config: &Config, args: &[&str], envs: HashMap) -> String { let mut command = Command::new(&config.rustc_path); add_dylib_path(&mut command, iter::once(&config.compile_lib_path)); diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 0f514db42bf9f..490df31322854 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -362,6 +362,7 @@ pub fn parse_config(args: Vec) -> Config { force_rerun: matches.opt_present("force-rerun"), target_cfgs: OnceLock::new(), + builtin_cfg_names: OnceLock::new(), nocapture: matches.opt_present("nocapture"), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7db37af60d2c5..42e5dcf258fc1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -478,6 +478,9 @@ impl<'test> TestCx<'test> { "error: redundant cfg argument `{normalized_revision}` is already created by the revision" ); } + if self.config.builtin_cfg_names().contains(&normalized_revision) { + panic!("error: revision `{normalized_revision}` collides with a builtin cfg"); + } cmd.args(cfg_arg); } diff --git a/tests/codegen/avr/avr-func-addrspace.rs b/tests/codegen/avr/avr-func-addrspace.rs index 7f9a7e6e81103..a2dcb1c092472 100644 --- a/tests/codegen/avr/avr-func-addrspace.rs +++ b/tests/codegen/avr/avr-func-addrspace.rs @@ -18,8 +18,8 @@ pub trait Sized {} #[lang = "copy"] pub trait Copy {} impl Copy for *const T {} -#[lang = "receiver"] -pub trait Receiver {} +#[lang = "legacy_receiver"] +pub trait LegacyReceiver {} #[lang = "tuple_trait"] pub trait Tuple {} diff --git a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs index c1967e55e75b4..5ab55a467268b 100644 --- a/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs +++ b/tests/codegen/sanitizer/kcfi/emit-type-metadata-trait-objects.rs @@ -16,8 +16,8 @@ trait Sized {} #[lang = "copy"] trait Copy {} impl Copy for &T {} -#[lang = "receiver"] -trait Receiver {} +#[lang = "legacy_receiver"] +trait LegacyReceiver {} #[lang = "dispatch_from_dyn"] trait DispatchFromDyn {} impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {} diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs index e14c935b23b87..f37dae4c1ed43 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -4,8 +4,8 @@ #[lang = "sized"] trait Sized {} -#[lang = "receiver"] -pub trait Receiver {} +#[lang = "legacy_receiver"] +pub trait LegacyReceiver {} pub auto trait Bar {} diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 33d67360ff11d..408dbea4ae834 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -79,10 +79,10 @@ mod prelude { #[lang = "sized"] pub trait Sized {} - #[lang = "receiver"] - pub trait Receiver {} - impl Receiver for &T {} - impl Receiver for &mut T {} + #[lang = "legacy_receiver"] + pub trait LegacyReceiver {} + impl LegacyReceiver for &T {} + impl LegacyReceiver for &mut T {} #[lang = "copy"] pub trait Copy: Sized {} diff --git a/tests/ui/cast/ptr-to-trait-obj-drop-principal.rs b/tests/ui/cast/ptr-to-trait-obj-drop-principal.rs new file mode 100644 index 0000000000000..01dd91fc77dd7 --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-drop-principal.rs @@ -0,0 +1,21 @@ +//! Test that non-coercion casts aren't allowed to drop the principal, +//! because they cannot modify the pointer metadata. +//! +//! We test this in a const context to guard against UB if this is allowed +//! in the future. + +trait Trait {} +impl Trait for () {} + +struct Wrapper(T); + +const OBJECT: *const (dyn Trait + Send) = &(); + +// coercions are allowed +const _: *const dyn Send = OBJECT as _; + +// casts are **not** allowed +const _: *const Wrapper = OBJECT as _; +//~^ ERROR casting `*const (dyn Trait + Send + 'static)` as `*const Wrapper` is invalid + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-drop-principal.stderr b/tests/ui/cast/ptr-to-trait-obj-drop-principal.stderr new file mode 100644 index 0000000000000..719e0711f5b9b --- /dev/null +++ b/tests/ui/cast/ptr-to-trait-obj-drop-principal.stderr @@ -0,0 +1,11 @@ +error[E0606]: casting `*const (dyn Trait + Send + 'static)` as `*const Wrapper` is invalid + --> $DIR/ptr-to-trait-obj-drop-principal.rs:18:37 + | +LL | const _: *const Wrapper = OBJECT as _; + | ^^^^^^^^^^^ + | + = note: the trait objects may have different vtables + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/error-codes/E0081.rs b/tests/ui/error-codes/E0081.rs index f53fda864d655..8fdb27c36e35e 100644 --- a/tests/ui/error-codes/E0081.rs +++ b/tests/ui/error-codes/E0081.rs @@ -50,5 +50,47 @@ enum MultipleDuplicates { //~^ NOTE `-2` assigned here } +// Test for #131902 +// Ensure that casting an enum with too many variants for its repr +// does not ICE +#[repr(u8)] +enum TooManyVariants { + //~^ ERROR discriminant value `0` assigned more than once + X000, X001, X002, X003, X004, X005, X006, X007, X008, X009, + //~^ NOTE `0` assigned here + //~| NOTE discriminant for `X256` incremented from this startpoint + X010, X011, X012, X013, X014, X015, X016, X017, X018, X019, + X020, X021, X022, X023, X024, X025, X026, X027, X028, X029, + X030, X031, X032, X033, X034, X035, X036, X037, X038, X039, + X040, X041, X042, X043, X044, X045, X046, X047, X048, X049, + X050, X051, X052, X053, X054, X055, X056, X057, X058, X059, + X060, X061, X062, X063, X064, X065, X066, X067, X068, X069, + X070, X071, X072, X073, X074, X075, X076, X077, X078, X079, + X080, X081, X082, X083, X084, X085, X086, X087, X088, X089, + X090, X091, X092, X093, X094, X095, X096, X097, X098, X099, + X100, X101, X102, X103, X104, X105, X106, X107, X108, X109, + X110, X111, X112, X113, X114, X115, X116, X117, X118, X119, + X120, X121, X122, X123, X124, X125, X126, X127, X128, X129, + X130, X131, X132, X133, X134, X135, X136, X137, X138, X139, + X140, X141, X142, X143, X144, X145, X146, X147, X148, X149, + X150, X151, X152, X153, X154, X155, X156, X157, X158, X159, + X160, X161, X162, X163, X164, X165, X166, X167, X168, X169, + X170, X171, X172, X173, X174, X175, X176, X177, X178, X179, + X180, X181, X182, X183, X184, X185, X186, X187, X188, X189, + X190, X191, X192, X193, X194, X195, X196, X197, X198, X199, + X200, X201, X202, X203, X204, X205, X206, X207, X208, X209, + X210, X211, X212, X213, X214, X215, X216, X217, X218, X219, + X220, X221, X222, X223, X224, X225, X226, X227, X228, X229, + X230, X231, X232, X233, X234, X235, X236, X237, X238, X239, + X240, X241, X242, X243, X244, X245, X246, X247, X248, X249, + X250, X251, X252, X253, X254, X255, + X256, + //~^ ERROR enum discriminant overflowed + //~| NOTE overflowed on value after 255 + //~| NOTE explicitly set `X256 = 0` + //~| NOTE `0` assigned here +} + fn main() { + TooManyVariants::X256 as u8; } diff --git a/tests/ui/error-codes/E0081.stderr b/tests/ui/error-codes/E0081.stderr index d4b21f6893b43..91445eedf4da9 100644 --- a/tests/ui/error-codes/E0081.stderr +++ b/tests/ui/error-codes/E0081.stderr @@ -73,6 +73,30 @@ LL | LL | V9, | -- `-2` assigned here -error: aborting due to 5 previous errors +error[E0370]: enum discriminant overflowed + --> $DIR/E0081.rs:87:5 + | +LL | X256, + | ^^^^ overflowed on value after 255 + | + = note: explicitly set `X256 = 0` if that is desired outcome + +error[E0081]: discriminant value `0` assigned more than once + --> $DIR/E0081.rs:57:1 + | +LL | enum TooManyVariants { + | ^^^^^^^^^^^^^^^^^^^^ +LL | +LL | X000, X001, X002, X003, X004, X005, X006, X007, X008, X009, + | ---- + | | + | `0` assigned here + | discriminant for `X256` incremented from this startpoint (`X000` + 256 variants later => `X256` = 0) +... +LL | X256, + | ---- `0` assigned here + +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0081`. +Some errors have detailed explanations: E0081, E0370. +For more information about an error, try `rustc --explain E0081`. diff --git a/tests/ui/lint/lint-missing-doc-expect.rs b/tests/ui/lint/lint-missing-doc-expect.rs index 991f65003dc26..b1abf8b69620c 100644 --- a/tests/ui/lint/lint-missing-doc-expect.rs +++ b/tests/ui/lint/lint-missing-doc-expect.rs @@ -1,10 +1,10 @@ // Make sure that `#[expect(missing_docs)]` is always correctly fulfilled. //@ check-pass -//@ revisions: lib bin test +//@ revisions: lib bin test_ //@ [lib]compile-flags: --crate-type lib //@ [bin]compile-flags: --crate-type bin -//@ [test]compile-flags: --test +//@ [test_]compile-flags: --test #[expect(missing_docs)] pub fn foo() {} diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index fcb2108ab5fec..31f3960100371 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -12,14 +12,14 @@ pub trait Deref { type Target; } -#[lang="receiver"] -pub trait Receiver: Deref {} +#[lang="legacy_receiver"] +pub trait LegacyReceiver: Deref {} impl<'a, T> Deref for &'a T { type Target = T; } -impl<'a, T> Receiver for &'a T {} +impl<'a, T> LegacyReceiver for &'a T {} mod bar { // shouldn't bring in too much diff --git a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs index b3087349e4d3c..b87387f4d5de3 100644 --- a/tests/ui/traits/const-traits/const-fns-are-early-bound.rs +++ b/tests/ui/traits/const-traits/const-fns-are-early-bound.rs @@ -82,12 +82,12 @@ trait Copy {} #[lang = "tuple_trait"] trait Tuple {} -#[lang = "receiver"] -trait Receiver {} +#[lang = "legacy_receiver"] +trait LegacyReceiver {} -impl Receiver for &T {} +impl LegacyReceiver for &T {} -impl Receiver for &mut T {} +impl LegacyReceiver for &mut T {} #[stable(feature = "minicore", since = "1.0.0")] pub mod effects { diff --git a/tests/ui/traits/const-traits/effects/minicore.rs b/tests/ui/traits/const-traits/effects/minicore.rs index 1c3c66bc3ce76..9b615450c68fe 100644 --- a/tests/ui/traits/const-traits/effects/minicore.rs +++ b/tests/ui/traits/const-traits/effects/minicore.rs @@ -137,12 +137,12 @@ macro_rules! impl_fn_mut_tuple { //impl_fn_mut_tuple!(A B C D); //impl_fn_mut_tuple!(A B C D E); -#[lang = "receiver"] -trait Receiver {} +#[lang = "legacy_receiver"] +trait LegacyReceiver {} -impl Receiver for &T {} +impl LegacyReceiver for &T {} -impl Receiver for &mut T {} +impl LegacyReceiver for &mut T {} #[lang = "destruct"] #[const_trait] @@ -454,7 +454,7 @@ impl /* const */ Deref for Option { } } -impl Receiver for Pin

{} +impl LegacyReceiver for Pin

{} impl Clone for RefCell { fn clone(&self) -> RefCell { diff --git a/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs new file mode 100644 index 0000000000000..5c53b745933b5 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Znext-solver + +// Make sure we try to mention a deeply normalized type in a type mismatch error. + +trait Mirror { + type Assoc; +} +impl Mirror for T { + type Assoc = T; +} + +fn needs(_: ::Assoc) {} + +fn main() { + needs::(()); + //~^ ERROR mismatched types +} diff --git a/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr new file mode 100644 index 0000000000000..88643945863d5 --- /dev/null +++ b/tests/ui/traits/next-solver/diagnostics/deeply-normalize-type-expectation.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/deeply-normalize-type-expectation.rs:15:18 + | +LL | needs::(()); + | ------------ ^^ expected `i32`, found `()` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/deeply-normalize-type-expectation.rs:12:4 + | +LL | fn needs(_: ::Assoc) {} + | ^^^^^ ----------------------- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/unpretty/extern-static.rs b/tests/ui/unpretty/extern-static.rs new file mode 100644 index 0000000000000..fbd605b12caec --- /dev/null +++ b/tests/ui/unpretty/extern-static.rs @@ -0,0 +1,6 @@ +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +unsafe extern "C" { + pub unsafe static STATIC: (); +} diff --git a/tests/ui/unpretty/extern-static.stdout b/tests/ui/unpretty/extern-static.stdout new file mode 100644 index 0000000000000..fbd605b12caec --- /dev/null +++ b/tests/ui/unpretty/extern-static.stdout @@ -0,0 +1,6 @@ +//@ compile-flags: -Zunpretty=normal +//@ check-pass + +unsafe extern "C" { + pub unsafe static STATIC: (); +}