Auto merge of #122182 - matthiaskrgr:rollup-gzimi4c, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #118623 (Improve std::fs::read_to_string example) - #119365 (Add asm goto support to `asm!`) - #120608 (Docs for std::ptr::slice_from_raw_parts) - #121832 (Add new Tier-3 target: `loongarch64-unknown-linux-musl`) - #121938 (Fix quadratic behavior of repeated vectored writes) - #122099 (Add `#[inline]` to `BTreeMap::new` constructor) - #122103 (Make TAITs and ATPITs capture late-bound lifetimes in scope) - #122143 (PassWrapper: update for llvm/llvm-project@a331937197) Failed merges: - #122076 (Tweak the way we protect in-place function arguments in interpreters) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1b2c53a15d
107 changed files with 1126 additions and 422 deletions
|
@ -1716,13 +1716,13 @@ mod size_asserts {
|
|||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(BasicBlockData<'_>, 136);
|
||||
static_assert_size!(BasicBlockData<'_>, 144);
|
||||
static_assert_size!(LocalDecl<'_>, 40);
|
||||
static_assert_size!(SourceScopeData<'_>, 72);
|
||||
static_assert_size!(Statement<'_>, 32);
|
||||
static_assert_size!(StatementKind<'_>, 16);
|
||||
static_assert_size!(Terminator<'_>, 104);
|
||||
static_assert_size!(TerminatorKind<'_>, 88);
|
||||
static_assert_size!(Terminator<'_>, 112);
|
||||
static_assert_size!(TerminatorKind<'_>, 96);
|
||||
static_assert_size!(VarDebugInfo<'_>, 88);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
|
|||
use crate::mir::interpret::ConstAllocation;
|
||||
|
||||
use super::graphviz::write_mir_fn_graphviz;
|
||||
use rustc_ast::InlineAsmTemplatePiece;
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_middle::mir::interpret::{
|
||||
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
|
||||
Provenance,
|
||||
|
@ -830,6 +830,9 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
InlineAsmOperand::SymStatic { def_id } => {
|
||||
write!(fmt, "sym_static {def_id:?}")?;
|
||||
}
|
||||
InlineAsmOperand::Label { target_index } => {
|
||||
write!(fmt, "label {target_index}")?;
|
||||
}
|
||||
}
|
||||
}
|
||||
write!(fmt, ", options({options:?}))")
|
||||
|
@ -868,16 +871,19 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
vec!["real".into(), "unwind".into()]
|
||||
}
|
||||
FalseUnwind { unwind: _, .. } => vec!["real".into()],
|
||||
InlineAsm { destination: Some(_), unwind: UnwindAction::Cleanup(_), .. } => {
|
||||
vec!["return".into(), "unwind".into()]
|
||||
InlineAsm { options, ref targets, unwind, .. } => {
|
||||
let mut vec = Vec::with_capacity(targets.len() + 1);
|
||||
if !options.contains(InlineAsmOptions::NORETURN) {
|
||||
vec.push("return".into());
|
||||
}
|
||||
vec.resize(targets.len(), "label".into());
|
||||
|
||||
if let UnwindAction::Cleanup(_) = unwind {
|
||||
vec.push("unwind".into());
|
||||
}
|
||||
|
||||
vec
|
||||
}
|
||||
InlineAsm { destination: Some(_), unwind: _, .. } => {
|
||||
vec!["return".into()]
|
||||
}
|
||||
InlineAsm { destination: None, unwind: UnwindAction::Cleanup(_), .. } => {
|
||||
vec!["unwind".into()]
|
||||
}
|
||||
InlineAsm { destination: None, unwind: _, .. } => vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -793,9 +793,10 @@ pub enum TerminatorKind<'tcx> {
|
|||
/// used to map assembler errors back to the line in the source code.
|
||||
line_spans: &'tcx [Span],
|
||||
|
||||
/// Destination block after the inline assembly returns, unless it is
|
||||
/// diverging (InlineAsmOptions::NORETURN).
|
||||
destination: Option<BasicBlock>,
|
||||
/// Valid targets for the inline assembly.
|
||||
/// The first element is the fallthrough destination, unless
|
||||
/// InlineAsmOptions::NORETURN is set.
|
||||
targets: Vec<BasicBlock>,
|
||||
|
||||
/// Action to be taken if the inline assembly unwinds. This is present
|
||||
/// if and only if InlineAsmOptions::MAY_UNWIND is set.
|
||||
|
@ -918,6 +919,10 @@ pub enum InlineAsmOperand<'tcx> {
|
|||
SymStatic {
|
||||
def_id: DefId,
|
||||
},
|
||||
Label {
|
||||
/// This represents the index into the `targets` array in `TerminatorKind::InlineAsm`.
|
||||
target_index: usize,
|
||||
},
|
||||
}
|
||||
|
||||
/// Type for MIR `Assert` terminator error messages.
|
||||
|
|
|
@ -347,8 +347,7 @@ pub struct Terminator<'tcx> {
|
|||
}
|
||||
|
||||
pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
|
||||
pub type SuccessorsMut<'a> =
|
||||
iter::Chain<std::option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
|
||||
pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
|
||||
|
||||
impl<'tcx> Terminator<'tcx> {
|
||||
#[inline]
|
||||
|
@ -382,40 +381,36 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
pub fn successors(&self) -> Successors<'_> {
|
||||
use self::TerminatorKind::*;
|
||||
match *self {
|
||||
Call { target: Some(t), unwind: UnwindAction::Cleanup(ref u), .. }
|
||||
| Yield { resume: t, drop: Some(ref u), .. }
|
||||
| Drop { target: t, unwind: UnwindAction::Cleanup(ref u), .. }
|
||||
| Assert { target: t, unwind: UnwindAction::Cleanup(ref u), .. }
|
||||
| FalseUnwind { real_target: t, unwind: UnwindAction::Cleanup(ref u) }
|
||||
| InlineAsm { destination: Some(t), unwind: UnwindAction::Cleanup(ref u), .. } => {
|
||||
Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied())
|
||||
Call { target: Some(ref t), unwind: UnwindAction::Cleanup(u), .. }
|
||||
| Yield { resume: ref t, drop: Some(u), .. }
|
||||
| Drop { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
|
||||
| Assert { target: ref t, unwind: UnwindAction::Cleanup(u), .. }
|
||||
| FalseUnwind { real_target: ref t, unwind: UnwindAction::Cleanup(u) } => {
|
||||
slice::from_ref(t).into_iter().copied().chain(Some(u))
|
||||
}
|
||||
Goto { target: t }
|
||||
| Call { target: None, unwind: UnwindAction::Cleanup(t), .. }
|
||||
| Call { target: Some(t), unwind: _, .. }
|
||||
| Yield { resume: t, drop: None, .. }
|
||||
| Drop { target: t, unwind: _, .. }
|
||||
| Assert { target: t, unwind: _, .. }
|
||||
| FalseUnwind { real_target: t, unwind: _ }
|
||||
| InlineAsm { destination: None, unwind: UnwindAction::Cleanup(t), .. }
|
||||
| InlineAsm { destination: Some(t), unwind: _, .. } => {
|
||||
Some(t).into_iter().chain((&[]).into_iter().copied())
|
||||
Goto { target: ref t }
|
||||
| Call { target: None, unwind: UnwindAction::Cleanup(ref t), .. }
|
||||
| Call { target: Some(ref t), unwind: _, .. }
|
||||
| Yield { resume: ref t, drop: None, .. }
|
||||
| Drop { target: ref t, unwind: _, .. }
|
||||
| Assert { target: ref t, unwind: _, .. }
|
||||
| FalseUnwind { real_target: ref t, unwind: _ } => {
|
||||
slice::from_ref(t).into_iter().copied().chain(None)
|
||||
}
|
||||
UnwindResume
|
||||
| UnwindTerminate(_)
|
||||
| CoroutineDrop
|
||||
| Return
|
||||
| Unreachable
|
||||
| Call { target: None, unwind: _, .. }
|
||||
| InlineAsm { destination: None, unwind: _, .. } => {
|
||||
None.into_iter().chain((&[]).into_iter().copied())
|
||||
| Call { target: None, unwind: _, .. } => (&[]).into_iter().copied().chain(None),
|
||||
InlineAsm { ref targets, unwind: UnwindAction::Cleanup(u), .. } => {
|
||||
targets.iter().copied().chain(Some(u))
|
||||
}
|
||||
SwitchInt { ref targets, .. } => {
|
||||
None.into_iter().chain(targets.targets.iter().copied())
|
||||
InlineAsm { ref targets, unwind: _, .. } => targets.iter().copied().chain(None),
|
||||
SwitchInt { ref targets, .. } => targets.targets.iter().copied().chain(None),
|
||||
FalseEdge { ref real_target, imaginary_target } => {
|
||||
slice::from_ref(real_target).into_iter().copied().chain(Some(imaginary_target))
|
||||
}
|
||||
FalseEdge { real_target, ref imaginary_target } => Some(real_target)
|
||||
.into_iter()
|
||||
.chain(slice::from_ref(imaginary_target).into_iter().copied()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,33 +422,31 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
||||
| Drop { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) }
|
||||
| InlineAsm {
|
||||
destination: Some(ref mut t),
|
||||
unwind: UnwindAction::Cleanup(ref mut u),
|
||||
..
|
||||
} => Some(t).into_iter().chain(slice::from_mut(u)),
|
||||
| FalseUnwind { real_target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u) } => {
|
||||
slice::from_mut(t).into_iter().chain(Some(u))
|
||||
}
|
||||
Goto { target: ref mut t }
|
||||
| Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
|
||||
| Call { target: Some(ref mut t), unwind: _, .. }
|
||||
| Yield { resume: ref mut t, drop: None, .. }
|
||||
| Drop { target: ref mut t, unwind: _, .. }
|
||||
| Assert { target: ref mut t, unwind: _, .. }
|
||||
| FalseUnwind { real_target: ref mut t, unwind: _ }
|
||||
| InlineAsm { destination: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
|
||||
| InlineAsm { destination: Some(ref mut t), unwind: _, .. } => {
|
||||
Some(t).into_iter().chain(&mut [])
|
||||
| FalseUnwind { real_target: ref mut t, unwind: _ } => {
|
||||
slice::from_mut(t).into_iter().chain(None)
|
||||
}
|
||||
UnwindResume
|
||||
| UnwindTerminate(_)
|
||||
| CoroutineDrop
|
||||
| Return
|
||||
| Unreachable
|
||||
| Call { target: None, unwind: _, .. }
|
||||
| InlineAsm { destination: None, unwind: _, .. } => None.into_iter().chain(&mut []),
|
||||
SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets.targets),
|
||||
| Call { target: None, unwind: _, .. } => (&mut []).into_iter().chain(None),
|
||||
InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
|
||||
targets.iter_mut().chain(Some(u))
|
||||
}
|
||||
InlineAsm { ref mut targets, unwind: _, .. } => targets.iter_mut().chain(None),
|
||||
SwitchInt { ref mut targets, .. } => targets.targets.iter_mut().chain(None),
|
||||
FalseEdge { ref mut real_target, ref mut imaginary_target } => {
|
||||
Some(real_target).into_iter().chain(slice::from_mut(imaginary_target))
|
||||
slice::from_mut(real_target).into_iter().chain(Some(imaginary_target))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -525,7 +518,7 @@ pub enum TerminatorEdges<'mir, 'tcx> {
|
|||
Double(BasicBlock, BasicBlock),
|
||||
/// Special action for `Yield`, `Call` and `InlineAsm` terminators.
|
||||
AssignOnReturn {
|
||||
return_: Option<BasicBlock>,
|
||||
return_: &'mir [BasicBlock],
|
||||
/// The cleanup block, if it exists.
|
||||
cleanup: Option<BasicBlock>,
|
||||
place: CallReturnPlaces<'mir, 'tcx>,
|
||||
|
@ -589,31 +582,37 @@ impl<'tcx> TerminatorKind<'tcx> {
|
|||
TerminatorEdges::Double(real_target, imaginary_target)
|
||||
}
|
||||
|
||||
Yield { resume: target, drop, resume_arg, value: _ } => {
|
||||
Yield { resume: ref target, drop, resume_arg, value: _ } => {
|
||||
TerminatorEdges::AssignOnReturn {
|
||||
return_: Some(target),
|
||||
return_: slice::from_ref(target),
|
||||
cleanup: drop,
|
||||
place: CallReturnPlaces::Yield(resume_arg),
|
||||
}
|
||||
}
|
||||
|
||||
Call { unwind, destination, target, func: _, args: _, fn_span: _, call_source: _ } => {
|
||||
TerminatorEdges::AssignOnReturn {
|
||||
return_: target,
|
||||
cleanup: unwind.cleanup_block(),
|
||||
place: CallReturnPlaces::Call(destination),
|
||||
}
|
||||
}
|
||||
Call {
|
||||
unwind,
|
||||
destination,
|
||||
ref target,
|
||||
func: _,
|
||||
args: _,
|
||||
fn_span: _,
|
||||
call_source: _,
|
||||
} => TerminatorEdges::AssignOnReturn {
|
||||
return_: target.as_ref().map(slice::from_ref).unwrap_or_default(),
|
||||
cleanup: unwind.cleanup_block(),
|
||||
place: CallReturnPlaces::Call(destination),
|
||||
},
|
||||
|
||||
InlineAsm {
|
||||
template: _,
|
||||
ref operands,
|
||||
options: _,
|
||||
line_spans: _,
|
||||
destination,
|
||||
ref targets,
|
||||
unwind,
|
||||
} => TerminatorEdges::AssignOnReturn {
|
||||
return_: destination,
|
||||
return_: targets,
|
||||
cleanup: unwind.cleanup_block(),
|
||||
place: CallReturnPlaces::InlineAsm(operands),
|
||||
},
|
||||
|
|
|
@ -565,7 +565,7 @@ macro_rules! make_mir_visitor {
|
|||
operands,
|
||||
options: _,
|
||||
line_spans: _,
|
||||
destination: _,
|
||||
targets: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
for op in operands {
|
||||
|
@ -595,7 +595,8 @@ macro_rules! make_mir_visitor {
|
|||
self.visit_constant(value, location);
|
||||
}
|
||||
InlineAsmOperand::Out { place: None, .. }
|
||||
| InlineAsmOperand::SymStatic { def_id: _ } => {}
|
||||
| InlineAsmOperand::SymStatic { def_id: _ }
|
||||
| InlineAsmOperand::Label { target_index: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -565,6 +565,9 @@ pub enum InlineAsmOperand<'tcx> {
|
|||
SymStatic {
|
||||
def_id: DefId,
|
||||
},
|
||||
Label {
|
||||
block: BlockId,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
|
||||
|
|
|
@ -162,6 +162,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
|
|||
| Const { value: _, span: _ }
|
||||
| SymFn { value: _, span: _ }
|
||||
| SymStatic { def_id: _ } => {}
|
||||
Label { block } => visitor.visit_block(&visitor.thir()[*block]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1254,7 +1254,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
if self.def_kind(scope) == DefKind::OpaqueTy {
|
||||
// Lifetime params of opaque types are synthetic and thus irrelevant to
|
||||
// diagnostics. Map them back to their origin!
|
||||
region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
|
||||
region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
|
||||
continue;
|
||||
}
|
||||
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
|
||||
|
@ -2219,31 +2219,31 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Given the def-id of an early-bound lifetime on an RPIT corresponding to
|
||||
/// Given the def-id of an early-bound lifetime on an opaque corresponding to
|
||||
/// a duplicated captured lifetime, map it back to the early- or late-bound
|
||||
/// lifetime of the function from which it originally as captured. If it is
|
||||
/// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
|
||||
/// of the signature.
|
||||
// FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
|
||||
// re-use the generics of the opaque, this function will need to be tweaked slightly.
|
||||
pub fn map_rpit_lifetime_to_fn_lifetime(
|
||||
pub fn map_opaque_lifetime_to_parent_lifetime(
|
||||
self,
|
||||
mut rpit_lifetime_param_def_id: LocalDefId,
|
||||
mut opaque_lifetime_param_def_id: LocalDefId,
|
||||
) -> ty::Region<'tcx> {
|
||||
debug_assert!(
|
||||
matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam),
|
||||
"{rpit_lifetime_param_def_id:?} is a {}",
|
||||
self.def_descr(rpit_lifetime_param_def_id.to_def_id())
|
||||
matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
|
||||
"{opaque_lifetime_param_def_id:?} is a {}",
|
||||
self.def_descr(opaque_lifetime_param_def_id.to_def_id())
|
||||
);
|
||||
|
||||
loop {
|
||||
let parent = self.local_parent(rpit_lifetime_param_def_id);
|
||||
let parent = self.local_parent(opaque_lifetime_param_def_id);
|
||||
let hir::OpaqueTy { lifetime_mapping, .. } =
|
||||
self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
|
||||
|
||||
let Some((lifetime, _)) = lifetime_mapping
|
||||
.iter()
|
||||
.find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id)
|
||||
.find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
|
||||
else {
|
||||
bug!("duplicated lifetime param should be present");
|
||||
};
|
||||
|
@ -2256,7 +2256,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// of the opaque we mapped from. Continue mapping.
|
||||
if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
|
||||
debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
|
||||
rpit_lifetime_param_def_id = ebv.expect_local();
|
||||
opaque_lifetime_param_def_id = ebv.expect_local();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1940,18 +1940,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
|
||||
}
|
||||
|
||||
/// Returns the `DefId` of the item within which the `impl Trait` is declared.
|
||||
/// For type-alias-impl-trait this is the `type` alias.
|
||||
/// For impl-trait-in-assoc-type this is the assoc type.
|
||||
/// For return-position-impl-trait this is the function.
|
||||
pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
|
||||
// Find the surrounding item (type alias or assoc type)
|
||||
while let DefKind::OpaqueTy = self.def_kind(def_id) {
|
||||
def_id = self.local_parent(def_id);
|
||||
}
|
||||
def_id
|
||||
}
|
||||
|
||||
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
|
||||
if self.def_kind(def_id) != DefKind::AssocFn {
|
||||
return false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue