1
Fork 0

Remove MIR unsafe check

This also remove safety information from MIR.
This commit is contained in:
Matthew Jasper 2024-02-27 11:57:52 +00:00
parent 76cf07d5df
commit a277c901d9
194 changed files with 667 additions and 2238 deletions

View file

@ -13,31 +13,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ast_block: BlockId,
source_info: SourceInfo,
) -> BlockAnd<()> {
let Block { region_scope, span, ref stmts, expr, targeted_by_break, safety_mode } =
let Block { region_scope, span, ref stmts, expr, targeted_by_break, safety_mode: _ } =
self.thir[ast_block];
self.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
if targeted_by_break {
this.in_breakable_scope(None, destination, span, |this| {
Some(this.ast_block_stmts(
destination,
block,
span,
stmts,
expr,
safety_mode,
region_scope,
))
Some(this.ast_block_stmts(destination, block, span, stmts, expr, region_scope))
})
} else {
this.ast_block_stmts(
destination,
block,
span,
stmts,
expr,
safety_mode,
region_scope,
)
this.ast_block_stmts(destination, block, span, stmts, expr, region_scope)
}
})
}
@ -49,7 +33,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
span: Span,
stmts: &[StmtId],
expr: Option<ExprId>,
safety_mode: BlockSafety,
region_scope: Scope,
) -> BlockAnd<()> {
let this = self;
@ -72,13 +55,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// First we build all the statements in the block.
let mut let_scope_stack = Vec::with_capacity(8);
let outer_source_scope = this.source_scope;
let outer_in_scope_unsafe = this.in_scope_unsafe;
// This scope information is kept for breaking out of the parent remainder scope in case
// one let-else pattern matching fails.
// By doing so, we can be sure that even temporaries that receive extended lifetime
// assignments are dropped, too.
let mut last_remainder_scope = region_scope;
this.update_source_scope_for_safety_mode(span, safety_mode);
let source_info = this.source_info(span);
for stmt in stmts {
@ -202,7 +183,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let_scope_stack.push(remainder_scope);
let visibility_scope =
Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
Some(this.new_source_scope(remainder_span, LintLevel::Inherited));
let initializer_span = this.thir[*initializer].span;
let scope = (*init_scope, source_info);
@ -271,7 +252,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let remainder_span = remainder_scope.span(this.tcx, this.region_scope_tree);
let visibility_scope =
Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
Some(this.new_source_scope(remainder_span, LintLevel::Inherited));
// Evaluate the initializer, if present.
if let Some(init) = *initializer {
@ -364,22 +345,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
// Restore the original source scope.
this.source_scope = outer_source_scope;
this.in_scope_unsafe = outer_in_scope_unsafe;
block.unit()
}
/// If we are entering an unsafe block, create a new source scope
fn update_source_scope_for_safety_mode(&mut self, span: Span, safety_mode: BlockSafety) {
debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
let new_unsafety = match safety_mode {
BlockSafety::Safe => return,
BlockSafety::BuiltinUnsafe => Safety::BuiltinUnsafe,
BlockSafety::ExplicitUnsafe(hir_id) => {
self.in_scope_unsafe = Safety::ExplicitUnsafe(hir_id);
Safety::ExplicitUnsafe(hir_id)
}
};
self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(new_unsafety));
}
}

View file

@ -72,10 +72,7 @@ pub(super) fn build_custom_mir<'tcx>(
parent_scope: None,
inlined: None,
inlined_parent_scope: None,
local_data: ClearCrossCrate::Set(SourceScopeLocalData {
lint_root: hir_id,
safety: Safety::Safe,
}),
local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
});
body.injection_phase = Some(parse_attribute(attr));

View file

@ -118,19 +118,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Box { value } => {
let value_ty = this.thir[value].ty;
let tcx = this.tcx;
// `exchange_malloc` is unsafe but box is safe, so need a new scope.
let synth_scope = this.new_source_scope(
expr_span,
LintLevel::Inherited,
Some(Safety::BuiltinUnsafe),
);
let synth_info = SourceInfo { span: expr_span, scope: synth_scope };
let source_info = this.source_info(expr_span);
let size = this.temp(tcx.types.usize, expr_span);
this.cfg.push_assign(
block,
synth_info,
source_info,
size,
Rvalue::NullaryOp(NullOp::SizeOf, value_ty),
);
@ -138,7 +131,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let align = this.temp(tcx.types.usize, expr_span);
this.cfg.push_assign(
block,
synth_info,
source_info,
align,
Rvalue::NullaryOp(NullOp::AlignOf, value_ty),
);
@ -154,7 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let success = this.cfg.start_new_block();
this.cfg.terminate(
block,
synth_info,
source_info,
TerminatorKind::Call {
func: exchange_malloc,
args: vec![

View file

@ -69,7 +69,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// FIXME: Does this need extra logic to handle let-chains?
let source_info = if this.is_let(cond) {
let variable_scope =
this.new_source_scope(then_span, LintLevel::Inherited, None);
this.new_source_scope(then_span, LintLevel::Inherited);
this.source_scope = variable_scope;
SourceInfo { span: then_span, scope: variable_scope }
} else {

View file

@ -732,7 +732,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
&mut |this, name, mode, var, span, ty, user_ty| {
if visibility_scope.is_none() {
visibility_scope =
Some(this.new_source_scope(scope_span, LintLevel::Inherited, None));
Some(this.new_source_scope(scope_span, LintLevel::Inherited));
}
let source_info = SourceInfo { span, scope: this.source_scope };
let visibility_scope = visibility_scope.unwrap();

View file

@ -66,17 +66,10 @@ pub(crate) fn mir_build<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx
// maybe move the check to a MIR pass?
tcx.ensure().check_liveness(def);
if tcx.sess.opts.unstable_opts.thir_unsafeck {
// Don't steal here if THIR unsafeck is being used. Instead
// steal in unsafeck. This is so that pattern inline constants
// can be evaluated as part of building the THIR of the parent
// function without a cycle.
build_mir(&thir.borrow())
} else {
// We ran all queries that depended on THIR at the beginning
// of `mir_build`, so now we can steal it
build_mir(&thir.steal())
}
// Don't steal here, instead steal in unsafeck. This is so that
// pattern inline constants can be evaluated as part of building the
// THIR of the parent function without a cycle.
build_mir(&thir.borrow())
}
};
@ -190,9 +183,6 @@ struct Builder<'a, 'tcx> {
/// `{ STMTS; EXPR1 } + EXPR2`.
block_context: BlockContext,
/// The current unsafe block in scope
in_scope_unsafe: Safety,
/// The vector of all scopes that we have created thus far;
/// we track this for debuginfo later.
source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
@ -470,11 +460,6 @@ fn construct_fn<'tcx>(
.output
.span();
let safety = match fn_sig.unsafety {
hir::Unsafety::Normal => Safety::Safe,
hir::Unsafety::Unsafe => Safety::FnUnsafe,
};
let mut abi = fn_sig.abi;
if let DefKind::Closure = tcx.def_kind(fn_def) {
// HACK(eddyb) Avoid having RustCall on closures,
@ -520,7 +505,6 @@ fn construct_fn<'tcx>(
fn_id,
span_with_body,
arguments.len(),
safety,
return_ty,
return_ty_span,
coroutine,
@ -590,18 +574,8 @@ fn construct_const<'a, 'tcx>(
};
let infcx = tcx.infer_ctxt().build();
let mut builder = Builder::new(
thir,
infcx,
def,
hir_id,
span,
0,
Safety::Safe,
const_ty,
const_ty_span,
None,
);
let mut builder =
Builder::new(thir, infcx, def, hir_id, span, 0, const_ty, const_ty_span, None);
let mut block = START_BLOCK;
unpack!(block = builder.expr_into_dest(Place::return_place(), block, expr));
@ -723,10 +697,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
parent_scope: None,
inlined: None,
inlined_parent_scope: None,
local_data: ClearCrossCrate::Set(SourceScopeLocalData {
lint_root: hir_id,
safety: Safety::Safe,
}),
local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
});
cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
@ -753,7 +724,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
hir_id: hir::HirId,
span: Span,
arg_count: usize,
safety: Safety,
return_ty: Ty<'tcx>,
return_span: Span,
coroutine: Option<Box<CoroutineInfo<'tcx>>>,
@ -795,7 +765,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
guard_context: vec![],
fixed_temps: Default::default(),
fixed_temps_scope: None,
in_scope_unsafe: safety,
local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1),
canonical_user_type_annotations: IndexVec::new(),
upvars: CaptureMap::new(),
@ -807,10 +776,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
assert_eq!(
builder.new_source_scope(span, lint_level, Some(safety)),
OUTERMOST_SOURCE_SCOPE
);
assert_eq!(builder.new_source_scope(span, lint_level), OUTERMOST_SOURCE_SCOPE);
builder.source_scopes[OUTERMOST_SOURCE_SCOPE].parent_scope = None;
builder
@ -1024,7 +990,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.as_ref()
.assert_crate_local()
.lint_root;
self.maybe_new_source_scope(pattern_span, None, arg_hir_id, parent_id);
self.maybe_new_source_scope(pattern_span, arg_hir_id, parent_id);
}
fn get_unit_temp(&mut self) -> Place<'tcx> {

View file

@ -578,7 +578,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if let LintLevel::Explicit(current_hir_id) = lint_level {
let parent_id =
self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root;
self.maybe_new_source_scope(region_scope.1.span, None, current_hir_id, parent_id);
self.maybe_new_source_scope(region_scope.1.span, current_hir_id, parent_id);
}
self.push_scope(region_scope);
let mut block;
@ -767,7 +767,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub(crate) fn maybe_new_source_scope(
&mut self,
span: Span,
safety: Option<Safety>,
current_id: HirId,
parent_id: HirId,
) {
@ -797,7 +796,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if current_root != parent_root {
let lint_level = LintLevel::Explicit(current_root);
self.source_scope = self.new_source_scope(span, lint_level, safety);
self.source_scope = self.new_source_scope(span, lint_level);
}
}
@ -846,18 +845,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
/// Creates a new source scope, nested in the current one.
pub(crate) fn new_source_scope(
&mut self,
span: Span,
lint_level: LintLevel,
safety: Option<Safety>,
) -> SourceScope {
pub(crate) fn new_source_scope(&mut self, span: Span, lint_level: LintLevel) -> SourceScope {
let parent = self.source_scope;
debug!(
"new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}",
"new_source_scope({:?}, {:?}) - parent({:?})={:?}",
span,
lint_level,
safety,
parent,
self.source_scopes.get(parent)
);
@ -867,9 +860,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} else {
self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root
},
safety: safety.unwrap_or_else(|| {
self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety
}),
};
self.source_scopes.push(SourceScopeData {
span,

View file

@ -909,11 +909,6 @@ impl UnsafeOpKind {
}
pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
// THIR unsafeck can be disabled with `-Z thir-unsafeck=off`
if !tcx.sess.opts.unstable_opts.thir_unsafeck {
return;
}
// Closures and inline consts are handled by their owner, if it has a body
// Also, don't safety check custom MIR
if tcx.is_typeck_child(def.to_def_id()) || tcx.has_attr(def, sym::custom_mir) {