Skip to content

Commit 5ffccc4

Browse files
authored
Rollup merge of #78742 - vn-ki:fix-issue-78655, r=oli-obk
make intern_const_alloc_recursive return error fix #78655 r? ``@oli-obk``
2 parents 171d29c + a15ee4d commit 5ffccc4

File tree

11 files changed

+66
-26
lines changed

11 files changed

+66
-26
lines changed

compiler/rustc_middle/src/mir/interpret/error.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ impl From<ErrorHandled> for InterpErrorInfo<'_> {
8181
}
8282
}
8383

84+
impl From<ErrorReported> for InterpErrorInfo<'_> {
85+
fn from(err: ErrorReported) -> Self {
86+
InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into()
87+
}
88+
}
89+
8490
impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
8591
fn from(kind: InterpError<'tcx>) -> Self {
8692
let capture_backtrace = tls::with_opt(|tcx| {
@@ -115,8 +121,8 @@ pub enum InvalidProgramInfo<'tcx> {
115121
/// Cannot compute this constant because it depends on another one
116122
/// which already produced an error.
117123
ReferencedConstant,
118-
/// Abort in case type errors are reached.
119-
TypeckError(ErrorReported),
124+
/// Abort in case errors are already reported.
125+
AlreadyReported(ErrorReported),
120126
/// An error occurred during layout computation.
121127
Layout(layout::LayoutError<'tcx>),
122128
/// An invalid transmute happened.
@@ -129,7 +135,7 @@ impl fmt::Display for InvalidProgramInfo<'_> {
129135
match self {
130136
TooGeneric => write!(f, "encountered overly generic constant"),
131137
ReferencedConstant => write!(f, "referenced constant has errors"),
132-
TypeckError(ErrorReported) => {
138+
AlreadyReported(ErrorReported) => {
133139
write!(f, "encountered constants with type errors, stopping evaluation")
134140
}
135141
Layout(ref err) => write!(f, "{}", err),

compiler/rustc_mir/src/const_eval/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
141141
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
142142
return ErrorHandled::TooGeneric;
143143
}
144-
err_inval!(TypeckError(error_reported)) => {
144+
err_inval!(AlreadyReported(error_reported)) => {
145145
return ErrorHandled::Reported(error_reported);
146146
}
147147
// We must *always* hard error on these, even if the caller wants just a lint.

compiler/rustc_mir/src/const_eval/eval_queries.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
6767
None => InternKind::Constant,
6868
}
6969
};
70-
intern_const_alloc_recursive(ecx, intern_kind, ret);
70+
intern_const_alloc_recursive(ecx, intern_kind, ret)?;
7171

7272
debug!("eval_body_using_ecx done: {:?}", *ret);
7373
Ok(ret)

compiler/rustc_mir/src/const_eval/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ pub(crate) fn const_caller_location(
2929
let mut ecx = mk_eval_cx(tcx, DUMMY_SP, ty::ParamEnv::reveal_all(), false);
3030

3131
let loc_place = ecx.alloc_caller_location(file, line, col);
32-
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place);
32+
if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place).is_err() {
33+
bug!("intern_const_alloc_recursive should not error in this case")
34+
}
3335
ConstValue::Scalar(loc_place.ptr)
3436
}
3537

compiler/rustc_mir/src/interpret/eval_context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
469469
if let Some(def) = def.as_local() {
470470
if self.tcx.has_typeck_results(def.did) {
471471
if let Some(error_reported) = self.tcx.typeck_opt_const_arg(def).tainted_by_errors {
472-
throw_inval!(TypeckError(error_reported))
472+
throw_inval!(AlreadyReported(error_reported))
473473
}
474474
}
475475
}
@@ -525,8 +525,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
525525
Ok(Some(instance)) => Ok(instance),
526526
Ok(None) => throw_inval!(TooGeneric),
527527

528-
// FIXME(eddyb) this could be a bit more specific than `TypeckError`.
529-
Err(error_reported) => throw_inval!(TypeckError(error_reported)),
528+
// FIXME(eddyb) this could be a bit more specific than `AlreadyReported`.
529+
Err(error_reported) => throw_inval!(AlreadyReported(error_reported)),
530530
}
531531
}
532532

compiler/rustc_mir/src/interpret/intern.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
use super::validity::RefTracking;
1818
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
19+
use rustc_errors::ErrorReported;
1920
use rustc_hir as hir;
2021
use rustc_middle::mir::interpret::InterpResult;
2122
use rustc_middle::ty::{self, layout::TyAndLayout, Ty};
@@ -285,11 +286,13 @@ pub enum InternKind {
285286
/// tracks where in the value we are and thus can show much better error messages.
286287
/// Any errors here would anyway be turned into `const_err` lints, whereas validation failures
287288
/// are hard errors.
289+
#[tracing::instrument(skip(ecx))]
288290
pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
289291
ecx: &mut InterpCx<'mir, 'tcx, M>,
290292
intern_kind: InternKind,
291293
ret: MPlaceTy<'tcx>,
292-
) where
294+
) -> Result<(), ErrorReported>
295+
where
293296
'tcx: 'mir,
294297
{
295298
let tcx = ecx.tcx;
@@ -405,12 +408,14 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
405408
// Codegen does not like dangling pointers, and generally `tcx` assumes that
406409
// all allocations referenced anywhere actually exist. So, make sure we error here.
407410
ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant");
411+
return Err(ErrorReported);
408412
} else if ecx.tcx.get_global_alloc(alloc_id).is_none() {
409413
// We have hit an `AllocId` that is neither in local or global memory and isn't
410414
// marked as dangling by local memory. That should be impossible.
411415
span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id);
412416
}
413417
}
418+
Ok(())
414419
}
415420

416421
impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

compiler/rustc_mir/src/interpret/operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
544544
// Early-return cases.
545545
let val_val = match val.val {
546546
ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric),
547-
ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)),
547+
ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorReported)),
548548
ty::ConstKind::Unevaluated(def, substs, promoted) => {
549549
let instance = self.resolve(def, substs)?;
550550
return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into());

src/test/ui/consts/dangling-alloc-id-ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ union Foo<'a> {
66
long_live_the_unit: &'static (),
77
}
88

9-
const FOO: &() = { //~ ERROR it is undefined behavior to use this value
9+
const FOO: &() = {
1010
//~^ ERROR encountered dangling pointer in final constant
1111
let y = ();
1212
unsafe { Foo { y: &y }.long_live_the_unit }

src/test/ui/consts/dangling-alloc-id-ice.stderr

+1-14
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,5 @@ LL | | unsafe { Foo { y: &y }.long_live_the_unit }
88
LL | | };
99
| |__^
1010

11-
error[E0080]: it is undefined behavior to use this value
12-
--> $DIR/dangling-alloc-id-ice.rs:9:1
13-
|
14-
LL | / const FOO: &() = {
15-
LL | |
16-
LL | | let y = ();
17-
LL | | unsafe { Foo { y: &y }.long_live_the_unit }
18-
LL | | };
19-
| |__^ type validation failed: encountered a dangling reference (use-after-free)
20-
|
21-
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
22-
23-
error: aborting due to 2 previous errors
11+
error: aborting due to previous error
2412

25-
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/issue-78655.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const FOO: *const u32 = { //~ ERROR encountered dangling pointer in final constant
2+
let x;
3+
&x //~ ERROR borrow of possibly-uninitialized variable: `x`
4+
};
5+
6+
fn main() {
7+
let FOO = FOO;
8+
//~^ ERROR could not evaluate constant pattern
9+
//~| ERROR could not evaluate constant pattern
10+
}

src/test/ui/consts/issue-78655.stderr

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error[E0381]: borrow of possibly-uninitialized variable: `x`
2+
--> $DIR/issue-78655.rs:3:5
3+
|
4+
LL | &x
5+
| ^^ use of possibly-uninitialized `x`
6+
7+
error: encountered dangling pointer in final constant
8+
--> $DIR/issue-78655.rs:1:1
9+
|
10+
LL | / const FOO: *const u32 = {
11+
LL | | let x;
12+
LL | | &x
13+
LL | | };
14+
| |__^
15+
16+
error: could not evaluate constant pattern
17+
--> $DIR/issue-78655.rs:7:9
18+
|
19+
LL | let FOO = FOO;
20+
| ^^^
21+
22+
error: could not evaluate constant pattern
23+
--> $DIR/issue-78655.rs:7:9
24+
|
25+
LL | let FOO = FOO;
26+
| ^^^
27+
28+
error: aborting due to 4 previous errors
29+
30+
For more information about this error, try `rustc --explain E0381`.

0 commit comments

Comments
 (0)