Auto merge of #139229 - Zalathar:rollup-5cs3f4d, r=Zalathar
Rollup of 14 pull requests Successful merges: - #135295 (Check empty SIMD vector in inline asm) - #138003 (Add the new `amx` target features and the `movrs` target feature) - #138823 (rustc_target: RISC-V: add base `I`-related important extensions) - #138913 (Remove even more instances of `@ts-expect-error` from search.js) - #138941 (Do not mix normalized and unnormalized caller bounds when constructing param-env for `receiver_is_dispatchable`) - #139060 (replace commit placeholder in vendor status with actual commit) - #139102 (coverage: Avoid splitting spans during span extraction/refinement) - #139191 (small opaque type/borrowck cleanup) - #139200 (Skip suggest impl or dyn when poly trait is not a real trait) - #139208 (fix dead link netbsd.md) - #139210 (chore: remove redundant backtick) - #139212 (Update mdbook to 0.4.48) - #139214 (Tell rustfmt to use the 2024 edition in ./x.py fmt) - #139225 (move autodiff from EnzymeAD/Enzyme to our rust-lang/Enzyme soft-fork) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c9cd707845
117 changed files with 760 additions and 583 deletions
|
@ -1,7 +1,7 @@
|
|||
//! This file provides API for compiler consumers.
|
||||
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::{IndexSlice, IndexVec};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::{Body, Promoted};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
|
@ -100,8 +100,5 @@ pub fn get_body_with_borrowck_facts(
|
|||
def: LocalDefId,
|
||||
options: ConsumerOptions,
|
||||
) -> BodyWithBorrowckFacts<'_> {
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||
*super::do_mir_borrowck(tcx, input_body, promoted, Some(options)).1.unwrap()
|
||||
*super::do_mir_borrowck(tcx, def, Some(options)).1.unwrap()
|
||||
}
|
||||
|
|
|
@ -103,11 +103,8 @@ pub fn provide(providers: &mut Providers) {
|
|||
}
|
||||
|
||||
fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
|
||||
|
||||
let (input_body, _) = tcx.mir_promoted(def);
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
|
||||
if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
|
||||
debug!("Skipping borrowck because of injected body or tainted body");
|
||||
// Let's make up a borrowck result! Fun times!
|
||||
|
@ -120,7 +117,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
|||
return tcx.arena.alloc(result);
|
||||
}
|
||||
|
||||
let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0;
|
||||
let borrowck_result = do_mir_borrowck(tcx, def, None).0;
|
||||
debug!("mir_borrowck done");
|
||||
|
||||
tcx.arena.alloc(borrowck_result)
|
||||
|
@ -131,15 +128,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
|||
/// Use `consumer_options: None` for the default behavior of returning
|
||||
/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
|
||||
/// to the given [`ConsumerOptions`].
|
||||
#[instrument(skip(tcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
fn do_mir_borrowck<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
input_body: &Body<'tcx>,
|
||||
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
||||
def: LocalDefId,
|
||||
consumer_options: Option<ConsumerOptions>,
|
||||
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
|
||||
let def = input_body.source.def_id().expect_local();
|
||||
let infcx = BorrowckInferCtxt::new(tcx, def);
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||
if let Some(e) = input_body.tainted_by_errors {
|
||||
infcx.set_tainted_by_errors(e);
|
||||
}
|
||||
|
@ -499,7 +497,8 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
|
|||
)
|
||||
});
|
||||
|
||||
self.inject_new_hidden_type_unchecked(key, hidden_ty);
|
||||
let prev = self.register_hidden_type_in_storage(key, hidden_ty);
|
||||
assert_eq!(prev, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,16 +6,25 @@
|
|||
#![feature(gen_blocks)]
|
||||
|
||||
fn foo() -> impl Iterator<Item = u32> {
|
||||
gen { yield 42; for x in 3..6 { yield x } }
|
||||
gen {
|
||||
yield 42;
|
||||
for x in 3..6 {
|
||||
yield x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn moved() -> impl Iterator<Item = u32> {
|
||||
let mut x = "foo".to_string();
|
||||
gen move {
|
||||
yield 42;
|
||||
if x == "foo" { return }
|
||||
if x == "foo" {
|
||||
return;
|
||||
}
|
||||
x.clear();
|
||||
for x in 3..6 { yield x }
|
||||
for x in 3..6 {
|
||||
yield x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,5 +41,4 @@ fn main() {
|
|||
let mut iter = moved();
|
||||
assert_eq!(iter.next(), Some(42));
|
||||
assert_eq!(iter.next(), None);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
ignore = [
|
||||
"example/gen_block_iterate.rs", # uses edition 2024
|
||||
]
|
||||
|
||||
# Matches rustfmt.toml of rustc
|
||||
style_edition = "2024"
|
||||
use_small_heuristics = "Max"
|
||||
|
|
|
@ -300,6 +300,13 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
|
|||
("sparc", "v8plus") if get_version().0 == 19 => Some(LLVMFeature::new("v9")),
|
||||
("sparc", "v8plus") if get_version().0 < 19 => None,
|
||||
("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")),
|
||||
// These new `amx` variants and `movrs` were introduced in LLVM20
|
||||
("x86", "amx-avx512" | "amx-fp8" | "amx-movrs" | "amx-tf32" | "amx-transpose")
|
||||
if get_version().0 < 20 =>
|
||||
{
|
||||
None
|
||||
}
|
||||
("x86", "movrs") if get_version().0 < 20 => None,
|
||||
(_, s) => Some(LLVMFeature::new(s)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -324,6 +324,7 @@ declare_features! (
|
|||
(unstable, loongarch_target_feature, "1.73.0", Some(44839)),
|
||||
(unstable, m68k_target_feature, "1.85.0", Some(134328)),
|
||||
(unstable, mips_target_feature, "1.27.0", Some(44839)),
|
||||
(unstable, movrs_target_feature, "CURRENT_RUSTC_VERSION", Some(137976)),
|
||||
(unstable, powerpc_target_feature, "1.27.0", Some(44839)),
|
||||
(unstable, prfchw_target_feature, "1.78.0", Some(44839)),
|
||||
(unstable, riscv_target_feature, "1.45.0", Some(44839)),
|
||||
|
|
|
@ -29,6 +29,7 @@ enum NonAsmTypeReason<'tcx> {
|
|||
Invalid(Ty<'tcx>),
|
||||
InvalidElement(DefId, Ty<'tcx>),
|
||||
NotSizedPtr(Ty<'tcx>),
|
||||
EmptySIMDArray(Ty<'tcx>),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
|
@ -102,6 +103,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
}
|
||||
ty::Adt(adt, args) if adt.repr().simd() => {
|
||||
let fields = &adt.non_enum_variant().fields;
|
||||
if fields.is_empty() {
|
||||
return Err(NonAsmTypeReason::EmptySIMDArray(ty));
|
||||
}
|
||||
let field = &fields[FieldIdx::ZERO];
|
||||
let elem_ty = field.ty(self.tcx(), args);
|
||||
|
||||
|
@ -226,6 +230,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
|||
can be used as arguments for inline assembly",
|
||||
).emit();
|
||||
}
|
||||
NonAsmTypeReason::EmptySIMDArray(ty) => {
|
||||
let msg = format!("use of empty SIMD vector `{ty}`");
|
||||
self.infcx.dcx().struct_span_err(expr.span, msg).emit();
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
"expected a type, found a trait"
|
||||
);
|
||||
if self_ty.span.can_be_used_for_suggestions()
|
||||
&& poly_trait_ref.trait_ref.trait_def_id().is_some()
|
||||
&& !self.maybe_suggest_impl_trait(self_ty, &mut diag)
|
||||
&& !self.maybe_suggest_dyn_trait(self_ty, sugg, &mut diag)
|
||||
{
|
||||
|
|
|
@ -198,13 +198,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// it hasn't previously been defined. This does not emit any
|
||||
/// constraints and it's the responsibility of the caller to make
|
||||
/// sure that the item bounds of the opaque are checked.
|
||||
pub fn inject_new_hidden_type_unchecked(
|
||||
pub fn register_hidden_type_in_storage(
|
||||
&self,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
hidden_ty: OpaqueHiddenType<'tcx>,
|
||||
) {
|
||||
let prev = self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty);
|
||||
assert_eq!(prev, None);
|
||||
) -> Option<Ty<'tcx>> {
|
||||
self.inner.borrow_mut().opaque_types().register(opaque_type_key, hidden_ty)
|
||||
}
|
||||
|
||||
/// Insert a hidden type into the opaque type storage, equating it
|
||||
|
|
|
@ -96,7 +96,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
|
|||
}
|
||||
} else {
|
||||
// Extract coverage spans from MIR statements/terminators as normal.
|
||||
extract_refined_covspans(mir_body, hir_info, graph, &mut code_mappings);
|
||||
extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings);
|
||||
}
|
||||
|
||||
branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::iter;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
|
||||
use tracing::{debug, debug_span, instrument};
|
||||
|
||||
|
@ -11,8 +13,9 @@ use crate::coverage::{ExtractedHirInfo, mappings, unexpand};
|
|||
|
||||
mod from_mir;
|
||||
|
||||
pub(super) fn extract_refined_covspans(
|
||||
mir_body: &mir::Body<'_>,
|
||||
pub(super) fn extract_refined_covspans<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mir_body: &mir::Body<'tcx>,
|
||||
hir_info: &ExtractedHirInfo,
|
||||
graph: &CoverageGraph,
|
||||
code_mappings: &mut impl Extend<mappings::CodeMapping>,
|
||||
|
@ -50,7 +53,7 @@ pub(super) fn extract_refined_covspans(
|
|||
// First, perform the passes that need macro information.
|
||||
covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
|
||||
remove_unwanted_expansion_spans(&mut covspans);
|
||||
split_visible_macro_spans(&mut covspans);
|
||||
shrink_visible_macro_spans(tcx, &mut covspans);
|
||||
|
||||
// We no longer need the extra information in `SpanFromMir`, so convert to `Covspan`.
|
||||
let mut covspans = covspans.into_iter().map(SpanFromMir::into_covspan).collect::<Vec<_>>();
|
||||
|
@ -83,9 +86,7 @@ pub(super) fn extract_refined_covspans(
|
|||
// Split the covspans into separate buckets that don't overlap any holes.
|
||||
let buckets = divide_spans_into_buckets(covspans, &holes);
|
||||
|
||||
for mut covspans in buckets {
|
||||
// Make sure each individual bucket is internally sorted.
|
||||
covspans.sort_by(compare_covspans);
|
||||
for covspans in buckets {
|
||||
let _span = debug_span!("processing bucket", ?covspans).entered();
|
||||
|
||||
let mut covspans = remove_unwanted_overlapping_spans(covspans);
|
||||
|
@ -129,82 +130,50 @@ fn remove_unwanted_expansion_spans(covspans: &mut Vec<SpanFromMir>) {
|
|||
}
|
||||
|
||||
/// When a span corresponds to a macro invocation that is visible from the
|
||||
/// function body, split it into two parts. The first part covers just the
|
||||
/// macro name plus `!`, and the second part covers the rest of the macro
|
||||
/// invocation. This seems to give better results for code that uses macros.
|
||||
fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) {
|
||||
let mut extra_spans = vec![];
|
||||
/// function body, truncate it to just the macro name plus `!`.
|
||||
/// This seems to give better results for code that uses macros.
|
||||
fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec<SpanFromMir>) {
|
||||
let source_map = tcx.sess.source_map();
|
||||
|
||||
covspans.retain(|covspan| {
|
||||
let Some(ExpnKind::Macro(MacroKind::Bang, visible_macro)) = covspan.expn_kind else {
|
||||
return true;
|
||||
};
|
||||
|
||||
let split_len = visible_macro.as_str().len() as u32 + 1;
|
||||
let (before, after) = covspan.span.split_at(split_len);
|
||||
if !covspan.span.contains(before) || !covspan.span.contains(after) {
|
||||
// Something is unexpectedly wrong with the split point.
|
||||
// The debug assertion in `split_at` will have already caught this,
|
||||
// but in release builds it's safer to do nothing and maybe get a
|
||||
// bug report for unexpected coverage, rather than risk an ICE.
|
||||
return true;
|
||||
for covspan in covspans {
|
||||
if matches!(covspan.expn_kind, Some(ExpnKind::Macro(MacroKind::Bang, _))) {
|
||||
covspan.span = source_map.span_through_char(covspan.span, '!');
|
||||
}
|
||||
|
||||
extra_spans.push(SpanFromMir::new(before, covspan.expn_kind.clone(), covspan.bcb));
|
||||
extra_spans.push(SpanFromMir::new(after, covspan.expn_kind.clone(), covspan.bcb));
|
||||
false // Discard the original covspan that we just split.
|
||||
});
|
||||
|
||||
// The newly-split spans are added at the end, so any previous sorting
|
||||
// is not preserved.
|
||||
covspans.extend(extra_spans);
|
||||
}
|
||||
}
|
||||
|
||||
/// Uses the holes to divide the given covspans into buckets, such that:
|
||||
/// - No span in any hole overlaps a bucket (truncating the spans if necessary).
|
||||
/// - No span in any hole overlaps a bucket (discarding spans if necessary).
|
||||
/// - The spans in each bucket are strictly after all spans in previous buckets,
|
||||
/// and strictly before all spans in subsequent buckets.
|
||||
///
|
||||
/// The resulting buckets are sorted relative to each other, but might not be
|
||||
/// internally sorted.
|
||||
/// The lists of covspans and holes must be sorted.
|
||||
/// The resulting buckets are sorted relative to each other, and each bucket's
|
||||
/// contents are sorted.
|
||||
#[instrument(level = "debug")]
|
||||
fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> {
|
||||
debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
|
||||
debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le()));
|
||||
|
||||
// Now we're ready to start carving holes out of the initial coverage spans,
|
||||
// and grouping them in buckets separated by the holes.
|
||||
// Now we're ready to start grouping spans into buckets separated by holes.
|
||||
|
||||
let mut input_covspans = VecDeque::from(input_covspans);
|
||||
let mut fragments = vec![];
|
||||
|
||||
// For each hole:
|
||||
// - Identify the spans that are entirely or partly before the hole.
|
||||
// - Put those spans in a corresponding bucket, truncated to the start of the hole.
|
||||
// - If one of those spans also extends after the hole, put the rest of it
|
||||
// in a "fragments" vector that is processed by the next hole.
|
||||
// - Discard any that overlap with the hole.
|
||||
// - Add the remaining identified spans to the corresponding bucket.
|
||||
let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>();
|
||||
for (hole, bucket) in holes.iter().zip(&mut buckets) {
|
||||
let fragments_from_prev = std::mem::take(&mut fragments);
|
||||
|
||||
// Only inspect spans that precede or overlap this hole,
|
||||
// leaving the rest to be inspected by later holes.
|
||||
// (This relies on the spans and holes both being sorted.)
|
||||
let relevant_input_covspans =
|
||||
drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi());
|
||||
|
||||
for covspan in fragments_from_prev.into_iter().chain(relevant_input_covspans) {
|
||||
let (before, after) = covspan.split_around_hole_span(hole.span);
|
||||
bucket.extend(before);
|
||||
fragments.extend(after);
|
||||
}
|
||||
bucket.extend(
|
||||
drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi())
|
||||
.filter(|c| !c.span.overlaps(hole.span)),
|
||||
);
|
||||
}
|
||||
|
||||
// After finding the spans before each hole, any remaining fragments/spans
|
||||
// form their own final bucket, after the final hole.
|
||||
// Any remaining spans form their own final bucket, after the final hole.
|
||||
// (If there were no holes, this will just be all of the initial spans.)
|
||||
fragments.extend(input_covspans);
|
||||
buckets.push(fragments);
|
||||
buckets.push(Vec::from(input_covspans));
|
||||
|
||||
buckets
|
||||
}
|
||||
|
@ -215,7 +184,7 @@ fn drain_front_while<'a, T>(
|
|||
queue: &'a mut VecDeque<T>,
|
||||
mut pred_fn: impl FnMut(&T) -> bool,
|
||||
) -> impl Iterator<Item = T> {
|
||||
std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None })
|
||||
iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x)))
|
||||
}
|
||||
|
||||
/// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines"
|
||||
|
@ -258,22 +227,6 @@ struct Covspan {
|
|||
}
|
||||
|
||||
impl Covspan {
|
||||
/// Splits this covspan into 0-2 parts:
|
||||
/// - The part that is strictly before the hole span, if any.
|
||||
/// - The part that is strictly after the hole span, if any.
|
||||
fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) {
|
||||
let before = try {
|
||||
let span = self.span.trim_end(hole_span)?;
|
||||
Self { span, ..*self }
|
||||
};
|
||||
let after = try {
|
||||
let span = self.span.trim_start(hole_span)?;
|
||||
Self { span, ..*self }
|
||||
};
|
||||
|
||||
(before, after)
|
||||
}
|
||||
|
||||
/// If `self` and `other` can be merged (i.e. they have the same BCB),
|
||||
/// mutates `self.span` to also include `other.span` and returns true.
|
||||
///
|
||||
|
|
|
@ -120,22 +120,20 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
|
|||
// an `if condition { block }` has a span that includes the executed block, if true,
|
||||
// but for coverage, the code region executed, up to *and* through the SwitchInt,
|
||||
// actually stops before the if's block.)
|
||||
TerminatorKind::Unreachable // Unreachable blocks are not connected to the MIR CFG
|
||||
TerminatorKind::Unreachable
|
||||
| TerminatorKind::Assert { .. }
|
||||
| TerminatorKind::Drop { .. }
|
||||
| TerminatorKind::SwitchInt { .. }
|
||||
// For `FalseEdge`, only the `real` branch is taken, so it is similar to a `Goto`.
|
||||
| TerminatorKind::FalseEdge { .. }
|
||||
| TerminatorKind::Goto { .. } => None,
|
||||
|
||||
// Call `func` operand can have a more specific span when part of a chain of calls
|
||||
TerminatorKind::Call { ref func, .. }
|
||||
| TerminatorKind::TailCall { ref func, .. } => {
|
||||
TerminatorKind::Call { ref func, .. } | TerminatorKind::TailCall { ref func, .. } => {
|
||||
let mut span = terminator.source_info.span;
|
||||
if let mir::Operand::Constant(box constant) = func {
|
||||
if constant.span.lo() > span.lo() {
|
||||
span = span.with_lo(constant.span.lo());
|
||||
}
|
||||
if let mir::Operand::Constant(constant) = func
|
||||
&& span.contains(constant.span)
|
||||
{
|
||||
span = constant.span;
|
||||
}
|
||||
Some(span)
|
||||
}
|
||||
|
@ -147,9 +145,7 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
|
|||
| TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::CoroutineDrop
|
||||
| TerminatorKind::FalseUnwind { .. }
|
||||
| TerminatorKind::InlineAsm { .. } => {
|
||||
Some(terminator.source_info.span)
|
||||
}
|
||||
| TerminatorKind::InlineAsm { .. } => Some(terminator.source_info.span),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#![feature(map_try_insert)]
|
||||
#![feature(never_type)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(vec_deque_pop_if)]
|
||||
#![feature(yeet_expr)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
|
|
|
@ -62,14 +62,12 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
|
|||
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
|
||||
) -> <Self::Interner as Interner>::GenericArg;
|
||||
|
||||
// FIXME: Can we implement this in terms of `add` and `inject`?
|
||||
fn insert_hidden_type(
|
||||
fn register_hidden_type_in_storage(
|
||||
&self,
|
||||
opaque_type_key: ty::OpaqueTypeKey<Self::Interner>,
|
||||
param_env: <Self::Interner as Interner>::ParamEnv,
|
||||
hidden_ty: <Self::Interner as Interner>::Ty,
|
||||
goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
|
||||
) -> Result<(), NoSolution>;
|
||||
span: <Self::Interner as Interner>::Span,
|
||||
) -> Option<<Self::Interner as Interner>::Ty>;
|
||||
|
||||
fn add_item_bounds_for_hidden_type(
|
||||
&self,
|
||||
|
@ -79,14 +77,6 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
|
|||
hidden_ty: <Self::Interner as Interner>::Ty,
|
||||
goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
|
||||
);
|
||||
|
||||
fn inject_new_hidden_type_unchecked(
|
||||
&self,
|
||||
key: ty::OpaqueTypeKey<Self::Interner>,
|
||||
hidden_ty: <Self::Interner as Interner>::Ty,
|
||||
span: <Self::Interner as Interner>::Span,
|
||||
);
|
||||
|
||||
fn reset_opaque_types(&self);
|
||||
|
||||
fn fetch_eligible_assoc_item(
|
||||
|
|
|
@ -425,7 +425,8 @@ where
|
|||
|
||||
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)]) {
|
||||
for &(key, ty) in opaque_types {
|
||||
self.delegate.inject_new_hidden_type_unchecked(key, ty, self.origin_span);
|
||||
let prev = self.delegate.register_hidden_type_in_storage(key, ty, self.origin_span);
|
||||
assert_eq!(prev, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -387,7 +387,8 @@ where
|
|||
};
|
||||
|
||||
for &(key, ty) in &input.predefined_opaques_in_body.opaque_types {
|
||||
ecx.delegate.inject_new_hidden_type_unchecked(key, ty, ecx.origin_span);
|
||||
let prev = ecx.delegate.register_hidden_type_in_storage(key, ty, ecx.origin_span);
|
||||
assert_eq!(prev, None);
|
||||
}
|
||||
|
||||
if !ecx.nested_goals.is_empty() {
|
||||
|
@ -1070,16 +1071,12 @@ where
|
|||
self.delegate.fetch_eligible_assoc_item(goal_trait_ref, trait_assoc_def_id, impl_def_id)
|
||||
}
|
||||
|
||||
pub(super) fn insert_hidden_type(
|
||||
pub(super) fn register_hidden_type_in_storage(
|
||||
&mut self,
|
||||
opaque_type_key: ty::OpaqueTypeKey<I>,
|
||||
param_env: I::ParamEnv,
|
||||
hidden_ty: I::Ty,
|
||||
) -> Result<(), NoSolution> {
|
||||
let mut goals = Vec::new();
|
||||
self.delegate.insert_hidden_type(opaque_type_key, param_env, hidden_ty, &mut goals)?;
|
||||
self.add_goals(GoalSource::Misc, goals);
|
||||
Ok(())
|
||||
) -> Option<I::Ty> {
|
||||
self.delegate.register_hidden_type_in_storage(opaque_type_key, hidden_ty, self.origin_span)
|
||||
}
|
||||
|
||||
pub(super) fn add_item_bounds_for_hidden_type(
|
||||
|
|
|
@ -86,8 +86,8 @@ where
|
|||
}
|
||||
|
||||
// Otherwise, define a new opaque type
|
||||
// FIXME: should we use `inject_hidden_type_unchecked` here?
|
||||
self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
|
||||
let prev = self.register_hidden_type_in_storage(opaque_type_key, expected);
|
||||
assert_eq!(prev, None);
|
||||
self.add_item_bounds_for_hidden_type(
|
||||
def_id.into(),
|
||||
opaque_ty.args,
|
||||
|
|
|
@ -1378,6 +1378,7 @@ symbols! {
|
|||
movbe_target_feature,
|
||||
move_ref_pattern,
|
||||
move_size_limit,
|
||||
movrs_target_feature,
|
||||
mul,
|
||||
mul_assign,
|
||||
mul_with_overflow,
|
||||
|
|
|
@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
|
|||
cpu: "generic-rv32".into(),
|
||||
llvm_abiname: "ilp32d".into(),
|
||||
max_atomic_width: Some(32),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
stack_probes: StackProbeType::Inline,
|
||||
..base::vxworks::opts()
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv32".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "ilp32d".into(),
|
||||
max_atomic_width: Some(32),
|
||||
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
|
||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv32".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "ilp32d".into(),
|
||||
max_atomic_width: Some(32),
|
||||
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
|
||||
|
|
|
@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zba,+zbb,+zbs,+v".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei,+zba,+zbb,+zbs,+v".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
supported_sanitizers: SanitizerSet::ADDRESS,
|
||||
max_atomic_width: Some(64),
|
||||
|
|
|
@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
|
|||
cpu: "generic-rv64".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
max_atomic_width: Some(64),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
stack_probes: StackProbeType::Inline,
|
||||
..base::vxworks::opts()
|
||||
},
|
||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
max_atomic_width: Some(64),
|
||||
..base::freebsd::opts()
|
||||
|
|
|
@ -4,7 +4,7 @@ pub(crate) fn target() -> Target {
|
|||
let mut base = base::fuchsia::opts();
|
||||
base.code_model = Some(CodeModel::Medium);
|
||||
base.cpu = "generic-rv64".into();
|
||||
base.features = "+m,+a,+f,+d,+c".into();
|
||||
base.features = "+m,+a,+f,+d,+c,+zicsr,+zifencei".into();
|
||||
base.llvm_abiname = "lp64d".into();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.stack_probes = StackProbeType::Inline;
|
||||
|
|
|
@ -14,7 +14,7 @@ pub(crate) fn target() -> Target {
|
|||
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
|
||||
options: TargetOptions {
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
relocation_model: RelocModel::Pic,
|
||||
code_model: Some(CodeModel::Medium),
|
||||
tls_model: TlsModel::LocalExec,
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
max_atomic_width: Some(64),
|
||||
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
|
||||
|
|
|
@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
max_atomic_width: Some(64),
|
||||
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
|
||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
max_atomic_width: Some(64),
|
||||
mcount: "__mcount".into(),
|
||||
|
|
|
@ -22,7 +22,7 @@ pub(crate) fn target() -> Target {
|
|||
llvm_abiname: "lp64d".into(),
|
||||
cpu: "generic-rv64".into(),
|
||||
max_atomic_width: Some(64),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
code_model: Some(CodeModel::Medium),
|
||||
|
|
|
@ -24,7 +24,7 @@ pub(crate) fn target() -> Target {
|
|||
llvm_abiname: "lp64d".into(),
|
||||
cpu: "generic-rv64".into(),
|
||||
max_atomic_width: Some(64),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
relocation_model: RelocModel::Static,
|
||||
code_model: Some(CodeModel::Medium),
|
||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
code_model: Some(CodeModel::Medium),
|
||||
cpu: "generic-rv64".into(),
|
||||
features: "+m,+a,+f,+d,+c".into(),
|
||||
features: "+m,+a,+f,+d,+c,+zicsr,+zifencei".into(),
|
||||
llvm_abiname: "lp64d".into(),
|
||||
max_atomic_width: Some(64),
|
||||
..base::openbsd::opts()
|
||||
|
|
|
@ -380,11 +380,16 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
|||
// tidy-alphabetical-start
|
||||
("adx", Stable, &[]),
|
||||
("aes", Stable, &["sse2"]),
|
||||
("amx-avx512", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-bf16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-complex", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-fp16", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-fp8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-int8", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-movrs", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-tf32", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("amx-tile", Unstable(sym::x86_amx_intrinsics), &[]),
|
||||
("amx-transpose", Unstable(sym::x86_amx_intrinsics), &["amx-tile"]),
|
||||
("avx", Stable, &["sse4.2"]),
|
||||
("avx2", Stable, &["avx"]),
|
||||
("avx512bf16", Unstable(sym::avx512_target_feature), &["avx512bw"]),
|
||||
|
@ -418,6 +423,7 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
|||
("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
|
||||
("lzcnt", Stable, &[]),
|
||||
("movbe", Stable, &[]),
|
||||
("movrs", Unstable(sym::movrs_target_feature), &[]),
|
||||
("pclmulqdq", Stable, &["sse2"]),
|
||||
("popcnt", Stable, &[]),
|
||||
("prfchw", Unstable(sym::prfchw_target_feature), &[]),
|
||||
|
@ -488,7 +494,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
|||
("c", Stable, &[]),
|
||||
("d", Unstable(sym::riscv_target_feature), &["f"]),
|
||||
("e", Unstable(sym::riscv_target_feature), &[]),
|
||||
("f", Unstable(sym::riscv_target_feature), &[]),
|
||||
("f", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||
(
|
||||
"forced-atomics",
|
||||
Stability::Forbidden { reason: "unsound because it changes the ABI of atomic operations" },
|
||||
|
@ -517,15 +523,20 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
|||
("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]),
|
||||
("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]),
|
||||
("zfhmin", Unstable(sym::riscv_target_feature), &["f"]),
|
||||
("zfinx", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||
("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]),
|
||||
("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]),
|
||||
("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||
("zicsr", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zifencei", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zihintpause", Unstable(sym::riscv_target_feature), &[]),
|
||||
("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]),
|
||||
("zk", Stable, &["zkn", "zkr", "zkt"]),
|
||||
("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
|
||||
("zknd", Stable, &[]),
|
||||
("zkne", Stable, &[]),
|
||||
("zknh", Stable, &[]),
|
||||
("zkr", Stable, &[]),
|
||||
("zkr", Stable, &["zicsr"]),
|
||||
("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
|
||||
("zksed", Stable, &[]),
|
||||
("zksh", Stable, &[]),
|
||||
|
@ -533,7 +544,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
|
|||
("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]),
|
||||
("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
|
||||
("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
|
||||
("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b"]),
|
||||
("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
|
||||
("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
|
||||
("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
|
||||
("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]),
|
||||
|
|
|
@ -149,16 +149,16 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
self.0.instantiate_canonical_var(span, cv_info, universe_map)
|
||||
}
|
||||
|
||||
fn insert_hidden_type(
|
||||
fn register_hidden_type_in_storage(
|
||||
&self,
|
||||
opaque_type_key: ty::OpaqueTypeKey<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||
) -> Result<(), NoSolution> {
|
||||
self.0
|
||||
.insert_hidden_type(opaque_type_key, DUMMY_SP, param_env, hidden_ty, goals)
|
||||
.map_err(|_| NoSolution)
|
||||
opaque_type_key: rustc_type_ir::OpaqueTypeKey<Self::Interner>,
|
||||
hidden_ty: <Self::Interner as ty::Interner>::Ty,
|
||||
span: <Self::Interner as ty::Interner>::Span,
|
||||
) -> Option<<Self::Interner as ty::Interner>::Ty> {
|
||||
self.0.register_hidden_type_in_storage(
|
||||
opaque_type_key,
|
||||
ty::OpaqueHiddenType { span, ty: hidden_ty },
|
||||
)
|
||||
}
|
||||
|
||||
fn add_item_bounds_for_hidden_type(
|
||||
|
@ -172,15 +172,6 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals);
|
||||
}
|
||||
|
||||
fn inject_new_hidden_type_unchecked(
|
||||
&self,
|
||||
key: ty::OpaqueTypeKey<'tcx>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
) {
|
||||
self.0.inject_new_hidden_type_unchecked(key, ty::OpaqueHiddenType { ty: hidden_ty, span })
|
||||
}
|
||||
|
||||
fn reset_opaque_types(&self) {
|
||||
let _ = self.take_opaque_types();
|
||||
}
|
||||
|
|
|
@ -583,27 +583,36 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` (and all of
|
||||
// its supertraits) added to caller bounds. `U: ?Sized` is already implied here.
|
||||
let param_env = {
|
||||
let param_env = tcx.param_env(method.def_id);
|
||||
// N.B. We generally want to emulate the construction of the `unnormalized_param_env`
|
||||
// in the param-env query here. The fact that we don't just start with the clauses
|
||||
// in the param-env of the method is because those are already normalized, and mixing
|
||||
// normalized and unnormalized copies of predicates in `normalize_param_env_or_error`
|
||||
// will cause ambiguity that the user can't really avoid.
|
||||
//
|
||||
// We leave out certain complexities of the param-env query here. Specifically, we:
|
||||
// 1. Do not add `~const` bounds since there are no `dyn const Trait`s.
|
||||
// 2. Do not add RPITIT self projection bounds for defaulted methods, since we
|
||||
// are not constructing a param-env for "inside" of the body of the defaulted
|
||||
// method, so we don't really care about projecting to a specific RPIT type,
|
||||
// and because RPITITs are not dyn compatible (yet).
|
||||
let mut predicates = tcx.predicates_of(method.def_id).instantiate_identity(tcx).predicates;
|
||||
|
||||
// Self: Unsize<U>
|
||||
let unsize_predicate =
|
||||
ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]).upcast(tcx);
|
||||
ty::TraitRef::new(tcx, unsize_did, [tcx.types.self_param, unsized_self_ty]);
|
||||
predicates.push(unsize_predicate.upcast(tcx));
|
||||
|
||||
// U: Trait<Arg1, ..., ArgN>
|
||||
let trait_predicate = {
|
||||
let trait_def_id = method.trait_container(tcx).unwrap();
|
||||
let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
|
||||
if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
|
||||
});
|
||||
|
||||
ty::TraitRef::new_from_args(tcx, trait_def_id, args).upcast(tcx)
|
||||
};
|
||||
let trait_def_id = method.trait_container(tcx).unwrap();
|
||||
let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
|
||||
if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
|
||||
});
|
||||
let trait_predicate = ty::TraitRef::new_from_args(tcx, trait_def_id, args);
|
||||
predicates.push(trait_predicate.upcast(tcx));
|
||||
|
||||
normalize_param_env_or_error(
|
||||
tcx,
|
||||
ty::ParamEnv::new(tcx.mk_clauses_from_iter(
|
||||
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]),
|
||||
)),
|
||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates)),
|
||||
ObligationCause::dummy_with_span(tcx.def_span(method.def_id)),
|
||||
)
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue