Skip to content

Commit a72f40d

Browse files
committed
Replace f16 and f128 unimplemented!/FIXMEs with real implementations
This removes the ICE codepaths for `f16` and `f128`. `rustc_apfloat` is used as a dependency for the parsing of these types, since their `FromStr` implementation will not be available in the standard library for a while.
1 parent 9e54ff2 commit a72f40d

File tree

5 files changed

+38
-10
lines changed

5 files changed

+38
-10
lines changed

clippy_lints/src/float_literal.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,17 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
141141
#[must_use]
142142
fn max_digits(fty: FloatTy) -> u32 {
143143
match fty {
144-
// FIXME(f16_f128): replace the magic numbers once `{f16,f128}::DIGITS` are available
145-
FloatTy::F16 => 3,
144+
FloatTy::F16 => f16::DIGITS,
146145
FloatTy::F32 => f32::DIGITS,
147146
FloatTy::F64 => f64::DIGITS,
148-
FloatTy::F128 => 33,
147+
FloatTy::F128 => f128::DIGITS,
149148
}
150149
}
151150

152151
/// Counts the digits excluding leading zeros
153152
#[must_use]
154153
fn count_digits(s: &str) -> usize {
155-
// Note that s does not contain the f32/64 suffix, and underscores have been stripped
154+
// Note that s does not contain the `f{16,32,64,128}`` suffix, and underscores have been stripped
156155
s.chars()
157156
.filter(|c| *c != '-' && *c != '.')
158157
.take_while(|c| *c != 'e' && *c != 'E')

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![feature(array_windows)]
22
#![feature(binary_heap_into_iter_sorted)]
33
#![feature(box_patterns)]
4+
#![feature(f128)]
5+
#![feature(f16)]
46
#![feature(if_let_guard)]
57
#![feature(iter_intersperse)]
68
#![feature(let_chains)]

clippy_utils/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ clippy_config = { path = "../clippy_config" }
99
arrayvec = { version = "0.7", default-features = false }
1010
itertools = "0.12"
1111
rustc-semver = "1.1"
12+
# FIXME(f16_f128): remove when no longer needed for parsing
13+
rustc_apfloat = "0.2.0"
1214

1315
[features]
1416
deny-warnings = ["clippy_config/deny-warnings"]

clippy_utils/src/consts.rs

+29-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use crate::source::{get_source_text, walk_span_to_context};
44
use crate::{clip, is_direct_expn_of, sext, unsext};
55

6+
use rustc_apfloat::ieee::{Half, Quad};
7+
use rustc_apfloat::Float;
68
use rustc_ast::ast::{self, LitFloatType, LitKind};
79
use rustc_data_structures::sync::Lrc;
810
use rustc_hir::def::{DefKind, Res};
@@ -33,10 +35,14 @@ pub enum Constant<'tcx> {
3335
Char(char),
3436
/// An integer's bit representation.
3537
Int(u128),
38+
/// An `f16`.
39+
F16(f16),
3640
/// An `f32`.
3741
F32(f32),
3842
/// An `f64`.
3943
F64(f64),
44+
/// An `f128`.
45+
F128(f128),
4046
/// `true` or `false`.
4147
Bool(bool),
4248
/// An array of constants.
@@ -161,12 +167,18 @@ impl<'tcx> Hash for Constant<'tcx> {
161167
Self::Int(i) => {
162168
i.hash(state);
163169
},
170+
Self::F16(f) => {
171+
f64::from(f).to_bits().hash(state);
172+
},
164173
Self::F32(f) => {
165174
f64::from(f).to_bits().hash(state);
166175
},
167176
Self::F64(f) => {
168177
f.to_bits().hash(state);
169178
},
179+
Self::F128(f) => {
180+
f.to_bits().hash(state);
181+
},
170182
Self::Bool(b) => {
171183
b.hash(state);
172184
},
@@ -268,6 +280,16 @@ impl<'tcx> Constant<'tcx> {
268280
}
269281
self
270282
}
283+
284+
fn parse_f16(s: &str) -> Self {
285+
let f: Half = s.parse().unwrap();
286+
Self::F16(f16::from_bits(f.to_bits().try_into().unwrap()))
287+
}
288+
289+
fn parse_f128(s: &str) -> Self {
290+
let f: Quad = s.parse().unwrap();
291+
Self::F128(f128::from_bits(f.to_bits()))
292+
}
271293
}
272294

273295
/// Parses a `LitKind` to a `Constant`.
@@ -279,16 +301,17 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
279301
LitKind::Char(c) => Constant::Char(c),
280302
LitKind::Int(n, _) => Constant::Int(n.get()),
281303
LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
282-
ast::FloatTy::F16 => unimplemented!("f16_f128"),
304+
// FIXME(f16_f128): just use `parse()` directly when available for `f16`/`f128`
305+
ast::FloatTy::F16 => Constant::parse_f16(is.as_str()),
283306
ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),
284307
ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),
285-
ast::FloatTy::F128 => unimplemented!("f16_f128"),
308+
ast::FloatTy::F128 => Constant::parse_f128(is.as_str()),
286309
},
287310
LitKind::Float(ref is, LitFloatType::Unsuffixed) => match ty.expect("type of float is known").kind() {
288-
ty::Float(FloatTy::F16) => unimplemented!("f16_f128"),
311+
ty::Float(FloatTy::F16) => Constant::parse_f16(is.as_str()),
289312
ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
290313
ty::Float(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
291-
ty::Float(FloatTy::F128) => unimplemented!("f16_f128"),
314+
ty::Float(FloatTy::F128) => Constant::parse_f128(is.as_str()),
292315
_ => bug!(),
293316
},
294317
LitKind::Bool(b) => Constant::Bool(b),
@@ -835,10 +858,10 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
835858
let range = alloc_range(offset + size * idx, size);
836859
let val = alloc.read_scalar(&lcx.tcx, range, /* read_provenance */ false).ok()?;
837860
res.push(match flt {
838-
FloatTy::F16 => unimplemented!("f16_f128"),
861+
FloatTy::F16 => Constant::F16(f16::from_bits(val.to_u16().ok()?)),
839862
FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().ok()?)),
840863
FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().ok()?)),
841-
FloatTy::F128 => unimplemented!("f16_f128"),
864+
FloatTy::F128 => Constant::F128(f128::from_bits(val.to_u128().ok()?)),
842865
});
843866
}
844867
Some(Constant::Vec(res))

clippy_utils/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#![feature(box_patterns)]
33
#![feature(control_flow_enum)]
44
#![feature(exhaustive_patterns)]
5+
#![feature(f128)]
6+
#![feature(f16)]
57
#![feature(if_let_guard)]
68
#![feature(let_chains)]
79
#![feature(lint_reasons)]

0 commit comments

Comments
 (0)