Auto merge of #132094 - Zalathar:rollup-5r1ppqt, r=Zalathar

Rollup of 10 pull requests

Successful merges:

 - #130225 (Rename Receiver -> LegacyReceiver)
 - #131169 (Fix `target_vendor` in QNX Neutrino targets)
 - #131623 (misc cleanups)
 - #131756 (Deeply normalize `TypeTrace` when reporting type error in new solver)
 - #131898 (minor `*dyn` cast cleanup)
 - #131909 (Prevent overflowing enum cast from ICEing)
 - #131930 (Don't allow test revisions that conflict with built in cfgs)
 - #131956 (coverage: Pass coverage mappings to LLVM as separate structs)
 - #132076 (HashStable for rustc_feature::Features: stop hashing compile-time constant)
 - #132088 (Print safety correctly in extern static items)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-10-24 03:24:50 +00:00
commit 55b7f8e800
64 changed files with 624 additions and 591 deletions

View File

@ -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,
);
}

View File

@ -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,

View File

@ -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
}

View File

@ -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,
}
};

View File

@ -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,

View File

@ -47,12 +47,12 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}
#[lang = "receiver"]
pub trait Receiver {}
#[lang = "legacy_receiver"]
pub trait LegacyReceiver {}
impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
impl<T: ?Sized> Receiver for Box<T> {}
impl<T: ?Sized> LegacyReceiver for &T {}
impl<T: ?Sized> LegacyReceiver for &mut T {}
impl<T: ?Sized> LegacyReceiver for Box<T> {}
#[lang = "copy"]
pub unsafe trait Copy {}

View File

@ -44,12 +44,12 @@ impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U, ()>> for Box<T, ()> {}
#[lang = "receiver"]
pub trait Receiver {}
#[lang = "legacy_receiver"]
pub trait LegacyReceiver {}
impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
impl<T: ?Sized, A: Allocator> Receiver for Box<T, A> {}
impl<T: ?Sized> LegacyReceiver for &T {}
impl<T: ?Sized> LegacyReceiver for &mut T {}
impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {}
#[lang = "copy"]
pub unsafe trait Copy {}

View File

@ -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<ConditionInfo> for BranchParameters {
fn from(value: ConditionInfo) -> Self {
let to_llvm_cond_id = |cond_id: Option<ConditionId>| {
@ -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,
}
}
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,
}
}
// 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,
}
}
// 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,
}
}
// 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,
}
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 }
}
}
/// Must match the layout of `LLVMRustCoverageCodeRegion`.
#[derive(Clone, Debug)]
#[repr(C)]
pub(crate) struct CodeRegion {
pub(crate) span: CoverageSpan,
pub(crate) counter: Counter,
}
/// 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,
}
/// 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,
}
/// 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,
}

View File

@ -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::<Vec<_>>();
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,
);
})

View File

@ -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<u32>,
expressions: Vec<CounterExpression>,
mapping_regions: Vec<CounterMappingRegion>,
expressions: Vec<ffi::CounterExpression>,
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,
);
}

View File

@ -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;

View File

@ -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);

View File

@ -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<TyCtxt<'tcx>> 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,
);

View File

@ -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,
);

View File

@ -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() {

View File

@ -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,

View File

@ -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();
}
}
}

View File

@ -876,20 +876,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
// A<dyn Src<...> + SrcAuto> -> B<dyn Dst<...> + 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.

View File

@ -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(..));

View File

@ -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));

View File

@ -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,
);

View File

@ -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

View File

@ -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,

View File

@ -187,10 +187,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
value_count: usize,
) -> (Range<TyVid>, Vec<TypeVariableOrigin>) {
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

View File

@ -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<coverage::mcdc::ConditionID>(
Params.BranchParameters.ConditionID),
{static_cast<coverage::mcdc::ConditionID>(
Params.BranchParameters.ConditionIDs[0]),
static_cast<coverage::mcdc::ConditionID>(
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<coverage::CounterMappingRegion, 0> MappingRegions;
MappingRegions.reserve(NumMappingRegions);
for (const auto &Region : ArrayRef<LLVMRustCounterMappingRegion>(
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<coverage::CounterExpression> Expressions;
Expressions.reserve(NumExpressions);
for (const auto &Expression :
@ -205,6 +165,46 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
fromRust(Expression.RHS));
}
std::vector<coverage::CounterMappingRegion> 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<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
Expressions, MappingRegions);

View File

@ -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}"))
})?)
})
}
///////////////////////////////////////////////////////////////////////////

View File

@ -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 });

View File

@ -363,7 +363,7 @@ fn calc_test_vectors_index(conditions: &mut Vec<MCDCBranch>) -> 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)
})

View File

@ -87,7 +87,7 @@ fn remove_unwanted_expansion_spans(covspans: &mut Vec<SpanFromMir>) {
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),

View File

@ -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,
);

View File

@ -111,13 +111,8 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
impl<'tcx> HashStable<StableHashingContext<'tcx>> 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);
}
}
}

View File

@ -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,

View File

@ -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()
},

View File

@ -21,6 +21,7 @@ pub(crate) fn target() -> Target {
"-Vgcc_ntox86_64_cxx",
]),
env: "nto71".into(),
vendor: "pc".into(),
..base::nto_qnx::opts()
},
}

View File

@ -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<Ty<'tcx>> {
@ -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<ValuePairs<'tcx>>,
mut values: Option<ty::ParamEnvAnd<'tcx, ValuePairs<'tcx>>>,
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
}

View File

@ -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(

View File

@ -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,
));
}

View File

@ -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,

View File

@ -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<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
#[unstable(feature = "deref_pure_trait", issue = "87121")]
unsafe impl<T: ?Sized, A: Allocator> DerefPure for Box<T, A> {}
#[unstable(feature = "receiver_trait", issue = "none")]
impl<T: ?Sized, A: Allocator> Receiver for Box<T, A> {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator + ?Sized, A: Allocator> Iterator for Box<I, A> {

View File

@ -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)]

View File

@ -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<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
#[unstable(feature = "deref_pure_trait", issue = "87121")]
unsafe impl<T: ?Sized, A: Allocator> DerefPure for Rc<T, A> {}
#[unstable(feature = "receiver_trait", issue = "none")]
impl<T: ?Sized> Receiver for Rc<T> {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<T: ?Sized> LegacyReceiver for Rc<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc<T, A> {

View File

@ -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<T: ?Sized, A: Allocator> PinCoerceUnsized for Weak<T, A> {}
#[unstable(feature = "deref_pure_trait", issue = "87121")]
unsafe impl<T: ?Sized, A: Allocator> DerefPure for Arc<T, A> {}
#[unstable(feature = "receiver_trait", issue = "none")]
impl<T: ?Sized> Receiver for Arc<T> {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<T: ?Sized> LegacyReceiver for Arc<T> {}
#[cfg(not(no_global_oom_handling))]
impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Arc<T, A> {

View File

@ -297,15 +297,21 @@ unsafe impl<T: ?Sized> 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<T>`,
/// `Rc<T>`, `&T`, and `Pin<P>`.
#[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<T: ?Sized> Receiver for &T {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<T: ?Sized> LegacyReceiver for &T {}
#[unstable(feature = "receiver_trait", issue = "none")]
impl<T: ?Sized> Receiver for &mut T {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<T: ?Sized> LegacyReceiver for &mut T {}

View File

@ -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")]

View File

@ -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<Ptr: DerefMut<Target: Unpin>> DerefMut for Pin<Ptr> {
#[unstable(feature = "deref_pure_trait", issue = "87121")]
unsafe impl<Ptr: DerefPure> DerefPure for Pin<Ptr> {}
#[unstable(feature = "receiver_trait", issue = "none")]
impl<Ptr: Receiver> Receiver for Pin<Ptr> {}
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
impl<Ptr: LegacyReceiver> LegacyReceiver for Pin<Ptr> {}
#[stable(feature = "pin", since = "1.33.0")]
impl<Ptr: fmt::Debug> fmt::Debug for Pin<Ptr> {

View File

@ -376,6 +376,7 @@ pub struct Config {
pub only_modified: bool,
pub target_cfgs: OnceLock<TargetCfgs>,
pub builtin_cfg_names: OnceLock<HashSet<String>>,
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<String> {
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<String> {
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, String>) -> String {
let mut command = Command::new(&config.rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));

View File

@ -362,6 +362,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
force_rerun: matches.opt_present("force-rerun"),
target_cfgs: OnceLock::new(),
builtin_cfg_names: OnceLock::new(),
nocapture: matches.opt_present("nocapture"),

View File

@ -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);
}

View File

@ -18,8 +18,8 @@ pub trait Sized {}
#[lang = "copy"]
pub trait Copy {}
impl<T: ?Sized> Copy for *const T {}
#[lang = "receiver"]
pub trait Receiver {}
#[lang = "legacy_receiver"]
pub trait LegacyReceiver {}
#[lang = "tuple_trait"]
pub trait Tuple {}

View File

@ -16,8 +16,8 @@ trait Sized {}
#[lang = "copy"]
trait Copy {}
impl<T: ?Sized> Copy for &T {}
#[lang = "receiver"]
trait Receiver {}
#[lang = "legacy_receiver"]
trait LegacyReceiver {}
#[lang = "dispatch_from_dyn"]
trait DispatchFromDyn<T> {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}

View File

@ -4,8 +4,8 @@
#[lang = "sized"]
trait Sized {}
#[lang = "receiver"]
pub trait Receiver {}
#[lang = "legacy_receiver"]
pub trait LegacyReceiver {}
pub auto trait Bar {}

View File

@ -79,10 +79,10 @@ mod prelude {
#[lang = "sized"]
pub trait Sized {}
#[lang = "receiver"]
pub trait Receiver {}
impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
#[lang = "legacy_receiver"]
pub trait LegacyReceiver {}
impl<T: ?Sized> LegacyReceiver for &T {}
impl<T: ?Sized> LegacyReceiver for &mut T {}
#[lang = "copy"]
pub trait Copy: Sized {}

View File

@ -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: ?Sized>(T);
const OBJECT: *const (dyn Trait + Send) = &();
// coercions are allowed
const _: *const dyn Send = OBJECT as _;
// casts are **not** allowed
const _: *const Wrapper<dyn Send> = OBJECT as _;
//~^ ERROR casting `*const (dyn Trait + Send + 'static)` as `*const Wrapper<dyn Send>` is invalid
fn main() {}

View File

@ -0,0 +1,11 @@
error[E0606]: casting `*const (dyn Trait + Send + 'static)` as `*const Wrapper<dyn Send>` is invalid
--> $DIR/ptr-to-trait-obj-drop-principal.rs:18:37
|
LL | const _: *const Wrapper<dyn Send> = 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`.

View File

@ -50,5 +50,47 @@ enum MultipleDuplicates {
//~^ NOTE `-2` assigned here
}
fn main() {
// 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;
}

View File

@ -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
For more information about this error, try `rustc --explain E0081`.
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
Some errors have detailed explanations: E0081, E0370.
For more information about an error, try `rustc --explain E0081`.

View File

@ -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() {}

View File

@ -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

View File

@ -82,12 +82,12 @@ trait Copy {}
#[lang = "tuple_trait"]
trait Tuple {}
#[lang = "receiver"]
trait Receiver {}
#[lang = "legacy_receiver"]
trait LegacyReceiver {}
impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> LegacyReceiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
impl<T: ?Sized> LegacyReceiver for &mut T {}
#[stable(feature = "minicore", since = "1.0.0")]
pub mod effects {

View File

@ -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<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> LegacyReceiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
impl<T: ?Sized> LegacyReceiver for &mut T {}
#[lang = "destruct"]
#[const_trait]
@ -454,7 +454,7 @@ impl<T> /* const */ Deref for Option<T> {
}
}
impl<P: Receiver> Receiver for Pin<P> {}
impl<P: LegacyReceiver> LegacyReceiver for Pin<P> {}
impl<T: Clone> Clone for RefCell<T> {
fn clone(&self) -> RefCell<T> {

View File

@ -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<T> Mirror for T {
type Assoc = T;
}
fn needs<T>(_: <T as Mirror>::Assoc) {}
fn main() {
needs::<i32>(());
//~^ ERROR mismatched types
}

View File

@ -0,0 +1,17 @@
error[E0308]: mismatched types
--> $DIR/deeply-normalize-type-expectation.rs:15:18
|
LL | needs::<i32>(());
| ------------ ^^ expected `i32`, found `()`
| |
| arguments to this function are incorrect
|
note: function defined here
--> $DIR/deeply-normalize-type-expectation.rs:12:4
|
LL | fn needs<T>(_: <T as Mirror>::Assoc) {}
| ^^^^^ -----------------------
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,6 @@
//@ compile-flags: -Zunpretty=normal
//@ check-pass
unsafe extern "C" {
pub unsafe static STATIC: ();
}

View File

@ -0,0 +1,6 @@
//@ compile-flags: -Zunpretty=normal
//@ check-pass
unsafe extern "C" {
pub unsafe static STATIC: ();
}