Skip to content

Commit

Permalink
Changed dec2flt to use the Eisel-Lemire algorithm.
Browse files Browse the repository at this point in the history
Implementation is based off fast-float-rust, with a few notable changes.

- Some unsafe methods have been removed.
- Safe methods with inherently unsafe functionality have been removed.
- All unsafe functionality is documented and provably safe.
- Extensive documentation has been added for simpler maintenance.
- Inline annotations on internal routines has been removed.
- Fixed Python errors in src/etc/test-float-parse/runtests.py.
- Updated test-float-parse to be a library, to avoid missing rand dependency.
- Added regression tests for rust-lang#31109 and rust-lang#31407 in core tests.
- Added regression tests for rust-lang#31109 and rust-lang#31407 in ui tests.
- Use the existing slice primitive to simplify shared dec2flt methods
- Remove Miri ignores from dec2flt, due to faster parsing times.

- resolves rust-lang#85198
- resolves rust-lang#85214
- resolves rust-lang#85234
- fixes rust-lang#31407
- fixes rust-lang#31109
- fixes rust-lang#53015
- resolves rust-lang#68396
- closes aldanor/fast-float-rust#15
  • Loading branch information
Alexhuszagh committed Jul 17, 2021
1 parent d2b04f0 commit 8752b40
Show file tree
Hide file tree
Showing 43 changed files with 2,530 additions and 2,823 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ pub enum LitToConstError {
/// This is used for graceful error handling (`delay_span_bug`) in
/// type checking (`Const::from_anon_const`).
TypeError,
UnparseableFloat,
Reported,
}

Expand Down
16 changes: 9 additions & 7 deletions compiler/rustc_mir_build/src/thir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ 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).map_err(|_| LitToConstError::UnparseableFloat)?
}
(ast::LitKind::Float(n, _), ty::Float(fty)) => parse_float(*n, *fty, neg),
(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 @@ -57,12 +55,14 @@ 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) -> Result<ConstValue<'tcx>, ()> {
fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> 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>().map_err(|_| ())?;
let rust_f = num
.parse::<f32>()
.unwrap_or_else(|e| panic!("f32 failed to parse `{}`: {:?}", num, e));
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
});
Expand All @@ -82,7 +82,9 @@ fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Result<ConstVa
Scalar::from_f32(f)
}
ty::FloatTy::F64 => {
let rust_f = num.parse::<f64>().map_err(|_| ())?;
let rust_f = num
.parse::<f64>()
.unwrap_or_else(|e| panic!("f64 failed to parse `{}`: {:?}", num, e));
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
});
Expand All @@ -103,5 +105,5 @@ fn parse_float<'tcx>(num: Symbol, fty: ty::FloatTy, neg: bool) -> Result<ConstVa
}
};

Ok(ConstValue::Scalar(scalar))
ConstValue::Scalar(scalar)
}
6 changes: 0 additions & 6 deletions compiler/rustc_mir_build/src/thir/cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,6 @@ impl<'tcx> Cx<'tcx> {

match self.tcx.at(sp).lit_to_const(LitToConstInput { lit, ty, neg }) {
Ok(c) => c,
Err(LitToConstError::UnparseableFloat) => {
// FIXME(#31407) this is only necessary because float parsing is buggy
self.tcx.sess.span_err(sp, "could not evaluate float literal (see issue #31407)");
// create a dummy value and continue compiling
self.tcx.const_error(ty)
}
Err(LitToConstError::Reported) => {
// create a dummy value and continue compiling
self.tcx.const_error(ty)
Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
}

impl PatCtxt<'_, '_> {
fn report_inlining_errors(&self, pat_span: Span) {
fn report_inlining_errors(&self) {
for error in &self.errors {
match *error {
PatternError::StaticInPattern(span) => {
Expand All @@ -96,14 +96,6 @@ impl PatCtxt<'_, '_> {
PatternError::ConstParamInPattern(span) => {
self.span_e0158(span, "const parameters cannot be referenced in patterns")
}
PatternError::FloatBug => {
// FIXME(#31407) this is only necessary because float parsing is buggy
rustc_middle::mir::interpret::struct_error(
self.tcx.at(pat_span),
"could not evaluate float literal (see issue #31407)",
)
.emit();
}
PatternError::NonConstPath(span) => {
rustc_middle::mir::interpret::struct_error(
self.tcx.at(span),
Expand Down Expand Up @@ -142,7 +134,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(pattern));
if !patcx.errors.is_empty() {
*have_errors = true;
patcx.report_inlining_errors(pat.span);
patcx.report_inlining_errors();
}
(pattern, pattern_ty)
}
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ crate enum PatternError {
AssocConstInPattern(Span),
ConstParamInPattern(Span),
StaticInPattern(Span),
FloatBug,
NonConstPath(Span),
}

Expand Down Expand Up @@ -563,10 +562,6 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
match self.tcx.at(expr.span).lit_to_const(lit_input) {
Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span, false).kind,
Err(LitToConstError::UnparseableFloat) => {
self.errors.push(PatternError::FloatBug);
PatKind::Wild
}
Err(LitToConstError::Reported) => PatKind::Wild,
Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
}
Expand Down
Loading

0 comments on commit 8752b40

Please sign in to comment.