Skip to content

Commit

Permalink
Fix an ICE when lowering a float with missing exponent magnitude
Browse files Browse the repository at this point in the history
Co-authored-by: Simonas Kazlauskas <github@kazlauskas.me>
  • Loading branch information
terrarier2111 and nagisa committed Dec 19, 2021
1 parent 2af5c65 commit 0003280
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
22 changes: 13 additions & 9 deletions compiler/rustc_mir_build/src/thir/constant.rs
Expand Up @@ -46,7 +46,9 @@ crate fn lit_to_const<'tcx>(
(ast::LitKind::Int(n, _), ty::Uint(_)) | (ast::LitKind::Int(n, _), ty::Int(_)) => {
trunc(if neg { (*n as i128).overflowing_neg().0 as u128 } else { *n })?
}
(ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float(*n, *fty, neg),
(ast::LitKind::Float(n, _), ty::Float(fty)) => {
parse_float(*n, *fty, neg).ok_or(LitToConstError::Reported)?
}
(ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
(ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
(ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported),
Expand All @@ -55,14 +57,15 @@ crate fn lit_to_const<'tcx>(
Ok(ty::Const::from_value(tcx, lit, ty))
}

fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> ConstValue<'tcx> {
fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Option<ConstValue<'tcx>> {
let num = num.as_str();
use rustc_apfloat::ieee::{Double, Single};
let scalar = match fty {
ty::FloatTy::F32 => {
let rust_f = num
.parse::<f32>()
.unwrap_or_else(|e| panic!("f32 failed to parse `{}`: {:?}", num, e));
let rust_f = match num.parse::<f32>() {
Ok(f) => f,
Err(_) => return None,
};
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
});
Expand All @@ -82,9 +85,10 @@ fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> ConstValue<'tc
Scalar::from_f32(f)
}
ty::FloatTy::F64 => {
let rust_f = num
.parse::<f64>()
.unwrap_or_else(|e| panic!("f64 failed to parse `{}`: {:?}", num, e));
let rust_f = match num.parse::<f64>() {
Ok(f) => f,
Err(_) => return None,
};
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
});
Expand All @@ -105,5 +109,5 @@ fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> ConstValue<'tc
}
};

ConstValue::Scalar(scalar)
Some(ConstValue::Scalar(scalar))
}
6 changes: 6 additions & 0 deletions src/test/ui/consts/issue-91434.rs
@@ -0,0 +1,6 @@
fn main() {
[9; [[9E; h]]];
//~^ ERROR: expected at least one digit in exponent
//~| ERROR: cannot find value `h` in this scope [E0425]
//~| ERROR: constant expression depends on a generic parameter
}
23 changes: 23 additions & 0 deletions src/test/ui/consts/issue-91434.stderr
@@ -0,0 +1,23 @@
error: expected at least one digit in exponent
--> $DIR/issue-91434.rs:2:11
|
LL | [9; [[9E; h]]];
| ^^

error[E0425]: cannot find value `h` in this scope
--> $DIR/issue-91434.rs:2:15
|
LL | [9; [[9E; h]]];
| ^ not found in this scope

error: constant expression depends on a generic parameter
--> $DIR/issue-91434.rs:2:9
|
LL | [9; [[9E; h]]];
| ^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error: aborting due to 3 previous errors

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

0 comments on commit 0003280

Please sign in to comment.