Skip to content

Commit 04567c3

Browse files
committed
Delay check for both freeze and drop
1 parent d42a3c6 commit 04567c3

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

compiler/rustc_middle/src/ty/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3300,7 +3300,8 @@ pub struct DeducedParamAttrs {
33003300
/// The parameter is marked immutable in the function and contains no `UnsafeCell` (i.e. its
33013301
/// type is freeze).
33023302
pub read_only: bool,
3303-
pub read_only_when_freeze: bool,
3303+
pub requires_freeze: bool,
3304+
pub requires_nop_drop: bool,
33043305
}
33053306

33063307
pub fn provide(providers: &mut Providers) {

compiler/rustc_mir_transform/src/deduce_param_attrs.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ struct DeduceReadOnly {
2222
/// 1). The bit is true if the argument may have been mutated or false if we know it hasn't
2323
/// been up to the point we're at.
2424
read_only: DenseBitSet<usize>,
25-
read_only_when_freeze: DenseBitSet<usize>,
25+
requires_freeze: DenseBitSet<usize>,
26+
requires_nop_drop: DenseBitSet<usize>,
2627
}
2728

2829
impl DeduceReadOnly {
2930
/// Returns a new DeduceReadOnly instance.
3031
fn new(arg_count: usize) -> Self {
3132
Self {
3233
read_only: DenseBitSet::new_filled(arg_count),
33-
read_only_when_freeze: DenseBitSet::new_filled(arg_count),
34+
requires_freeze: DenseBitSet::new_empty(arg_count),
35+
requires_nop_drop: DenseBitSet::new_empty(arg_count),
3436
}
3537
}
3638

@@ -54,16 +56,14 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
5456
PlaceContext::MutatingUse(..) => {
5557
// This is a mutation, so mark it as such.
5658
self.read_only.remove(arg_index);
57-
self.read_only_when_freeze.remove(arg_index);
5859
}
5960
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) => {
6061
// Whether mutating though a `&raw const` is allowed is still undecided, so we
6162
// disable any sketchy `readonly` optimizations for now.
6263
self.read_only.remove(arg_index);
63-
self.read_only_when_freeze.remove(arg_index);
6464
}
6565
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) => {
66-
self.read_only.remove(arg_index);
66+
self.requires_freeze.insert(arg_index);
6767
}
6868
PlaceContext::NonMutatingUse(..) | PlaceContext::NonUse(..) => {}
6969
};
@@ -99,11 +99,18 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
9999
}
100100
if let Some(arg_index) = self.arg_index(place.local) {
101101
self.read_only.remove(arg_index);
102-
self.read_only_when_freeze.remove(arg_index);
103102
}
104103
}
105104
}
106105
};
106+
if let TerminatorKind::Drop { place, .. } = terminator.kind {
107+
if let Some(local) = place.as_local()
108+
&& let Some(arg_index) = self.arg_index(local)
109+
{
110+
self.requires_nop_drop.insert(arg_index);
111+
return;
112+
}
113+
}
107114

108115
self.super_terminator(terminator, location);
109116
}
@@ -173,11 +180,14 @@ pub(super) fn deduced_param_attrs<'tcx>(
173180

174181
// Set the `readonly` attribute for every argument that we concluded is immutable and that
175182
// contains no UnsafeCells.
176-
let mut deduced_param_attrs =
177-
tcx.arena.alloc_from_iter((0..body.arg_count).map(|arg_index| DeducedParamAttrs {
178-
read_only: deduce.read_only.contains(arg_index),
179-
read_only_when_freeze: deduce.read_only_when_freeze.contains(arg_index),
180-
}));
183+
let mut deduced_param_attrs = tcx.arena.alloc_from_iter((0..body.arg_count).map(|arg_index| {
184+
let read_only = deduce.read_only.contains(arg_index);
185+
DeducedParamAttrs {
186+
read_only,
187+
requires_freeze: read_only && deduce.requires_freeze.contains(arg_index),
188+
requires_nop_drop: read_only && deduce.requires_nop_drop.contains(arg_index),
189+
}
190+
}));
181191

182192
// Trailing parameters past the size of the `deduced_param_attrs` array are assumed to have the
183193
// default set of attributes, so we don't have to store them explicitly. Pop them off to save a

compiler/rustc_ty_utils/src/abi.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,10 @@ fn fn_abi_adjust_for_abi<'tcx>(
713713
// bounds.
714714
if let Some(deduced_param_attrs) = deduced_param_attrs.get(arg_idx) {
715715
if deduced_param_attrs.read_only
716-
|| (deduced_param_attrs.read_only_when_freeze
717-
&& arg.layout.ty.is_freeze(tcx, cx.typing_env))
716+
&& (!deduced_param_attrs.requires_freeze
717+
|| arg.layout.ty.is_freeze(tcx, cx.typing_env))
718+
&& (!deduced_param_attrs.requires_nop_drop
719+
|| !arg.layout.ty.needs_drop(tcx, cx.typing_env))
718720
{
719721
attrs.regular.insert(ArgAttribute::ReadOnly);
720722
debug!("added deduced read-only attribute");

0 commit comments

Comments
 (0)