Skip to content

Commit 74e8046

Browse files
committed
Auto merge of rust-lang#72778 - RalfJung:rollup-f01z68m, r=RalfJung
Rollup of 9 pull requests Successful merges: - rust-lang#72299 (more `LocalDefId`s) - rust-lang#72368 (Resolve overflow behavior for RangeFrom) - rust-lang#72441 (Fix ICE with explicit late-bound lifetimes) - rust-lang#72499 (Override Box::<[T]>::clone_from) - rust-lang#72521 (Properly handle InlineAsmOperand::SymFn when collecting monomorphized items) - rust-lang#72540 (mir: adjust conditional in recursion limit check) - rust-lang#72563 (multiple Return terminators are possible) - rust-lang#72585 (Only capture tokens for items with outer attributes) - rust-lang#72607 (Eagerly lower asm sub-expressions to HIR even if there is an error) Failed merges: r? @ghost
2 parents 91fb72a + 69310de commit 74e8046

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+580
-256
lines changed

src/liballoc/boxed.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,14 @@ impl<T: Clone> Clone for Box<[T]> {
11091109
fn clone(&self) -> Self {
11101110
self.to_vec().into_boxed_slice()
11111111
}
1112+
1113+
fn clone_from(&mut self, other: &Self) {
1114+
if self.len() == other.len() {
1115+
self.clone_from_slice(&other);
1116+
} else {
1117+
*self = other.clone();
1118+
}
1119+
}
11121120
}
11131121

11141122
#[stable(feature = "box_borrow", since = "1.1.0")]

src/liballoc/tests/boxed.rs

+33
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,36 @@ fn unitialized_zero_size_box() {
1616
NonNull::<MaybeUninit<String>>::dangling().as_ptr(),
1717
);
1818
}
19+
20+
#[derive(Clone, PartialEq, Eq, Debug)]
21+
struct Dummy {
22+
_data: u8,
23+
}
24+
25+
#[test]
26+
fn box_clone_and_clone_from_equivalence() {
27+
for size in (0..8).map(|i| 2usize.pow(i)) {
28+
let control = vec![Dummy { _data: 42 }; size].into_boxed_slice();
29+
let clone = control.clone();
30+
let mut copy = vec![Dummy { _data: 84 }; size].into_boxed_slice();
31+
copy.clone_from(&control);
32+
assert_eq!(control, clone);
33+
assert_eq!(control, copy);
34+
}
35+
}
36+
37+
/// This test might give a false positive in case the box realocates, but the alocator keeps the
38+
/// original pointer.
39+
///
40+
/// On the other hand it won't give a false negative, if it fails than the memory was definitly not
41+
/// reused
42+
#[test]
43+
fn box_clone_from_ptr_stability() {
44+
for size in (0..8).map(|i| 2usize.pow(i)) {
45+
let control = vec![Dummy { _data: 42 }; size].into_boxed_slice();
46+
let mut copy = vec![Dummy { _data: 84 }; size].into_boxed_slice();
47+
let copy_raw = copy.as_ptr() as usize;
48+
copy.clone_from(&control);
49+
assert_eq!(copy.as_ptr() as usize, copy_raw);
50+
}
51+
}

src/libcore/iter/range.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -619,15 +619,7 @@ impl<A: Step> Iterator for ops::RangeFrom<A> {
619619

620620
#[inline]
621621
fn nth(&mut self, n: usize) -> Option<A> {
622-
// If we would jump over the maximum value, panic immediately.
623-
// This is consistent with behavior before the Step redesign,
624-
// even though it's inconsistent with n `next` calls.
625-
// To get consistent behavior, change it to use `forward` instead.
626-
// This change should go through FCP separately to the redesign, so is for now left as a
627-
// FIXME: make this consistent
628-
let plus_n =
629-
Step::forward_checked(self.start.clone(), n).expect("overflow in RangeFrom::nth");
630-
// The final step should always be debug-checked.
622+
let plus_n = Step::forward(self.start.clone(), n);
631623
self.start = Step::forward(plus_n.clone(), 1);
632624
Some(plus_n)
633625
}

src/libcore/ops/range.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,16 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
151151
///
152152
/// The `RangeFrom` `start..` contains all values with `x >= start`.
153153
///
154-
/// *Note*: Currently, no overflow checking is done for the [`Iterator`]
155-
/// implementation; if you use an integer range and the integer overflows, it
156-
/// might panic in debug mode or create an endless loop in release mode. **This
157-
/// overflow behavior might change in the future.**
154+
/// *Note*: Overflow in the [`Iterator`] implementation (when the contained
155+
/// data type reaches its numerical limit) is allowed to panic, wrap, or
156+
/// saturate. This behavior is defined by the implementation of the [`Step`]
157+
/// trait. For primitive integers, this follows the normal rules, and respects
158+
/// the overflow checks profile (panic in debug, wrap in release). Note also
159+
/// that overflow happens earlier than you might assume: the overflow happens
160+
/// in the call to `next` that yields the maximum value, as the range must be
161+
/// set to a state to yield the next value.
162+
///
163+
/// [`Step`]: crate::iter::Step
158164
///
159165
/// # Examples
160166
///

src/librustc_ast_lowering/expr.rs

+36-34
Original file line numberDiff line numberDiff line change
@@ -974,20 +974,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
974974
}
975975

976976
fn lower_expr_asm(&mut self, sp: Span, asm: &InlineAsm) -> hir::ExprKind<'hir> {
977-
let asm_arch = if let Some(asm_arch) = self.sess.asm_arch {
978-
asm_arch
979-
} else {
977+
if self.sess.asm_arch.is_none() {
980978
struct_span_err!(self.sess, sp, E0472, "asm! is unsupported on this target").emit();
981-
return hir::ExprKind::Err;
982-
};
983-
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
984-
match asm_arch {
985-
asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64 => {}
986-
_ => self
987-
.sess
988-
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
989-
.emit(),
990-
}
979+
}
980+
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
981+
&& !matches!(
982+
self.sess.asm_arch,
983+
Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)
984+
)
985+
{
986+
self.sess
987+
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
988+
.emit();
991989
}
992990

993991
// Lower operands to HIR, filter_map skips any operands with invalid
@@ -1001,10 +999,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
1001999
Some(match reg {
10021000
InlineAsmRegOrRegClass::Reg(s) => asm::InlineAsmRegOrRegClass::Reg(
10031001
asm::InlineAsmReg::parse(
1004-
asm_arch,
1005-
|feature| {
1006-
self.sess.target_features.contains(&Symbol::intern(feature))
1007-
},
1002+
sess.asm_arch?,
1003+
|feature| sess.target_features.contains(&Symbol::intern(feature)),
10081004
s,
10091005
)
10101006
.map_err(|e| {
@@ -1015,7 +1011,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10151011
),
10161012
InlineAsmRegOrRegClass::RegClass(s) => {
10171013
asm::InlineAsmRegOrRegClass::RegClass(
1018-
asm::InlineAsmRegClass::parse(asm_arch, s)
1014+
asm::InlineAsmRegClass::parse(sess.asm_arch?, s)
10191015
.map_err(|e| {
10201016
let msg = format!(
10211017
"invalid register class `{}`: {}",
@@ -1029,33 +1025,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
10291025
}
10301026
})
10311027
};
1032-
let op = match op {
1033-
InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In {
1034-
reg: lower_reg(*reg)?,
1028+
1029+
// lower_reg is executed last because we need to lower all
1030+
// sub-expressions even if we throw them away later.
1031+
let op = match *op {
1032+
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
10351033
expr: self.lower_expr_mut(expr),
1034+
reg: lower_reg(reg)?,
10361035
},
1037-
InlineAsmOperand::Out { reg, late, expr } => hir::InlineAsmOperand::Out {
1038-
reg: lower_reg(*reg)?,
1039-
late: *late,
1036+
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
1037+
late,
10401038
expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
1039+
reg: lower_reg(reg)?,
10411040
},
1042-
InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut {
1043-
reg: lower_reg(*reg)?,
1044-
late: *late,
1045-
expr: self.lower_expr_mut(expr),
1046-
},
1047-
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
1041+
InlineAsmOperand::InOut { reg, late, ref expr } => {
1042+
hir::InlineAsmOperand::InOut {
1043+
late,
1044+
expr: self.lower_expr_mut(expr),
1045+
reg: lower_reg(reg)?,
1046+
}
1047+
}
1048+
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
10481049
hir::InlineAsmOperand::SplitInOut {
1049-
reg: lower_reg(*reg)?,
1050-
late: *late,
1050+
late,
10511051
in_expr: self.lower_expr_mut(in_expr),
10521052
out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
1053+
reg: lower_reg(reg)?,
10531054
}
10541055
}
1055-
InlineAsmOperand::Const { expr } => {
1056+
InlineAsmOperand::Const { ref expr } => {
10561057
hir::InlineAsmOperand::Const { expr: self.lower_expr_mut(expr) }
10571058
}
1058-
InlineAsmOperand::Sym { expr } => {
1059+
InlineAsmOperand::Sym { ref expr } => {
10591060
hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
10601061
}
10611062
};
@@ -1069,6 +1070,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10691070
}
10701071

10711072
// Validate template modifiers against the register classes for the operands
1073+
let asm_arch = sess.asm_arch.unwrap();
10721074
for p in &asm.template {
10731075
if let InlineAsmTemplatePiece::Placeholder {
10741076
operand_idx,

src/librustc_codegen_ssa/mir/block.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -908,13 +908,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
908908
mir::InlineAsmOperand::SymFn { ref value } => {
909909
let literal = self.monomorphize(&value.literal);
910910
if let ty::FnDef(def_id, substs) = literal.ty.kind {
911-
let instance = ty::Instance::resolve(
911+
let instance = ty::Instance::resolve_for_fn_ptr(
912912
bx.tcx(),
913913
ty::ParamEnv::reveal_all(),
914914
def_id,
915915
substs,
916916
)
917-
.unwrap()
918917
.unwrap();
919918
InlineAsmOperandRef::SymFn { instance }
920919
} else {

src/librustc_error_codes/error_codes/E0055.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ recursion limit (which can be set via the `recursion_limit` attribute).
66
For a somewhat artificial example:
77

88
```compile_fail,E0055
9-
#![recursion_limit="5"]
9+
#![recursion_limit="4"]
1010
1111
struct Foo;
1212

src/librustc_expand/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxHashMap;
1212
use rustc_data_structures::sync::{self, Lrc};
1313
use rustc_errors::{DiagnosticBuilder, ErrorReported};
1414
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
15-
use rustc_session::parse::ParseSess;
15+
use rustc_session::{parse::ParseSess, Limit};
1616
use rustc_span::def_id::DefId;
1717
use rustc_span::edition::Edition;
1818
use rustc_span::hygiene::{AstPass, ExpnData, ExpnId, ExpnKind};
@@ -941,7 +941,7 @@ pub struct ExpansionData {
941941
pub struct ExtCtxt<'a> {
942942
pub parse_sess: &'a ParseSess,
943943
pub ecfg: expand::ExpansionConfig<'a>,
944-
pub reduced_recursion_limit: Option<usize>,
944+
pub reduced_recursion_limit: Option<Limit>,
945945
pub root_path: PathBuf,
946946
pub resolver: &'a mut dyn Resolver,
947947
pub current_expansion: ExpansionData,

src/librustc_expand/expand.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc_parse::validate_attr;
2424
use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
2525
use rustc_session::lint::BuiltinLintDiagnostics;
2626
use rustc_session::parse::{feature_err, ParseSess};
27+
use rustc_session::Limit;
2728
use rustc_span::source_map::respan;
2829
use rustc_span::symbol::{sym, Ident, Symbol};
2930
use rustc_span::{FileName, Span, DUMMY_SP};
@@ -664,7 +665,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
664665
) -> ExpandResult<AstFragment, Invocation> {
665666
let recursion_limit =
666667
self.cx.reduced_recursion_limit.unwrap_or(self.cx.ecfg.recursion_limit);
667-
if self.cx.current_expansion.depth > recursion_limit {
668+
if !recursion_limit.value_within_limit(self.cx.current_expansion.depth) {
668669
if self.cx.reduced_recursion_limit.is_none() {
669670
self.error_recursion_limit_reached();
670671
}
@@ -1784,7 +1785,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
17841785
pub struct ExpansionConfig<'feat> {
17851786
pub crate_name: String,
17861787
pub features: Option<&'feat Features>,
1787-
pub recursion_limit: usize,
1788+
pub recursion_limit: Limit,
17881789
pub trace_mac: bool,
17891790
pub should_test: bool, // If false, strip `#[test]` nodes
17901791
pub keep_macs: bool,
@@ -1795,7 +1796,7 @@ impl<'feat> ExpansionConfig<'feat> {
17951796
ExpansionConfig {
17961797
crate_name,
17971798
features: None,
1798-
recursion_limit: 1024,
1799+
recursion_limit: Limit::new(1024),
17991800
trace_mac: false,
18001801
should_test: false,
18011802
keep_macs: false,

src/librustc_interface/passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
838838

839839
sess.time("MIR_effect_checking", || {
840840
for def_id in tcx.body_owners() {
841-
mir::transform::check_unsafety::check_unsafety(tcx, def_id.to_def_id())
841+
mir::transform::check_unsafety::check_unsafety(tcx, def_id)
842842
}
843843
});
844844

src/librustc_middle/middle/limits.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use crate::bug;
99
use rustc_ast::ast;
1010
use rustc_data_structures::sync::OnceCell;
11-
use rustc_session::Session;
11+
use rustc_session::{Limit, Session};
1212
use rustc_span::symbol::{sym, Symbol};
1313

1414
use std::num::IntErrorKind;
@@ -22,7 +22,7 @@ pub fn update_limits(sess: &Session, krate: &ast::Crate) {
2222
fn update_limit(
2323
sess: &Session,
2424
krate: &ast::Crate,
25-
limit: &OnceCell<usize>,
25+
limit: &OnceCell<Limit>,
2626
name: Symbol,
2727
default: usize,
2828
) {
@@ -34,7 +34,7 @@ fn update_limit(
3434
if let Some(s) = attr.value_str() {
3535
match s.as_str().parse() {
3636
Ok(n) => {
37-
limit.set(n).unwrap();
37+
limit.set(Limit::new(n)).unwrap();
3838
return;
3939
}
4040
Err(e) => {
@@ -62,5 +62,5 @@ fn update_limit(
6262
}
6363
}
6464
}
65-
limit.set(default).unwrap();
65+
limit.set(Limit::new(default)).unwrap();
6666
}

src/librustc_middle/mir/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,8 @@ pub enum TerminatorKind<'tcx> {
10721072
Abort,
10731073

10741074
/// Indicates a normal return. The return place should have
1075-
/// been filled in by now. This should occur at most once.
1075+
/// been filled in before this executes. This can occur multiple times
1076+
/// in different basic blocks.
10761077
Return,
10771078

10781079
/// Indicates a terminator that can never be reached.

src/librustc_middle/query/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,14 @@ rustc_queries! {
386386
storage(ArenaCacheSelector<'tcx>)
387387
}
388388

389-
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error
390-
query unsafe_derive_on_repr_packed(_: DefId) -> () {}
389+
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error.
390+
///
391+
/// Unsafety checking is executed for each method separately, but we only want
392+
/// to emit this error once per derive. As there are some impls with multiple
393+
/// methods, we use a query for deduplication.
394+
query unsafe_derive_on_repr_packed(key: LocalDefId) -> () {
395+
desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) }
396+
}
391397

392398
/// The signature of functions and closures.
393399
query fn_sig(_: DefId) -> ty::PolyFnSig<'tcx> {}

src/librustc_middle/ty/layout.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,9 @@ fn layout_raw<'tcx>(
187187
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
188188
) -> Result<&'tcx Layout, LayoutError<'tcx>> {
189189
ty::tls::with_related_context(tcx, move |icx| {
190-
let rec_limit = tcx.sess.recursion_limit.get().copied().unwrap();
191190
let (param_env, ty) = query.into_parts();
192191

193-
if icx.layout_depth > rec_limit {
192+
if !tcx.sess.recursion_limit().value_within_limit(icx.layout_depth) {
194193
tcx.sess.fatal(&format!("overflow representing the type `{}`", ty));
195194
}
196195

src/librustc_mir/const_eval/machine.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_data_structures::fx::FxHashMap;
1010
use rustc_ast::ast::Mutability;
1111
use rustc_hir::def_id::DefId;
1212
use rustc_middle::mir::AssertMessage;
13+
use rustc_session::Limit;
1314
use rustc_span::symbol::Symbol;
1415

1516
use crate::interpret::{
@@ -109,8 +110,8 @@ pub struct MemoryExtra {
109110
}
110111

111112
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
112-
pub(super) fn new(const_eval_limit: usize) -> Self {
113-
CompileTimeInterpreter { steps_remaining: const_eval_limit, stack: Vec::new() }
113+
pub(super) fn new(const_eval_limit: Limit) -> Self {
114+
CompileTimeInterpreter { steps_remaining: const_eval_limit.0, stack: Vec::new() }
114115
}
115116
}
116117

src/librustc_mir/interpret/eval_context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
651651
M::after_stack_push(self)?;
652652
info!("ENTERING({}) {}", self.frame_idx(), self.frame().instance);
653653

654-
if self.stack().len() > self.tcx.sess.recursion_limit() {
654+
if !self.tcx.sess.recursion_limit().value_within_limit(self.stack().len()) {
655655
throw_exhaust!(StackFrameLimitReached)
656656
} else {
657657
Ok(())

0 commit comments

Comments
 (0)