Skip to content

Commit b7195e3

Browse files
pnkfelixcelinval
authored andcommitted
Contracts core intrinsics.
These are hooks to: 1. control whether contract checks are run 2. allow 3rd party tools to intercept and reintepret the results of running contracts.
1 parent 336209e commit b7195e3

File tree

30 files changed

+182
-6
lines changed

30 files changed

+182
-6
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16311631
ConstraintCategory::SizedBound,
16321632
);
16331633
}
1634+
&Rvalue::NullaryOp(NullOp::ContractChecks, _) => {}
16341635
&Rvalue::NullaryOp(NullOp::UbChecks, _) => {}
16351636

16361637
Rvalue::ShallowInitBox(operand, ty) => {

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,15 @@ fn codegen_stmt<'tcx>(
858858
lval.write_cvalue(fx, val);
859859
return;
860860
}
861+
NullOp::ContractChecks => {
862+
let val = fx.tcx.sess.contract_checks();
863+
let val = CValue::by_val(
864+
fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()),
865+
fx.layout_of(fx.tcx.types.bool),
866+
);
867+
lval.write_cvalue(fx, val);
868+
return;
869+
}
861870
};
862871
let val = CValue::by_val(
863872
fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(val).unwrap()),

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
707707
let val = bx.tcx().sess.ub_checks();
708708
bx.cx().const_bool(val)
709709
}
710+
mir::NullOp::ContractChecks => {
711+
let val = bx.tcx().sess.contract_checks();
712+
bx.cx().const_bool(val)
713+
}
710714
};
711715
let tcx = self.cx.tcx();
712716
OperandRef {

compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
567567
Rvalue::Cast(_, _, _) => {}
568568

569569
Rvalue::NullaryOp(
570-
NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks,
570+
NullOp::SizeOf
571+
| NullOp::AlignOf
572+
| NullOp::OffsetOf(_)
573+
| NullOp::UbChecks
574+
| NullOp::ContractChecks,
571575
_,
572576
) => {}
573577
Rvalue::ShallowInitBox(_, _) => {}

compiler/rustc_const_eval/src/interpret/machine.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ pub trait Machine<'tcx>: Sized {
287287
/// Determines the result of a `NullaryOp::UbChecks` invocation.
288288
fn ub_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
289289

290+
/// Determines the result of a `NullaryOp::ContractChecks` invocation.
291+
fn contract_checks(_ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool>;
292+
290293
/// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
291294
/// You can use this to detect long or endlessly running programs.
292295
#[inline]
@@ -673,6 +676,13 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
673676
interp_ok(true)
674677
}
675678

679+
#[inline(always)]
680+
fn contract_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> {
681+
// We can't look at `tcx.sess` here as that can differ across crates, which can lead to
682+
// unsound differences in evaluating the same constant at different instantiation sites.
683+
interp_ok(true)
684+
}
685+
676686
#[inline(always)]
677687
fn adjust_global_allocation<'b>(
678688
_ecx: &InterpCx<$tcx, Self>,

compiler/rustc_const_eval/src/interpret/operator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
537537
ImmTy::from_uint(val, usize_layout())
538538
}
539539
UbChecks => ImmTy::from_bool(M::ub_checks(self)?, *self.tcx),
540+
ContractChecks => ImmTy::from_bool(M::contract_checks(self)?, *self.tcx),
540541
})
541542
}
542543
}

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const GATED_CFGS: &[GatedCfg] = &[
1919
// (name in cfg, feature, function to check if the feature is enabled)
2020
(sym::overflow_checks, sym::cfg_overflow_checks, Features::cfg_overflow_checks),
2121
(sym::ub_checks, sym::cfg_ub_checks, Features::cfg_ub_checks),
22+
(sym::contract_checks, sym::cfg_contract_checks, Features::cfg_contract_checks),
2223
(sym::target_thread_local, sym::cfg_target_thread_local, Features::cfg_target_thread_local),
2324
(
2425
sym::target_has_atomic_equal_alignment,

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ declare_features! (
403403
(unstable, c_variadic, "1.34.0", Some(44930)),
404404
/// Allows the use of `#[cfg(<true/false>)]`.
405405
(unstable, cfg_boolean_literals, "1.83.0", Some(131204)),
406+
/// Allows the use of `#[cfg(contract_checks)` to check if contract checks are enabled.
407+
(unstable, cfg_contract_checks, "CURRENT_RUSTC_VERSION", Some(133866)),
406408
/// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
407409
(unstable, cfg_overflow_checks, "1.71.0", Some(111466)),
408410
/// Provides the relocation model information as cfg entry

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
132132
| sym::aggregate_raw_ptr
133133
| sym::ptr_metadata
134134
| sym::ub_checks
135+
| sym::contract_checks
136+
| sym::contract_check_requires
137+
| sym::contract_check_ensures
135138
| sym::fadd_algebraic
136139
| sym::fsub_algebraic
137140
| sym::fmul_algebraic
@@ -218,6 +221,18 @@ pub fn check_intrinsic_type(
218221
}
219222
};
220223
(n_tps, 0, 0, inputs, output, hir::Safety::Unsafe)
224+
} else if intrinsic_name == sym::contract_check_ensures {
225+
// contract_check_ensures::<'a, Ret, C>(&'a Ret, C) -> bool
226+
// where C: impl Fn(&'a Ret) -> bool,
227+
//
228+
// so: two type params, one lifetime param, 0 const params, two inputs, returns boolean
229+
230+
let p = generics.param_at(0, tcx);
231+
let r = ty::Region::new_early_param(tcx, p.to_early_bound_region_data());
232+
let ref_ret = Ty::new_imm_ref(tcx, r, param(1));
233+
// let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon };
234+
// let ref_ret = Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
235+
(2, 1, 0, vec![ref_ret, param(2)], tcx.types.bool, hir::Safety::Safe)
221236
} else {
222237
let safety = intrinsic_operation_unsafety(tcx, intrinsic_id);
223238
let (n_tps, n_cts, inputs, output) = match intrinsic_name {
@@ -609,6 +624,11 @@ pub fn check_intrinsic_type(
609624

610625
sym::box_new => (1, 0, vec![param(0)], Ty::new_box(tcx, param(0))),
611626

627+
// contract_checks() -> bool
628+
sym::contract_checks => (0, 0, Vec::new(), tcx.types.bool),
629+
// contract_check_requires::<C>(C) -> bool, where C: impl Fn() -> bool
630+
sym::contract_check_requires => (1, 0, vec![param(0)], tcx.types.bool),
631+
612632
sym::simd_eq
613633
| sym::simd_ne
614634
| sym::simd_lt

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
10811081
NullOp::AlignOf => write!(fmt, "AlignOf({t})"),
10821082
NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"),
10831083
NullOp::UbChecks => write!(fmt, "UbChecks()"),
1084+
NullOp::ContractChecks => write!(fmt, "ContractChecks()"),
10841085
}
10851086
}
10861087
ThreadLocalRef(did) => ty::tls::with(|tcx| {

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,9 @@ pub enum NullOp<'tcx> {
15131513
/// Returns whether we should perform some UB-checking at runtime.
15141514
/// See the `ub_checks` intrinsic docs for details.
15151515
UbChecks,
1516+
/// Returns whether we should perform contract-checking at runtime.
1517+
/// See the `contract_checks` intrinsic docs for details.
1518+
ContractChecks,
15161519
}
15171520

15181521
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]

compiler/rustc_middle/src/mir/tcx.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ impl<'tcx> Rvalue<'tcx> {
224224
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
225225
tcx.types.usize
226226
}
227-
Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool,
227+
Rvalue::NullaryOp(NullOp::ContractChecks, _)
228+
| Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool,
228229
Rvalue::Aggregate(ref ak, ref ops) => match **ak {
229230
AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64),
230231
AggregateKind::Tuple => {

compiler/rustc_mir_dataflow/src/move_paths/builder.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,11 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
414414
| Rvalue::RawPtr(..)
415415
| Rvalue::Discriminant(..)
416416
| Rvalue::NullaryOp(
417-
NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..) | NullOp::UbChecks,
417+
NullOp::SizeOf
418+
| NullOp::AlignOf
419+
| NullOp::OffsetOf(..)
420+
| NullOp::UbChecks
421+
| NullOp::ContractChecks,
418422
_,
419423
) => {}
420424
}

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
527527
.offset_of_subfield(self.typing_env(), layout, fields.iter())
528528
.bytes(),
529529
NullOp::UbChecks => return None,
530+
NullOp::ContractChecks => return None,
530531
};
531532
let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap();
532533
let imm = ImmTy::from_uint(val, usize_layout);

compiler/rustc_mir_transform/src/known_panics_lint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
611611
.offset_of_subfield(self.typing_env, op_layout, fields.iter())
612612
.bytes(),
613613
NullOp::UbChecks => return None,
614+
NullOp::ContractChecks => return None,
614615
};
615616
ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into()
616617
}

compiler/rustc_mir_transform/src/lower_intrinsics.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
3434
});
3535
terminator.kind = TerminatorKind::Goto { target };
3636
}
37+
sym::contract_checks => {
38+
let target = target.unwrap();
39+
block.statements.push(Statement {
40+
source_info: terminator.source_info,
41+
kind: StatementKind::Assign(Box::new((
42+
*destination,
43+
Rvalue::NullaryOp(NullOp::ContractChecks, tcx.types.bool),
44+
))),
45+
});
46+
terminator.kind = TerminatorKind::Goto { target };
47+
}
3748
sym::forget => {
3849
let target = target.unwrap();
3950
block.statements.push(Statement {

compiler/rustc_mir_transform/src/promote_consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ impl<'tcx> Validator<'_, 'tcx> {
448448
NullOp::AlignOf => {}
449449
NullOp::OffsetOf(_) => {}
450450
NullOp::UbChecks => {}
451+
NullOp::ContractChecks => {}
451452
},
452453

453454
Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
13391339
Rvalue::Repeat(_, _)
13401340
| Rvalue::ThreadLocalRef(_)
13411341
| Rvalue::RawPtr(_, _)
1342-
| Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks, _)
1342+
| Rvalue::NullaryOp(
1343+
NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks | NullOp::ContractChecks,
1344+
_,
1345+
)
13431346
| Rvalue::Discriminant(_) => {}
13441347
}
13451348
self.super_rvalue(rvalue, location);

compiler/rustc_session/src/config/cfg.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
119119
(sym::overflow_checks, None) => disallow(cfg, "-C overflow-checks"),
120120
(sym::debug_assertions, None) => disallow(cfg, "-C debug-assertions"),
121121
(sym::ub_checks, None) => disallow(cfg, "-Z ub-checks"),
122+
(sym::contract_checks, None) => disallow(cfg, "-Z contract-checks"),
122123
(sym::sanitize, None | Some(_)) => disallow(cfg, "-Z sanitizer"),
123124
(
124125
sym::sanitizer_cfi_generalize_pointers | sym::sanitizer_cfi_normalize_integers,
@@ -300,6 +301,11 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
300301
if sess.is_nightly_build() && sess.opts.unstable_opts.emscripten_wasm_eh {
301302
ins_none!(sym::emscripten_wasm_eh);
302303
}
304+
305+
if sess.contract_checks() {
306+
ins_none!(sym::contract_checks);
307+
}
308+
303309
ret
304310
}
305311

@@ -464,6 +470,7 @@ impl CheckCfg {
464470
ins!(sym::target_thread_local, no_values);
465471

466472
ins!(sym::ub_checks, no_values);
473+
ins!(sym::contract_checks, no_values);
467474

468475
ins!(sym::unix, no_values);
469476
ins!(sym::windows, no_values);

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,8 @@ options! {
17371737
"the backend to use"),
17381738
combine_cgu: bool = (false, parse_bool, [TRACKED],
17391739
"combine CGUs into a single one"),
1740+
contract_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
1741+
"emit runtime checks for contract pre- and post-conditions (default: no)"),
17401742
coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED],
17411743
"control details of coverage instrumentation"),
17421744
crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],

compiler/rustc_session/src/session.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,10 @@ impl Session {
709709
self.opts.unstable_opts.ub_checks.unwrap_or(self.opts.debug_assertions)
710710
}
711711

712+
pub fn contract_checks(&self) -> bool {
713+
self.opts.unstable_opts.contract_checks.unwrap_or(false)
714+
}
715+
712716
pub fn relocation_model(&self) -> RelocModel {
713717
self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model)
714718
}

compiler/rustc_smir/src/rustc_smir/convert/mir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
277277
indices.iter().map(|idx| idx.stable(tables)).collect(),
278278
),
279279
UbChecks => stable_mir::mir::NullOp::UbChecks,
280+
ContractChecks => stable_mir::mir::NullOp::ContractChecks,
280281
}
281282
}
282283
}

compiler/rustc_span/src/symbol.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ symbols! {
569569
cfg_attr_multi,
570570
cfg_autodiff_fallback,
571571
cfg_boolean_literals,
572+
cfg_contract_checks,
572573
cfg_doctest,
573574
cfg_emscripten_wasm_eh,
574575
cfg_eval,
@@ -678,6 +679,9 @@ symbols! {
678679
const_ty_placeholder: "<const_ty>",
679680
constant,
680681
constructor,
682+
contract_check_ensures,
683+
contract_check_requires,
684+
contract_checks,
681685
convert_identity,
682686
copy,
683687
copy_closures,

compiler/stable_mir/src/mir/body.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,8 @@ impl Rvalue {
606606
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
607607
Ok(Ty::usize_ty())
608608
}
609-
Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()),
609+
Rvalue::NullaryOp(NullOp::ContractChecks, _)
610+
| Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()),
610611
Rvalue::Aggregate(ak, ops) => match *ak {
611612
AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64),
612613
AggregateKind::Tuple => Ok(Ty::new_tuple(
@@ -987,6 +988,8 @@ pub enum NullOp {
987988
OffsetOf(Vec<(VariantIdx, FieldIdx)>),
988989
/// cfg!(ub_checks), but at codegen time
989990
UbChecks,
991+
/// cfg!(contract_checks), but at codegen time
992+
ContractChecks,
990993
}
991994

992995
impl Operand {

library/core/src/intrinsics/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4035,6 +4035,38 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
40354035
// Runtime NOP
40364036
}
40374037

4038+
/// Returns whether we should perform contract-checking at runtime.
4039+
///
4040+
/// This is meant to be similar to the ub_checks intrinsic, in terms
4041+
/// of not prematurely commiting at compile-time to whether contract
4042+
/// checking is turned on, so that we can specify contracts in libstd
4043+
/// and let an end user opt into turning them on.
4044+
#[cfg(not(bootstrap))]
4045+
#[rustc_const_unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
4046+
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
4047+
#[inline(always)]
4048+
#[rustc_intrinsic]
4049+
pub const fn contract_checks() -> bool {
4050+
// FIXME: should this be `false` or `cfg!(contract_checks)`?
4051+
4052+
// cfg!(contract_checks)
4053+
false
4054+
}
4055+
4056+
#[cfg(not(bootstrap))]
4057+
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
4058+
#[rustc_intrinsic]
4059+
pub fn contract_check_requires<C: FnOnce() -> bool>(c: C) -> bool {
4060+
c()
4061+
}
4062+
4063+
#[cfg(not(bootstrap))]
4064+
#[unstable(feature = "rustc_contracts", issue = "none" /* compiler-team#759 */)]
4065+
#[rustc_intrinsic]
4066+
pub fn contract_check_ensures<'a, Ret, C: FnOnce(&'a Ret) -> bool>(ret: &'a Ret, c: C) -> bool {
4067+
c(ret)
4068+
}
4069+
40384070
/// The intrinsic will return the size stored in that vtable.
40394071
///
40404072
/// # Safety

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ fn check_rvalue<'tcx>(
177177
))
178178
}
179179
},
180-
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks, _)
180+
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks, _)
181181
| Rvalue::ShallowInitBox(_, _) => Ok(()),
182182
Rvalue::UnaryOp(_, operand) => {
183183
let ty = operand.ty(body, tcx);

src/tools/miri/src/machine.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
11431143
interp_ok(ecx.tcx.sess.ub_checks())
11441144
}
11451145

1146+
fn contract_checks(ecx: &InterpCx<'tcx, Self>) -> InterpResult<'tcx, bool> {
1147+
interp_ok(ecx.tcx.sess.contract_checks())
1148+
}
1149+
11461150
fn thread_local_static_pointer(
11471151
ecx: &mut MiriInterpCx<'tcx>,
11481152
def_id: DefId,

0 commit comments

Comments
 (0)