Skip to content

Commit 612af94

Browse files
committed
Don't panic on layout errors
1 parent a44a72e commit 612af94

File tree

2 files changed

+62
-57
lines changed

2 files changed

+62
-57
lines changed

src/librustc_mir/const_eval.rs

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,12 @@ pub fn const_eval_provider<'tcx>(
620620
ty::FnDef(_, substs) => substs,
621621
_ => bug!("intrinsic with type {:?}", ty),
622622
};
623-
return Ok(eval_nullary_intrinsic(tcx, key.param_env, def_id, substs));
623+
return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs)
624+
.map_err(|error| {
625+
let span = tcx.def_span(def_id);
626+
let error = ConstEvalErr { error: error.kind, stacktrace: vec![], span };
627+
error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic")
628+
})
624629
}
625630

626631
tcx.const_eval_raw(key).and_then(|val| {
@@ -691,63 +696,63 @@ pub fn const_eval_raw_provider<'tcx>(
691696
})
692697
}).map_err(|error| {
693698
let err = error_to_const_error(&ecx, error);
694-
// errors in statics are always emitted as fatal errors
695-
if tcx.is_static(def_id) {
696-
// Ensure that if the above error was either `TooGeneric` or `Reported`
697-
// an error must be reported.
699+
// errors in statics are always emitted as fatal errors
700+
if tcx.is_static(def_id) {
701+
// Ensure that if the above error was either `TooGeneric` or `Reported`
702+
// an error must be reported.
698703
let v = err.report_as_error(ecx.tcx, "could not evaluate static initializer");
699-
tcx.sess.delay_span_bug(
700-
err.span,
701-
&format!("static eval failure did not emit an error: {:#?}", v)
702-
);
703-
v
704-
} else if def_id.is_local() {
705-
// constant defined in this crate, we can figure out a lint level!
706-
match tcx.def_kind(def_id) {
707-
// constants never produce a hard error at the definition site. Anything else is
708-
// a backwards compatibility hazard (and will break old versions of winapi for sure)
709-
//
710-
// note that validation may still cause a hard error on this very same constant,
711-
// because any code that existed before validation could not have failed validation
712-
// thus preventing such a hard error from being a backwards compatibility hazard
713-
Some(DefKind::Const) | Some(DefKind::AssocConst) => {
714-
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
704+
tcx.sess.delay_span_bug(
705+
err.span,
706+
&format!("static eval failure did not emit an error: {:#?}", v)
707+
);
708+
v
709+
} else if def_id.is_local() {
710+
// constant defined in this crate, we can figure out a lint level!
711+
match tcx.def_kind(def_id) {
712+
// constants never produce a hard error at the definition site. Anything else is
713+
// a backwards compatibility hazard (and will break old versions of winapi for sure)
714+
//
715+
// note that validation may still cause a hard error on this very same constant,
716+
// because any code that existed before validation could not have failed validation
717+
// thus preventing such a hard error from being a backwards compatibility hazard
718+
Some(DefKind::Const) | Some(DefKind::AssocConst) => {
719+
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
720+
err.report_as_lint(
721+
tcx.at(tcx.def_span(def_id)),
722+
"any use of this value will cause an error",
723+
hir_id,
724+
Some(err.span),
725+
)
726+
},
727+
// promoting runtime code is only allowed to error if it references broken constants
728+
// any other kind of error will be reported to the user as a deny-by-default lint
729+
_ => if let Some(p) = cid.promoted {
730+
let span = tcx.promoted_mir(def_id)[p].span;
731+
if let err_inval!(ReferencedConstant) = err.error {
732+
err.report_as_error(
733+
tcx.at(span),
734+
"evaluation of constant expression failed",
735+
)
736+
} else {
715737
err.report_as_lint(
716-
tcx.at(tcx.def_span(def_id)),
717-
"any use of this value will cause an error",
718-
hir_id,
738+
tcx.at(span),
739+
"reaching this expression at runtime will panic or abort",
740+
tcx.hir().as_local_hir_id(def_id).unwrap(),
719741
Some(err.span),
720742
)
721-
},
722-
// promoting runtime code is only allowed to error if it references broken constants
723-
// any other kind of error will be reported to the user as a deny-by-default lint
724-
_ => if let Some(p) = cid.promoted {
725-
let span = tcx.promoted_mir(def_id)[p].span;
726-
if let err_inval!(ReferencedConstant) = err.error {
727-
err.report_as_error(
728-
tcx.at(span),
729-
"evaluation of constant expression failed",
730-
)
731-
} else {
732-
err.report_as_lint(
733-
tcx.at(span),
734-
"reaching this expression at runtime will panic or abort",
735-
tcx.hir().as_local_hir_id(def_id).unwrap(),
736-
Some(err.span),
737-
)
738-
}
739-
// anything else (array lengths, enum initializers, constant patterns) are reported
740-
// as hard errors
741-
} else {
742-
err.report_as_error(
743+
}
744+
// anything else (array lengths, enum initializers, constant patterns) are reported
745+
// as hard errors
746+
} else {
747+
err.report_as_error(
743748
ecx.tcx,
744-
"evaluation of constant value failed",
745-
)
746-
},
747-
}
748-
} else {
749-
// use of broken constant from other crate
750-
err.report_as_error(ecx.tcx, "could not evaluate constant")
749+
"evaluation of constant value failed",
750+
)
751+
},
751752
}
753+
} else {
754+
// use of broken constant from other crate
755+
err.report_as_error(ecx.tcx, "could not evaluate constant")
756+
}
752757
})
753758
}

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ crate fn eval_nullary_intrinsic<'tcx>(
4545
param_env: ty::ParamEnv<'tcx>,
4646
def_id: DefId,
4747
substs: SubstsRef<'tcx>,
48-
) -> &'tcx ty::Const<'tcx> {
48+
) -> InterpResult<'tcx, &'tcx ty::Const<'tcx>> {
4949
let tp_ty = substs.type_at(0);
5050
let name = &*tcx.item_name(def_id).as_str();
51-
match name {
51+
Ok(match name {
5252
"type_name" => {
5353
let alloc = type_name::alloc_type_name(tcx, tp_ty);
5454
tcx.mk_const(ty::Const {
@@ -64,7 +64,7 @@ crate fn eval_nullary_intrinsic<'tcx>(
6464
"size_of" |
6565
"min_align_of" |
6666
"pref_align_of" => {
67-
let layout = tcx.layout_of(param_env.and(tp_ty)).unwrap();
67+
let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
6868
let n = match name {
6969
"pref_align_of" => layout.align.pref.bytes(),
7070
"min_align_of" => layout.align.abi.bytes(),
@@ -79,7 +79,7 @@ crate fn eval_nullary_intrinsic<'tcx>(
7979
param_env.and(tcx.types.u64),
8080
),
8181
other => bug!("`{}` is not a zero arg intrinsic", other),
82-
}
82+
})
8383
}
8484

8585
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

0 commit comments

Comments
 (0)