Auto merge of #139826 - matthiaskrgr:rollup-0q0qvkd, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #139745 (Avoid unused clones in `Cloned<I>` and `Copied<I>`) - #139757 (opt-dist: use executable-extension for host llvm-profdata) - #139778 (Add test for issue 34834) - #139783 (Use `compiletest-ignore-dir` for bootstrap self-tests) - #139797 (Allow (but don't require) `#[unsafe(naked)]` so that `compiler-builtins` can upgrade to it) - #139799 (Specify `--print info=file` syntax in `--help`) - #139811 (Use `newtype_index!`-generated types more idiomatically) - #139813 (Miri subtree update) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
58c2dd9a54
42 changed files with 353 additions and 173 deletions
|
@ -2038,9 +2038,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libffi"
|
name = "libffi"
|
||||||
version = "3.2.0"
|
version = "4.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2"
|
checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"libffi-sys",
|
"libffi-sys",
|
||||||
|
@ -2048,9 +2048,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libffi-sys"
|
name = "libffi-sys"
|
||||||
version = "2.3.0"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c"
|
checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
|
@ -448,8 +448,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
generic_args.args.insert_many(
|
generic_args.args.insert_many(
|
||||||
0,
|
0,
|
||||||
(start.as_u32()..end.as_u32()).map(|i| {
|
(start..end).map(|id| {
|
||||||
let id = NodeId::from_u32(i);
|
|
||||||
let l = self.lower_lifetime_anon_in_path(id, elided_lifetime_span);
|
let l = self.lower_lifetime_anon_in_path(id, elided_lifetime_span);
|
||||||
GenericArg::Lifetime(l)
|
GenericArg::Lifetime(l)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -338,8 +338,7 @@ fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
|
||||||
let num_components = sccs.num_sccs();
|
let num_components = sccs.num_sccs();
|
||||||
let mut components = vec![FxIndexSet::default(); num_components];
|
let mut components = vec![FxIndexSet::default(); num_components];
|
||||||
|
|
||||||
for (reg_var_idx, scc_idx) in sccs.scc_indices().iter().enumerate() {
|
for (reg_var, scc_idx) in sccs.scc_indices().iter_enumerated() {
|
||||||
let reg_var = ty::RegionVid::from_usize(reg_var_idx);
|
|
||||||
let origin = var_to_origin.get(®_var).unwrap_or(&RegionCtxt::Unknown);
|
let origin = var_to_origin.get(®_var).unwrap_or(&RegionCtxt::Unknown);
|
||||||
components[scc_idx.as_usize()].insert((reg_var, *origin));
|
components[scc_idx.as_usize()].insert((reg_var, *origin));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::collections::hash_map::Entry;
|
||||||
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
|
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_index::Idx;
|
|
||||||
use rustc_index::bit_set::DenseBitSet;
|
use rustc_index::bit_set::DenseBitSet;
|
||||||
use rustc_middle::mir::{Body, SourceScope};
|
use rustc_middle::mir::{Body, SourceScope};
|
||||||
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
|
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
|
||||||
|
@ -43,8 +42,7 @@ pub(crate) fn compute_mir_scopes<'ll, 'tcx>(
|
||||||
let mut instantiated = DenseBitSet::new_empty(mir.source_scopes.len());
|
let mut instantiated = DenseBitSet::new_empty(mir.source_scopes.len());
|
||||||
let mut discriminators = FxHashMap::default();
|
let mut discriminators = FxHashMap::default();
|
||||||
// Instantiate all scopes.
|
// Instantiate all scopes.
|
||||||
for idx in 0..mir.source_scopes.len() {
|
for scope in mir.source_scopes.indices() {
|
||||||
let scope = SourceScope::new(idx);
|
|
||||||
make_mir_scope(
|
make_mir_scope(
|
||||||
cx,
|
cx,
|
||||||
instance,
|
instance,
|
||||||
|
|
|
@ -47,12 +47,9 @@ impl DefPathTable {
|
||||||
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
|
debug_assert_eq!(self.stable_crate_id, def_path_hash.stable_crate_id());
|
||||||
let local_hash = def_path_hash.local_hash();
|
let local_hash = def_path_hash.local_hash();
|
||||||
|
|
||||||
let index = {
|
let index = self.index_to_key.push(key);
|
||||||
let index = DefIndex::from(self.index_to_key.len());
|
debug!("DefPathTable::insert() - {key:?} <-> {index:?}");
|
||||||
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
|
|
||||||
self.index_to_key.push(key);
|
|
||||||
index
|
|
||||||
};
|
|
||||||
self.def_path_hashes.push(local_hash);
|
self.def_path_hashes.push(local_hash);
|
||||||
debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
|
debug_assert!(self.def_path_hashes.len() == self.index_to_key.len());
|
||||||
|
|
||||||
|
|
|
@ -606,7 +606,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
// with placeholders, which imply nothing about outlives bounds, and then
|
// with placeholders, which imply nothing about outlives bounds, and then
|
||||||
// prove below that the hidden types are well formed.
|
// prove below that the hidden types are well formed.
|
||||||
let universe = infcx.create_next_universe();
|
let universe = infcx.create_next_universe();
|
||||||
let mut idx = 0;
|
let mut idx = ty::BoundVar::ZERO;
|
||||||
let mapping: FxIndexMap<_, _> = collector
|
let mapping: FxIndexMap<_, _> = collector
|
||||||
.types
|
.types
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -623,10 +623,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
ty::Placeholder {
|
ty::Placeholder {
|
||||||
universe,
|
universe,
|
||||||
bound: ty::BoundTy {
|
bound: ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon },
|
||||||
var: ty::BoundVar::from_usize(idx),
|
|
||||||
kind: ty::BoundTyKind::Anon,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -618,9 +618,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||||
RegionVid::from(value_count)..RegionVid::from(self.storage.unification_table.len());
|
RegionVid::from(value_count)..RegionVid::from(self.storage.unification_table.len());
|
||||||
(
|
(
|
||||||
range.clone(),
|
range.clone(),
|
||||||
(range.start.index()..range.end.index())
|
(range.start..range.end).map(|index| self.storage.var_infos[index].origin).collect(),
|
||||||
.map(|index| self.storage.var_infos[ty::RegionVid::from(index)].origin)
|
|
||||||
.collect(),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,12 @@ fn const_vars_since_snapshot<'tcx>(
|
||||||
snapshot_var_len: usize,
|
snapshot_var_len: usize,
|
||||||
) -> (Range<ConstVid>, Vec<ConstVariableOrigin>) {
|
) -> (Range<ConstVid>, Vec<ConstVariableOrigin>) {
|
||||||
let range = vars_since_snapshot(table, snapshot_var_len);
|
let range = vars_since_snapshot(table, snapshot_var_len);
|
||||||
|
let range = range.start.vid..range.end.vid;
|
||||||
|
|
||||||
(
|
(
|
||||||
range.start.vid..range.end.vid,
|
range.clone(),
|
||||||
(range.start.index()..range.end.index())
|
range
|
||||||
.map(|index| match table.probe_value(ConstVid::from_u32(index)) {
|
.map(|index| match table.probe_value(index) {
|
||||||
ConstVariableValue::Known { value: _ } => {
|
ConstVariableValue::Known { value: _ } => {
|
||||||
ConstVariableOrigin { param_def_id: None, span: rustc_span::DUMMY_SP }
|
ConstVariableOrigin { param_def_id: None, span: rustc_span::DUMMY_SP }
|
||||||
}
|
}
|
||||||
|
|
|
@ -531,12 +531,12 @@ fn write_mir_intro<'tcx>(
|
||||||
|
|
||||||
// construct a scope tree and write it out
|
// construct a scope tree and write it out
|
||||||
let mut scope_tree: FxHashMap<SourceScope, Vec<SourceScope>> = Default::default();
|
let mut scope_tree: FxHashMap<SourceScope, Vec<SourceScope>> = Default::default();
|
||||||
for (index, scope_data) in body.source_scopes.iter().enumerate() {
|
for (index, scope_data) in body.source_scopes.iter_enumerated() {
|
||||||
if let Some(parent) = scope_data.parent_scope {
|
if let Some(parent) = scope_data.parent_scope {
|
||||||
scope_tree.entry(parent).or_default().push(SourceScope::new(index));
|
scope_tree.entry(parent).or_default().push(index);
|
||||||
} else {
|
} else {
|
||||||
// Only the argument scope has no parent, because it's the root.
|
// Only the argument scope has no parent, because it's the root.
|
||||||
assert_eq!(index, OUTERMOST_SOURCE_SCOPE.index());
|
assert_eq!(index, OUTERMOST_SOURCE_SCOPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars);
|
let shift_bv = |bv: ty::BoundVar| bv + bound_vars;
|
||||||
self.replace_escaping_bound_vars_uncached(
|
self.replace_escaping_bound_vars_uncached(
|
||||||
value,
|
value,
|
||||||
FnMutDelegate {
|
FnMutDelegate {
|
||||||
|
|
|
@ -231,9 +231,7 @@ impl MaxUniverse {
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
fn visit_ty(&mut self, t: Ty<'tcx>) {
|
||||||
if let ty::Placeholder(placeholder) = t.kind() {
|
if let ty::Placeholder(placeholder) = t.kind() {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = self.max_universe.max(placeholder.universe);
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
|
@ -241,9 +239,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
||||||
|
|
||||||
fn visit_const(&mut self, c: ty::consts::Const<'tcx>) {
|
fn visit_const(&mut self, c: ty::consts::Const<'tcx>) {
|
||||||
if let ty::ConstKind::Placeholder(placeholder) = c.kind() {
|
if let ty::ConstKind::Placeholder(placeholder) = c.kind() {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = self.max_universe.max(placeholder.universe);
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.super_visit_with(self)
|
c.super_visit_with(self)
|
||||||
|
@ -251,9 +247,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse {
|
||||||
|
|
||||||
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
fn visit_region(&mut self, r: ty::Region<'tcx>) {
|
||||||
if let ty::RePlaceholder(placeholder) = r.kind() {
|
if let ty::RePlaceholder(placeholder) = r.kind() {
|
||||||
self.max_universe = ty::UniverseIndex::from_u32(
|
self.max_universe = self.max_universe.max(placeholder.universe);
|
||||||
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
let pointer_target = ExprKind::Field {
|
let pointer_target = ExprKind::Field {
|
||||||
lhs: self.thir.exprs.push(expr),
|
lhs: self.thir.exprs.push(expr),
|
||||||
variant_index: FIRST_VARIANT,
|
variant_index: FIRST_VARIANT,
|
||||||
name: FieldIdx::from(0u32),
|
name: FieldIdx::ZERO,
|
||||||
};
|
};
|
||||||
let arg = Expr { temp_lifetime, ty: pin_ty, span, kind: pointer_target };
|
let arg = Expr { temp_lifetime, ty: pin_ty, span, kind: pointer_target };
|
||||||
let arg = self.thir.exprs.push(arg);
|
let arg = self.thir.exprs.push(arg);
|
||||||
|
@ -226,7 +226,7 @@ impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
adt_def: self.tcx.adt_def(pin_did),
|
adt_def: self.tcx.adt_def(pin_did),
|
||||||
variant_index: FIRST_VARIANT,
|
variant_index: FIRST_VARIANT,
|
||||||
args,
|
args,
|
||||||
fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
|
fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]),
|
||||||
user_ty: None,
|
user_ty: None,
|
||||||
base: AdtExprBase::None,
|
base: AdtExprBase::None,
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -203,7 +203,7 @@ struct TransformVisitor<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> TransformVisitor<'tcx> {
|
impl<'tcx> TransformVisitor<'tcx> {
|
||||||
fn insert_none_ret_block(&self, body: &mut Body<'tcx>) -> BasicBlock {
|
fn insert_none_ret_block(&self, body: &mut Body<'tcx>) -> BasicBlock {
|
||||||
let block = BasicBlock::new(body.basic_blocks.len());
|
let block = body.basic_blocks.next_index();
|
||||||
let source_info = SourceInfo::outermost(body.span);
|
let source_info = SourceInfo::outermost(body.span);
|
||||||
|
|
||||||
let none_value = match self.coroutine_kind {
|
let none_value = match self.coroutine_kind {
|
||||||
|
@ -1193,7 +1193,7 @@ fn insert_panic_block<'tcx>(
|
||||||
body: &mut Body<'tcx>,
|
body: &mut Body<'tcx>,
|
||||||
message: AssertMessage<'tcx>,
|
message: AssertMessage<'tcx>,
|
||||||
) -> BasicBlock {
|
) -> BasicBlock {
|
||||||
let assert_block = BasicBlock::new(body.basic_blocks.len());
|
let assert_block = body.basic_blocks.next_index();
|
||||||
let kind = TerminatorKind::Assert {
|
let kind = TerminatorKind::Assert {
|
||||||
cond: Operand::Constant(Box::new(ConstOperand {
|
cond: Operand::Constant(Box::new(ConstOperand {
|
||||||
span: body.span,
|
span: body.span,
|
||||||
|
|
|
@ -258,17 +258,16 @@ where
|
||||||
) -> Vec<(Place<'tcx>, Option<D::Path>)> {
|
) -> Vec<(Place<'tcx>, Option<D::Path>)> {
|
||||||
variant
|
variant
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter_enumerated()
|
||||||
.enumerate()
|
.map(|(field_idx, field)| {
|
||||||
.map(|(i, f)| {
|
let subpath = self.elaborator.field_subpath(variant_path, field_idx);
|
||||||
let field = FieldIdx::new(i);
|
|
||||||
let subpath = self.elaborator.field_subpath(variant_path, field);
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
assert_eq!(self.elaborator.typing_env().typing_mode, ty::TypingMode::PostAnalysis);
|
assert_eq!(self.elaborator.typing_env().typing_mode, ty::TypingMode::PostAnalysis);
|
||||||
let field_ty = match tcx
|
let field_ty = match tcx.try_normalize_erasing_regions(
|
||||||
.try_normalize_erasing_regions(self.elaborator.typing_env(), f.ty(tcx, args))
|
self.elaborator.typing_env(),
|
||||||
{
|
field.ty(tcx, args),
|
||||||
|
) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(_) => Ty::new_error(
|
Err(_) => Ty::new_error(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
|
@ -279,7 +278,7 @@ where
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
(tcx.mk_place_field(base_place, field, field_ty), subpath)
|
(tcx.mk_place_field(base_place, field_idx, field_ty), subpath)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -903,9 +903,9 @@ fn inline_call<'tcx, I: Inliner<'tcx>>(
|
||||||
|
|
||||||
let mut integrator = Integrator {
|
let mut integrator = Integrator {
|
||||||
args: &args,
|
args: &args,
|
||||||
new_locals: Local::new(caller_body.local_decls.len())..,
|
new_locals: caller_body.local_decls.next_index()..,
|
||||||
new_scopes: SourceScope::new(caller_body.source_scopes.len())..,
|
new_scopes: caller_body.source_scopes.next_index()..,
|
||||||
new_blocks: BasicBlock::new(caller_body.basic_blocks.len())..,
|
new_blocks: caller_body.basic_blocks.next_index()..,
|
||||||
destination: destination_local,
|
destination: destination_local,
|
||||||
callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(),
|
callsite_scope: caller_body.source_scopes[callsite.source_info.scope].clone(),
|
||||||
callsite,
|
callsite,
|
||||||
|
@ -1169,7 +1169,7 @@ impl Integrator<'_, '_> {
|
||||||
if idx < self.args.len() {
|
if idx < self.args.len() {
|
||||||
self.args[idx]
|
self.args[idx]
|
||||||
} else {
|
} else {
|
||||||
Local::new(self.new_locals.start.index() + (idx - self.args.len()))
|
self.new_locals.start + (idx - self.args.len())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
trace!("mapping local `{:?}` to `{:?}`", local, new);
|
trace!("mapping local `{:?}` to `{:?}`", local, new);
|
||||||
|
@ -1177,13 +1177,13 @@ impl Integrator<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_scope(&self, scope: SourceScope) -> SourceScope {
|
fn map_scope(&self, scope: SourceScope) -> SourceScope {
|
||||||
let new = SourceScope::new(self.new_scopes.start.index() + scope.index());
|
let new = self.new_scopes.start + scope.index();
|
||||||
trace!("mapping scope `{:?}` to `{:?}`", scope, new);
|
trace!("mapping scope `{:?}` to `{:?}`", scope, new);
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_block(&self, block: BasicBlock) -> BasicBlock {
|
fn map_block(&self, block: BasicBlock) -> BasicBlock {
|
||||||
let new = BasicBlock::new(self.new_blocks.start.index() + block.index());
|
let new = self.new_blocks.start + block.index();
|
||||||
trace!("mapping block `{:?}` to `{:?}`", block, new);
|
trace!("mapping block `{:?}` to `{:?}`", block, new);
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@ impl<'tcx> MirPatch<'tcx> {
|
||||||
|
|
||||||
/// Queues the addition of a new basic block.
|
/// Queues the addition of a new basic block.
|
||||||
pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock {
|
pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock {
|
||||||
let block = BasicBlock::new(self.term_patch_map.len());
|
let block = self.term_patch_map.next_index();
|
||||||
debug!("MirPatch: new_block: {:?}: {:?}", block, data);
|
debug!("MirPatch: new_block: {:?}: {:?}", block, data);
|
||||||
self.new_blocks.push(data);
|
self.new_blocks.push(data);
|
||||||
self.term_patch_map.push(None);
|
self.term_patch_map.push(None);
|
||||||
|
|
|
@ -18,7 +18,7 @@ use either::{Left, Right};
|
||||||
use rustc_const_eval::check_consts::{ConstCx, qualifs};
|
use rustc_const_eval::check_consts::{ConstCx, qualifs};
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
use rustc_index::{IndexSlice, IndexVec};
|
||||||
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::{self, GenericArgs, List, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, GenericArgs, List, Ty, TyCtxt, TypeVisitableExt};
|
||||||
|
@ -864,17 +864,21 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||||
new_temp
|
new_temp
|
||||||
}
|
}
|
||||||
|
|
||||||
fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
|
fn promote_candidate(
|
||||||
|
mut self,
|
||||||
|
candidate: Candidate,
|
||||||
|
next_promoted_index: Promoted,
|
||||||
|
) -> Body<'tcx> {
|
||||||
let def = self.source.source.def_id();
|
let def = self.source.source.def_id();
|
||||||
let (mut rvalue, promoted_op) = {
|
let (mut rvalue, promoted_op) = {
|
||||||
let promoted = &mut self.promoted;
|
let promoted = &mut self.promoted;
|
||||||
let promoted_id = Promoted::new(next_promoted_id);
|
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let mut promoted_operand = |ty, span| {
|
let mut promoted_operand = |ty, span| {
|
||||||
promoted.span = span;
|
promoted.span = span;
|
||||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||||
let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
|
let args = tcx.erase_regions(GenericArgs::identity_for_item(tcx, def));
|
||||||
let uneval = mir::UnevaluatedConst { def, args, promoted: Some(promoted_id) };
|
let uneval =
|
||||||
|
mir::UnevaluatedConst { def, args, promoted: Some(next_promoted_index) };
|
||||||
|
|
||||||
ConstOperand { span, user_ty: None, const_: Const::Unevaluated(uneval, ty) }
|
ConstOperand { span, user_ty: None, const_: Const::Unevaluated(uneval, ty) }
|
||||||
};
|
};
|
||||||
|
@ -1034,7 +1038,7 @@ fn promote_candidates<'tcx>(
|
||||||
required_consts: Vec::new(),
|
required_consts: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut promoted = promoter.promote_candidate(candidate, promotions.len());
|
let mut promoted = promoter.promote_candidate(candidate, promotions.next_index());
|
||||||
promoted.source.promoted = Some(promotions.next_index());
|
promoted.source.promoted = Some(promotions.next_index());
|
||||||
promotions.push(promoted);
|
promotions.push(promoted);
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,7 +355,7 @@ where
|
||||||
// exist at all (see the FIXME at the start of this method), we have to deal with
|
// exist at all (see the FIXME at the start of this method), we have to deal with
|
||||||
// them for now.
|
// them for now.
|
||||||
delegate.instantiate_canonical_var_with_infer(info, span, |idx| {
|
delegate.instantiate_canonical_var_with_infer(info, span, |idx| {
|
||||||
ty::UniverseIndex::from(prev_universe.index() + idx.index())
|
prev_universe + idx.index()
|
||||||
})
|
})
|
||||||
} else if info.is_existential() {
|
} else if info.is_existential() {
|
||||||
// As an optimization we sometimes avoid creating a new inference variable here.
|
// As an optimization we sometimes avoid creating a new inference variable here.
|
||||||
|
|
|
@ -194,6 +194,12 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
|
} else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
|
||||||
|
// Allow (but don't require) `#[unsafe(naked)]` so that compiler-builtins can upgrade to it.
|
||||||
|
// FIXME(#139797): remove this special case when compiler-builtins has upgraded.
|
||||||
|
if attr.has_name(sym::naked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
|
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
|
||||||
span: unsafe_span,
|
span: unsafe_span,
|
||||||
name: attr_item.path.clone(),
|
name: attr_item.path.clone(),
|
||||||
|
|
|
@ -578,8 +578,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
F: FnMut(Variable) -> bool,
|
F: FnMut(Variable) -> bool,
|
||||||
{
|
{
|
||||||
for var_idx in 0..self.ir.var_kinds.len() {
|
for var in self.ir.var_kinds.indices() {
|
||||||
let var = Variable::from(var_idx);
|
|
||||||
if test(var) {
|
if test(var) {
|
||||||
write!(wr, " {var:?}")?;
|
write!(wr, " {var:?}")?;
|
||||||
}
|
}
|
||||||
|
@ -609,8 +608,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
debug!(
|
debug!(
|
||||||
"^^ liveness computation results for body {} (entry={:?})",
|
"^^ liveness computation results for body {} (entry={:?})",
|
||||||
{
|
{
|
||||||
for ln_idx in 0..self.ir.lnks.len() {
|
for ln_idx in self.ir.lnks.indices() {
|
||||||
debug!("{:?}", self.ln_str(LiveNode::from(ln_idx)));
|
debug!("{:?}", self.ln_str(ln_idx));
|
||||||
}
|
}
|
||||||
hir_id
|
hir_id
|
||||||
},
|
},
|
||||||
|
|
|
@ -1948,7 +1948,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
||||||
|
|
||||||
self.record_lifetime_res(
|
self.record_lifetime_res(
|
||||||
anchor_id,
|
anchor_id,
|
||||||
LifetimeRes::ElidedAnchor { start: id, end: NodeId::from_u32(id.as_u32() + 1) },
|
LifetimeRes::ElidedAnchor { start: id, end: id + 1 },
|
||||||
LifetimeElisionCandidate::Ignore,
|
LifetimeElisionCandidate::Ignore,
|
||||||
);
|
);
|
||||||
self.resolve_anonymous_lifetime(<, anchor_id, true);
|
self.resolve_anonymous_lifetime(<, anchor_id, true);
|
||||||
|
|
|
@ -1560,9 +1560,10 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
static PRINT_KINDS_STRING: LazyLock<String> = LazyLock::new(|| {
|
static PRINT_HELP: LazyLock<String> = LazyLock::new(|| {
|
||||||
format!(
|
format!(
|
||||||
"[{}]",
|
"Compiler information to print on stdout (or to a file)\n\
|
||||||
|
INFO may be one of ({}).",
|
||||||
PRINT_KINDS.iter().map(|(name, _)| format!("{name}")).collect::<Vec<_>>().join("|")
|
PRINT_KINDS.iter().map(|(name, _)| format!("{name}")).collect::<Vec<_>>().join("|")
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -1621,14 +1622,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
||||||
"Comma separated list of types of output for the compiler to emit",
|
"Comma separated list of types of output for the compiler to emit",
|
||||||
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
|
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
|
||||||
),
|
),
|
||||||
opt(
|
opt(Stable, Multi, "", "print", &PRINT_HELP, "INFO[=FILE]"),
|
||||||
Stable,
|
|
||||||
Multi,
|
|
||||||
"",
|
|
||||||
"print",
|
|
||||||
"Compiler information to print on stdout",
|
|
||||||
&PRINT_KINDS_STRING,
|
|
||||||
),
|
|
||||||
opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
|
opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
|
||||||
opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
|
opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
|
||||||
opt(Stable, Opt, "o", "", "Write output to <filename>", "FILENAME"),
|
opt(Stable, Opt, "o", "", "Write output to <filename>", "FILENAME"),
|
||||||
|
|
|
@ -643,7 +643,7 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
||||||
) -> GenericArgsRef<'tcx> {
|
) -> GenericArgsRef<'tcx> {
|
||||||
struct ReplaceParamAndInferWithPlaceholder<'tcx> {
|
struct ReplaceParamAndInferWithPlaceholder<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
idx: u32,
|
idx: ty::BoundVar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceParamAndInferWithPlaceholder<'tcx> {
|
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceParamAndInferWithPlaceholder<'tcx> {
|
||||||
|
@ -653,19 +653,13 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if let ty::Infer(_) = t.kind() {
|
if let ty::Infer(_) = t.kind() {
|
||||||
let idx = {
|
let idx = self.idx;
|
||||||
let idx = self.idx;
|
self.idx += 1;
|
||||||
self.idx += 1;
|
|
||||||
idx
|
|
||||||
};
|
|
||||||
Ty::new_placeholder(
|
Ty::new_placeholder(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::PlaceholderType {
|
ty::PlaceholderType {
|
||||||
universe: ty::UniverseIndex::ROOT,
|
universe: ty::UniverseIndex::ROOT,
|
||||||
bound: ty::BoundTy {
|
bound: ty::BoundTy { var: idx, kind: ty::BoundTyKind::Anon },
|
||||||
var: ty::BoundVar::from_u32(idx),
|
|
||||||
kind: ty::BoundTyKind::Anon,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -675,16 +669,11 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
||||||
|
|
||||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
if let ty::ConstKind::Infer(_) = c.kind() {
|
if let ty::ConstKind::Infer(_) = c.kind() {
|
||||||
|
let idx = self.idx;
|
||||||
|
self.idx += 1;
|
||||||
ty::Const::new_placeholder(
|
ty::Const::new_placeholder(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::PlaceholderConst {
|
ty::PlaceholderConst { universe: ty::UniverseIndex::ROOT, bound: idx },
|
||||||
universe: ty::UniverseIndex::ROOT,
|
|
||||||
bound: ty::BoundVar::from_u32({
|
|
||||||
let idx = self.idx;
|
|
||||||
self.idx += 1;
|
|
||||||
idx
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
c.super_fold_with(self)
|
c.super_fold_with(self)
|
||||||
|
@ -692,7 +681,7 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
|
args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: ty::BoundVar::ZERO })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
|
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use core::num::NonZero;
|
use core::num::NonZero;
|
||||||
|
|
||||||
|
use crate::cmp::Ordering;
|
||||||
use crate::iter::adapters::zip::try_get_unchecked;
|
use crate::iter::adapters::zip::try_get_unchecked;
|
||||||
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
||||||
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
|
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen, UncheckedIterator};
|
||||||
|
@ -41,13 +42,31 @@ where
|
||||||
self.it.next().cloned()
|
self.it.next().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
self.it.size_hint()
|
self.it.size_hint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn count(self) -> usize {
|
||||||
|
self.it.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn last(self) -> Option<T> {
|
||||||
|
self.it.last().cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
||||||
|
self.it.advance_by(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nth(&mut self, n: usize) -> Option<T> {
|
||||||
|
self.it.nth(n).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||||
where
|
where
|
||||||
Self: Sized,
|
|
||||||
F: FnMut(B, Self::Item) -> R,
|
F: FnMut(B, Self::Item) -> R,
|
||||||
R: Try<Output = B>,
|
R: Try<Output = B>,
|
||||||
{
|
{
|
||||||
|
@ -61,6 +80,58 @@ where
|
||||||
self.it.map(T::clone).fold(init, f)
|
self.it.map(T::clone).fold(init, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
|
||||||
|
where
|
||||||
|
P: FnMut(&Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
self.it.find(move |x| predicate(&x)).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
|
||||||
|
where
|
||||||
|
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
|
||||||
|
{
|
||||||
|
self.it.max_by(move |&x, &y| compare(x, y)).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
|
||||||
|
where
|
||||||
|
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
|
||||||
|
{
|
||||||
|
self.it.min_by(move |&x, &y| compare(x, y)).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cmp<O>(self, other: O) -> Ordering
|
||||||
|
where
|
||||||
|
O: IntoIterator<Item = Self::Item>,
|
||||||
|
Self::Item: Ord,
|
||||||
|
{
|
||||||
|
self.it.cmp_by(other, |x, y| x.cmp(&y))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn partial_cmp<O>(self, other: O) -> Option<Ordering>
|
||||||
|
where
|
||||||
|
O: IntoIterator,
|
||||||
|
Self::Item: PartialOrd<O::Item>,
|
||||||
|
{
|
||||||
|
self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eq<O>(self, other: O) -> bool
|
||||||
|
where
|
||||||
|
O: IntoIterator,
|
||||||
|
Self::Item: PartialEq<O::Item>,
|
||||||
|
{
|
||||||
|
self.it.eq_by(other, |x, y| x == &y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_sorted_by<F>(self, mut compare: F) -> bool
|
||||||
|
where
|
||||||
|
F: FnMut(&Self::Item, &Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
self.it.is_sorted_by(move |&x, &y| compare(x, y))
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
|
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
|
||||||
where
|
where
|
||||||
Self: TrustedRandomAccessNoCoerce,
|
Self: TrustedRandomAccessNoCoerce,
|
||||||
|
@ -81,9 +152,13 @@ where
|
||||||
self.it.next_back().cloned()
|
self.it.next_back().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
||||||
|
self.it.advance_back_by(n)
|
||||||
|
}
|
||||||
|
|
||||||
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||||
where
|
where
|
||||||
Self: Sized,
|
|
||||||
F: FnMut(B, Self::Item) -> R,
|
F: FnMut(B, Self::Item) -> R,
|
||||||
R: Try<Output = B>,
|
R: Try<Output = B>,
|
||||||
{
|
{
|
||||||
|
@ -96,6 +171,13 @@ where
|
||||||
{
|
{
|
||||||
self.it.map(T::clone).rfold(init, f)
|
self.it.map(T::clone).rfold(init, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
|
||||||
|
where
|
||||||
|
P: FnMut(&Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
self.it.rfind(move |x| predicate(&x)).cloned()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "iter_cloned", since = "1.1.0")]
|
#[stable(feature = "iter_cloned", since = "1.1.0")]
|
||||||
|
@ -104,10 +186,12 @@ where
|
||||||
I: ExactSizeIterator<Item = &'a T>,
|
I: ExactSizeIterator<Item = &'a T>,
|
||||||
T: Clone,
|
T: Clone,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.it.len()
|
self.it.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.it.is_empty()
|
self.it.is_empty()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::cmp::Ordering;
|
||||||
use crate::iter::adapters::zip::try_get_unchecked;
|
use crate::iter::adapters::zip::try_get_unchecked;
|
||||||
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
|
||||||
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
|
use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen};
|
||||||
|
@ -48,20 +49,35 @@ where
|
||||||
|
|
||||||
fn next_chunk<const N: usize>(
|
fn next_chunk<const N: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
|
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
<I as SpecNextChunk<'_, N, T>>::spec_next_chunk(&mut self.it)
|
<I as SpecNextChunk<'_, N, T>>::spec_next_chunk(&mut self.it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
self.it.size_hint()
|
self.it.size_hint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn count(self) -> usize {
|
||||||
|
self.it.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn last(self) -> Option<T> {
|
||||||
|
self.it.last().copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
||||||
|
self.it.advance_by(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nth(&mut self, n: usize) -> Option<T> {
|
||||||
|
self.it.nth(n).copied()
|
||||||
|
}
|
||||||
|
|
||||||
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||||
where
|
where
|
||||||
Self: Sized,
|
|
||||||
F: FnMut(B, Self::Item) -> R,
|
F: FnMut(B, Self::Item) -> R,
|
||||||
R: Try<Output = B>,
|
R: Try<Output = B>,
|
||||||
{
|
{
|
||||||
|
@ -75,21 +91,56 @@ where
|
||||||
self.it.fold(init, copy_fold(f))
|
self.it.fold(init, copy_fold(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nth(&mut self, n: usize) -> Option<T> {
|
fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item>
|
||||||
self.it.nth(n).copied()
|
where
|
||||||
|
P: FnMut(&Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
self.it.find(move |x| predicate(&x)).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn last(self) -> Option<T> {
|
fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
|
||||||
self.it.last().copied()
|
where
|
||||||
|
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
|
||||||
|
{
|
||||||
|
self.it.max_by(move |&x, &y| compare(x, y)).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count(self) -> usize {
|
fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
|
||||||
self.it.count()
|
where
|
||||||
|
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
|
||||||
|
{
|
||||||
|
self.it.min_by(move |&x, &y| compare(x, y)).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn cmp<O>(self, other: O) -> Ordering
|
||||||
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
where
|
||||||
self.it.advance_by(n)
|
O: IntoIterator<Item = Self::Item>,
|
||||||
|
Self::Item: Ord,
|
||||||
|
{
|
||||||
|
self.it.cmp_by(other, |x, y| x.cmp(&y))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn partial_cmp<O>(self, other: O) -> Option<Ordering>
|
||||||
|
where
|
||||||
|
O: IntoIterator,
|
||||||
|
Self::Item: PartialOrd<O::Item>,
|
||||||
|
{
|
||||||
|
self.it.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eq<O>(self, other: O) -> bool
|
||||||
|
where
|
||||||
|
O: IntoIterator,
|
||||||
|
Self::Item: PartialEq<O::Item>,
|
||||||
|
{
|
||||||
|
self.it.eq_by(other, |x, y| x == &y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_sorted_by<F>(self, mut compare: F) -> bool
|
||||||
|
where
|
||||||
|
F: FnMut(&Self::Item, &Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
self.it.is_sorted_by(move |&x, &y| compare(x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
|
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
|
||||||
|
@ -112,9 +163,13 @@ where
|
||||||
self.it.next_back().copied()
|
self.it.next_back().copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
||||||
|
self.it.advance_back_by(n)
|
||||||
|
}
|
||||||
|
|
||||||
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
|
||||||
where
|
where
|
||||||
Self: Sized,
|
|
||||||
F: FnMut(B, Self::Item) -> R,
|
F: FnMut(B, Self::Item) -> R,
|
||||||
R: Try<Output = B>,
|
R: Try<Output = B>,
|
||||||
{
|
{
|
||||||
|
@ -128,9 +183,11 @@ where
|
||||||
self.it.rfold(init, copy_fold(f))
|
self.it.rfold(init, copy_fold(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
|
||||||
fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
|
where
|
||||||
self.it.advance_back_by(n)
|
P: FnMut(&Self::Item) -> bool,
|
||||||
|
{
|
||||||
|
self.it.rfind(move |x| predicate(&x)).copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,10 +197,12 @@ where
|
||||||
I: ExactSizeIterator<Item = &'a T>,
|
I: ExactSizeIterator<Item = &'a T>,
|
||||||
T: Copy,
|
T: Copy,
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
self.it.len()
|
self.it.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.it.is_empty()
|
self.it.is_empty()
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,9 +257,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.14"
|
version = "0.5.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471"
|
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
@ -436,9 +436,9 @@ checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libffi"
|
name = "libffi"
|
||||||
version = "3.2.0"
|
version = "4.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2"
|
checksum = "4a9434b6fc77375fb624698d5f8c49d7e80b10d59eb1219afda27d1f824d4074"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"libffi-sys",
|
"libffi-sys",
|
||||||
|
@ -446,9 +446,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libffi-sys"
|
name = "libffi-sys"
|
||||||
version = "2.3.0"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f36115160c57e8529781b4183c2bb51fdc1f6d6d1ed345591d84be7703befb3c"
|
checksum = "ead36a2496acfc8edd6cc32352110e9478ac5b9b5f5b9856ebd3d28019addb84"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,7 @@ features = ['unprefixed_malloc_on_supported_platforms']
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
libffi = "3.2.0"
|
libffi = "4.0.0"
|
||||||
libloading = "0.8"
|
libloading = "0.8"
|
||||||
|
|
||||||
[target.'cfg(target_family = "windows")'.dependencies]
|
[target.'cfg(target_family = "windows")'.dependencies]
|
||||||
|
|
|
@ -164,9 +164,9 @@ case $HOST_TARGET in
|
||||||
# Partially supported targets (tier 2)
|
# Partially supported targets (tier 2)
|
||||||
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
|
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
|
||||||
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
|
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
|
||||||
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe concurrency sync
|
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency fs libc-pipe
|
||||||
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
|
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency fs libc-pipe
|
||||||
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random sync concurrency thread epoll eventfd
|
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd
|
||||||
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
|
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
|
||||||
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
|
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
|
||||||
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
|
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
7d7de5bf3c3cbf9c2c5bbc5cbfb9197a8a427d35
|
1bc56185ee257ed829a0aea7abdc3b03c5fed887
|
||||||
|
|
|
@ -65,7 +65,7 @@ fn win_get_full_path_name<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<Pa
|
||||||
}
|
}
|
||||||
// Otherwise we try to do something kind of close to what Windows does, but this is probably not
|
// Otherwise we try to do something kind of close to what Windows does, but this is probably not
|
||||||
// right in all cases.
|
// right in all cases.
|
||||||
let mut result: Vec<&[u8]> = vec![]; // will be a vecot of components, joined by `/`.
|
let mut result: Vec<&[u8]> = vec![]; // will be a vector of components, joined by `/`.
|
||||||
let mut bytes = bytes; // the remaining bytes to process
|
let mut bytes = bytes; // the remaining bytes to process
|
||||||
let mut stop = false;
|
let mut stop = false;
|
||||||
while !stop {
|
while !stop {
|
||||||
|
@ -396,6 +396,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
let last_error = this.get_last_error()?;
|
let last_error = this.get_last_error()?;
|
||||||
this.write_scalar(last_error, dest)?;
|
this.write_scalar(last_error, dest)?;
|
||||||
}
|
}
|
||||||
|
"RtlNtStatusToDosError" => {
|
||||||
|
let [status] = this.check_shim(abi, sys_conv, link_name, args)?;
|
||||||
|
let status = this.read_scalar(status)?.to_u32()?;
|
||||||
|
let err = match status {
|
||||||
|
// STATUS_MEDIA_WRITE_PROTECTED => ERROR_WRITE_PROTECT
|
||||||
|
0xC00000A2 => 19,
|
||||||
|
// STATUS_FILE_INVALID => ERROR_FILE_INVALID
|
||||||
|
0xC0000098 => 1006,
|
||||||
|
// STATUS_DISK_FULL => ERROR_DISK_FULL
|
||||||
|
0xC000007F => 112,
|
||||||
|
// STATUS_IO_DEVICE_ERROR => ERROR_IO_DEVICE
|
||||||
|
0xC0000185 => 1117,
|
||||||
|
// STATUS_ACCESS_DENIED => ERROR_ACCESS_DENIED
|
||||||
|
0xC0000022 => 5,
|
||||||
|
// Anything without an error code => ERROR_MR_MID_NOT_FOUND
|
||||||
|
_ => 317,
|
||||||
|
};
|
||||||
|
this.write_scalar(Scalar::from_i32(err), dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Querying system information
|
// Querying system information
|
||||||
"GetSystemInfo" => {
|
"GetSystemInfo" => {
|
||||||
|
|
|
@ -10,7 +10,9 @@ use std::ptr;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use windows_sys::Win32::Foundation::{
|
use windows_sys::Win32::Foundation::{
|
||||||
CloseHandle, ERROR_ALREADY_EXISTS, GENERIC_READ, GENERIC_WRITE, GetLastError,
|
CloseHandle, ERROR_ACCESS_DENIED, ERROR_ALREADY_EXISTS, ERROR_IO_DEVICE, GENERIC_READ,
|
||||||
|
GENERIC_WRITE, GetLastError, RtlNtStatusToDosError, STATUS_ACCESS_DENIED,
|
||||||
|
STATUS_IO_DEVICE_ERROR,
|
||||||
};
|
};
|
||||||
use windows_sys::Win32::Storage::FileSystem::{
|
use windows_sys::Win32::Storage::FileSystem::{
|
||||||
BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
|
BY_HANDLE_FILE_INFORMATION, CREATE_ALWAYS, CREATE_NEW, CreateFileW, FILE_ATTRIBUTE_DIRECTORY,
|
||||||
|
@ -26,6 +28,7 @@ fn main() {
|
||||||
test_create_always_twice();
|
test_create_always_twice();
|
||||||
test_open_always_twice();
|
test_open_always_twice();
|
||||||
test_open_dir_reparse();
|
test_open_dir_reparse();
|
||||||
|
test_ntstatus_to_dos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +194,12 @@ unsafe fn test_open_dir_reparse() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn test_ntstatus_to_dos() {
|
||||||
|
// We won't test all combinations, just a couple common ones
|
||||||
|
assert_eq!(RtlNtStatusToDosError(STATUS_IO_DEVICE_ERROR), ERROR_IO_DEVICE);
|
||||||
|
assert_eq!(RtlNtStatusToDosError(STATUS_ACCESS_DENIED), ERROR_ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
|
||||||
fn to_wide_cstr(path: &Path) -> Vec<u16> {
|
fn to_wide_cstr(path: &Path) -> Vec<u16> {
|
||||||
let mut raw_path = path.as_os_str().encode_wide().collect::<Vec<_>>();
|
let mut raw_path = path.as_os_str().encode_wide().collect::<Vec<_>>();
|
||||||
raw_path.extend([0, 0]);
|
raw_path.extend([0, 0]);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::mem::{size_of, align_of};
|
use std::mem::{align_of, size_of};
|
||||||
|
|
||||||
// See <https://github.com/rust-lang/rust/issues/134713>
|
// See <https://github.com/rust-lang/rust/issues/134713>
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,9 @@ fn merge_llvm_profiles(
|
||||||
profdata: LlvmProfdata,
|
profdata: LlvmProfdata,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let llvm_profdata = match profdata {
|
let llvm_profdata = match profdata {
|
||||||
LlvmProfdata::Host => env.host_llvm_dir().join("bin/llvm-profdata"),
|
LlvmProfdata::Host => {
|
||||||
|
env.host_llvm_dir().join(format!("bin/llvm-profdata{}", executable_extension()))
|
||||||
|
}
|
||||||
LlvmProfdata::Target => env
|
LlvmProfdata::Target => env
|
||||||
.build_artifacts()
|
.build_artifacts()
|
||||||
.join("llvm")
|
.join("llvm")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@@ -51,10 +51,27 @@
|
@@ -53,10 +53,27 @@
|
||||||
Set a codegen option
|
Set a codegen option
|
||||||
-V, --version Print version info and exit
|
-V, --version Print version info and exit
|
||||||
-v, --verbose Use verbose output
|
-v, --verbose Use verbose output
|
||||||
|
|
|
@ -29,8 +29,10 @@ Options:
|
||||||
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
|
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
|
||||||
Comma separated list of types of output for the
|
Comma separated list of types of output for the
|
||||||
compiler to emit
|
compiler to emit
|
||||||
--print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
|
--print INFO[=FILE]
|
||||||
Compiler information to print on stdout
|
Compiler information to print on stdout (or to a file)
|
||||||
|
INFO may be one of
|
||||||
|
(all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models).
|
||||||
-g Equivalent to -C debuginfo=2
|
-g Equivalent to -C debuginfo=2
|
||||||
-O Equivalent to -C opt-level=3
|
-O Equivalent to -C opt-level=3
|
||||||
-o FILENAME Write output to <filename>
|
-o FILENAME Write output to <filename>
|
||||||
|
|
|
@ -29,8 +29,10 @@ Options:
|
||||||
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
|
--emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
|
||||||
Comma separated list of types of output for the
|
Comma separated list of types of output for the
|
||||||
compiler to emit
|
compiler to emit
|
||||||
--print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
|
--print INFO[=FILE]
|
||||||
Compiler information to print on stdout
|
Compiler information to print on stdout (or to a file)
|
||||||
|
INFO may be one of
|
||||||
|
(all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models).
|
||||||
-g Equivalent to -C debuginfo=2
|
-g Equivalent to -C debuginfo=2
|
||||||
-O Equivalent to -C opt-level=3
|
-O Equivalent to -C opt-level=3
|
||||||
-o FILENAME Write output to <filename>
|
-o FILENAME Write output to <filename>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use std::arch::{asm, naked_asm};
|
use std::arch::{asm, naked_asm};
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn inline_asm_macro() {
|
pub unsafe extern "C" fn inline_asm_macro() {
|
||||||
asm!("", options(raw));
|
asm!("", options(raw));
|
||||||
//~^ERROR the `asm!` macro is not allowed in naked functions
|
//~^ERROR the `asm!` macro is not allowed in naked functions
|
||||||
|
@ -20,7 +20,7 @@ pub struct P {
|
||||||
y: u16,
|
y: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn patterns(
|
pub unsafe extern "C" fn patterns(
|
||||||
mut a: u32,
|
mut a: u32,
|
||||||
//~^ ERROR patterns not allowed in naked function parameters
|
//~^ ERROR patterns not allowed in naked function parameters
|
||||||
|
@ -34,27 +34,27 @@ pub unsafe extern "C" fn patterns(
|
||||||
naked_asm!("")
|
naked_asm!("")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn inc(a: u32) -> u32 {
|
pub unsafe extern "C" fn inc(a: u32) -> u32 {
|
||||||
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
||||||
a + 1
|
a + 1
|
||||||
//~^ ERROR referencing function parameters is not allowed in naked functions
|
//~^ ERROR referencing function parameters is not allowed in naked functions
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
#[allow(asm_sub_register)]
|
#[allow(asm_sub_register)]
|
||||||
pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
|
pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
|
||||||
naked_asm!("/* {0} */", in(reg) a)
|
naked_asm!("/* {0} */", in(reg) a)
|
||||||
//~^ ERROR the `in` operand cannot be used with `naked_asm!`
|
//~^ ERROR the `in` operand cannot be used with `naked_asm!`
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
|
pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
|
||||||
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
||||||
(|| a + 1)()
|
(|| a + 1)()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn unsupported_operands() {
|
pub unsafe extern "C" fn unsupported_operands() {
|
||||||
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
||||||
let mut a = 0usize;
|
let mut a = 0usize;
|
||||||
|
@ -76,12 +76,12 @@ pub unsafe extern "C" fn unsupported_operands() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub extern "C" fn missing_assembly() {
|
pub extern "C" fn missing_assembly() {
|
||||||
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub extern "C" fn too_many_asm_blocks() {
|
pub extern "C" fn too_many_asm_blocks() {
|
||||||
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -92,7 +92,7 @@ pub extern "C" fn too_many_asm_blocks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
|
pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub extern "C" fn inner(y: usize) -> usize {
|
pub extern "C" fn inner(y: usize) -> usize {
|
||||||
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
//~^ ERROR naked functions must contain a single `naked_asm!` invocation
|
||||||
*&y
|
*&y
|
||||||
|
@ -101,14 +101,14 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
|
||||||
inner
|
inner
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
unsafe extern "C" fn invalid_options() {
|
unsafe extern "C" fn invalid_options() {
|
||||||
naked_asm!("", options(nomem, preserves_flags));
|
naked_asm!("", options(nomem, preserves_flags));
|
||||||
//~^ ERROR the `nomem` option cannot be used with `naked_asm!`
|
//~^ ERROR the `nomem` option cannot be used with `naked_asm!`
|
||||||
//~| ERROR the `preserves_flags` option cannot be used with `naked_asm!`
|
//~| ERROR the `preserves_flags` option cannot be used with `naked_asm!`
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
unsafe extern "C" fn invalid_options_continued() {
|
unsafe extern "C" fn invalid_options_continued() {
|
||||||
naked_asm!("", options(readonly, nostack), options(pure));
|
naked_asm!("", options(readonly, nostack), options(pure));
|
||||||
//~^ ERROR the `readonly` option cannot be used with `naked_asm!`
|
//~^ ERROR the `readonly` option cannot be used with `naked_asm!`
|
||||||
|
@ -116,20 +116,20 @@ unsafe extern "C" fn invalid_options_continued() {
|
||||||
//~| ERROR the `pure` option cannot be used with `naked_asm!`
|
//~| ERROR the `pure` option cannot be used with `naked_asm!`
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
unsafe extern "C" fn invalid_may_unwind() {
|
unsafe extern "C" fn invalid_may_unwind() {
|
||||||
naked_asm!("", options(may_unwind));
|
naked_asm!("", options(may_unwind));
|
||||||
//~^ ERROR the `may_unwind` option cannot be used with `naked_asm!`
|
//~^ ERROR the `may_unwind` option cannot be used with `naked_asm!`
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub extern "C" fn valid_a<T>() -> T {
|
pub extern "C" fn valid_a<T>() -> T {
|
||||||
unsafe {
|
unsafe {
|
||||||
naked_asm!("");
|
naked_asm!("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub extern "C" fn valid_b() {
|
pub extern "C" fn valid_b() {
|
||||||
unsafe {
|
unsafe {
|
||||||
{
|
{
|
||||||
|
@ -140,32 +140,32 @@ pub extern "C" fn valid_b() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn valid_c() {
|
pub unsafe extern "C" fn valid_c() {
|
||||||
naked_asm!("");
|
naked_asm!("");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn valid_att_syntax() {
|
pub unsafe extern "C" fn valid_att_syntax() {
|
||||||
naked_asm!("", options(att_syntax));
|
naked_asm!("", options(att_syntax));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
|
pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
|
||||||
compile_error!("this is a user specified error")
|
compile_error!("this is a user specified error")
|
||||||
//~^ ERROR this is a user specified error
|
//~^ ERROR this is a user specified error
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
|
pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
|
||||||
compile_error!("this is a user specified error");
|
compile_error!("this is a user specified error");
|
||||||
//~^ ERROR this is a user specified error
|
//~^ ERROR this is a user specified error
|
||||||
naked_asm!("")
|
naked_asm!("")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
|
pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
|
||||||
naked_asm!(invalid_syntax)
|
naked_asm!(invalid_syntax)
|
||||||
//~^ ERROR asm template must be a string literal
|
//~^ ERROR asm template must be a string literal
|
||||||
|
@ -173,7 +173,7 @@ pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[cfg_attr(target_pointer_width = "64", no_mangle)]
|
#[cfg_attr(target_pointer_width = "64", no_mangle)]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_cfg_attributes() {
|
pub unsafe extern "C" fn compatible_cfg_attributes() {
|
||||||
naked_asm!("", options(att_syntax));
|
naked_asm!("", options(att_syntax));
|
||||||
}
|
}
|
||||||
|
@ -182,20 +182,20 @@ pub unsafe extern "C" fn compatible_cfg_attributes() {
|
||||||
#[warn(dead_code)]
|
#[warn(dead_code)]
|
||||||
#[deny(dead_code)]
|
#[deny(dead_code)]
|
||||||
#[forbid(dead_code)]
|
#[forbid(dead_code)]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_diagnostic_attributes() {
|
pub unsafe extern "C" fn compatible_diagnostic_attributes() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated = "test"]
|
#[deprecated = "test"]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_deprecated_attributes() {
|
pub unsafe extern "C" fn compatible_deprecated_attributes() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
|
pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
|
||||||
naked_asm!(
|
naked_asm!(
|
||||||
"
|
"
|
||||||
|
@ -207,13 +207,13 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
|
||||||
|
|
||||||
#[export_name = "exported_function_name"]
|
#[export_name = "exported_function_name"]
|
||||||
#[link_section = ".custom_section"]
|
#[link_section = ".custom_section"]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
|
pub unsafe extern "C" fn compatible_ffi_attributes_1() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cold]
|
#[cold]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_codegen_attributes() {
|
pub unsafe extern "C" fn compatible_codegen_attributes() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
}
|
}
|
||||||
|
@ -222,13 +222,13 @@ pub unsafe extern "C" fn compatible_codegen_attributes() {
|
||||||
/// a doc comment
|
/// a doc comment
|
||||||
// a normal comment
|
// a normal comment
|
||||||
#[doc(alias = "ADocAlias")]
|
#[doc(alias = "ADocAlias")]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_doc_attributes() {
|
pub unsafe extern "C" fn compatible_doc_attributes() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[linkage = "external"]
|
#[linkage = "external"]
|
||||||
#[naked]
|
#[unsafe(naked)]
|
||||||
pub unsafe extern "C" fn compatible_linkage() {
|
pub unsafe extern "C" fn compatible_linkage() {
|
||||||
naked_asm!("", options(raw));
|
naked_asm!("", options(raw));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
//! Not used by compiler, this is used by bootstrap cli self-test.
|
//! Not used by compiler, this is used by bootstrap cli self-test.
|
||||||
//@ ignore-test (used by bootstrap)
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
//! Not used by compiler, used by bootstrap cli self-test.
|
//! Not used by compiler, used by bootstrap cli self-test.
|
||||||
//@ ignore-test (used by bootstrap)
|
|
||||||
|
|
0
tests/ui/bootstrap/self-test/compiletest-ignore-dir
Normal file
0
tests/ui/bootstrap/self-test/compiletest-ignore-dir
Normal file
|
@ -1,5 +1,6 @@
|
||||||
error: Argument to option 'print' missing
|
error: Argument to option 'print' missing
|
||||||
Usage:
|
Usage:
|
||||||
--print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
|
--print INFO[=FILE] Compiler information to print on stdout (or to a file)
|
||||||
Compiler information to print on stdout
|
INFO may be one of
|
||||||
|
(all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|crate-root-lint-levels|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models).
|
||||||
|
|
||||||
|
|
30
tests/ui/traits/associated_type_bound/hrtb-associated.rs
Normal file
30
tests/ui/traits/associated_type_bound/hrtb-associated.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//@ check-pass
|
||||||
|
//! This test ensures that HRTB (higher-ranked trait bounds) on associated types
|
||||||
|
//! compile correctly. This was previously rejected by the compiler.
|
||||||
|
//! Related issue: <https://github.com/rust-lang/rust/issues/34834>
|
||||||
|
|
||||||
|
pub trait Provides<'a> {
|
||||||
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Selector: for<'a> Provides<'a> {
|
||||||
|
type Namespace: PartialEq + for<'a> PartialEq<<Self as Provides<'a>>::Item>;
|
||||||
|
|
||||||
|
fn get_namespace(&self) -> <Self as Provides>::Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MySelector;
|
||||||
|
|
||||||
|
impl<'a> Provides<'a> for MySelector {
|
||||||
|
type Item = &'a str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Selector for MySelector {
|
||||||
|
type Namespace = String;
|
||||||
|
|
||||||
|
fn get_namespace(&self) -> &str {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue