Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support float literals #880

Merged
merged 13 commits into from
Sep 11, 2024
6 changes: 4 additions & 2 deletions engine/lib/import_thir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ end) : EXPR = struct
Thir.expr_kind =
match ce with
| Literal lit ->
let lit, neg = constant_lit_to_lit lit in
let lit, neg = constant_lit_to_lit lit span in
Literal { lit = { node = lit; span }; neg }
| Adt { fields; info } ->
let fields = List.map ~f:constant_field_expr fields in
Expand All @@ -810,7 +810,8 @@ end) : EXPR = struct
unimplemented [ span ]
"constant_lit_to_lit: TraitConst | FnPtr | MutPtr"
| Todo _ -> unimplemented [ span ] "ConstantExpr::Todo"
and constant_lit_to_lit (l : Thir.constant_literal) : Thir.lit_kind * bool =
and constant_lit_to_lit (l : Thir.constant_literal) span :
Thir.lit_kind * bool =
match l with
| Bool v -> (Bool v, false)
| Char v -> (Char v, false)
Expand All @@ -819,6 +820,7 @@ end) : EXPR = struct
| Some v -> (Int (v, Signed ty), true)
| None -> (Int (v, Signed ty), false))
| Int (Uint (v, ty)) -> (Int (v, Unsigned ty), false)
| Float _ -> unimplemented [ span ] "constant_lit_to_lit: Float"
| Str (v, style) -> (Str (v, style), false)
| ByteStr (v, style) -> (ByteStr (v, style), false)
and constant_field_expr ({ field; value } : Thir.constant_field_expr) :
Expand Down
17 changes: 17 additions & 0 deletions frontend/exporter/src/constant_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub enum ConstantInt {
pub enum ConstantLiteral {
Bool(bool),
Char(char),
// Rust floats do not have the Eq or Ord traits due to the presence of NaN
// We instead store their bit representation, which always fits in a u128
Float(u128, FloatTy),
Int(ConstantInt),
Str(String, StrStyle),
ByteStr(Vec<u8>, StrStyle),
Expand Down Expand Up @@ -156,6 +159,7 @@ mod rustc {
}
}
}
Float(_bits, _ty) => todo!("Converting float literals back to AST"),
ByteStr(raw, str_style) => LitKind::ByteStr(raw, str_style),
Str(raw, str_style) => LitKind::Str(raw, str_style),
};
Expand Down Expand Up @@ -255,6 +259,19 @@ mod rustc {
});
ConstantExprKind::Literal(scalar_int_to_constant_literal(s, scalar_int, ty))
}
ty::Float(float_type) => {
let scalar_int = scalar.try_to_scalar_int().unwrap_or_else(|_| {
fatal!(
s[span],
"Type is [Float], but the scalar {:#?} is not a number",
scalar
)
});
ConstantExprKind::Literal(ConstantLiteral::Float(
scalar_int.to_bits_unchecked(),
float_type.sinto(s),
))
}
ty::Ref(_, inner_ty, Mutability::Not) | ty::RawPtr(inner_ty, Mutability::Mut) => {
let tcx = s.base().tcx;
let pointer = scalar.to_pointer(&tcx).unwrap_or_else(|_| {
Expand Down
Loading