Enable const casting for f16 and f128 · rust-lang/rust@648cb16 (original) (raw)

1

1

`use std::assert_matches::assert_matches;

`

2

2

``

3

``

`-

use rustc_apfloat::ieee::{Double, Single};

`

``

3

`+

use rustc_apfloat::ieee::{Double, Half, Quad, Single};

`

4

4

`use rustc_apfloat::{Float, FloatConvert};

`

5

5

`use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};

`

6

6

`use rustc_middle::mir::CastKind;

`

`@@ -187,10 +187,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

187

187

`bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty)

`

188

188

`};

`

189

189

`let val = match fty {

`

190

``

`-

FloatTy::F16 => unimplemented!("f16_f128"),

`

``

190

`+

FloatTy::F16 => self.cast_from_float(src.to_scalar().to_f16()?, cast_to.ty),

`

191

191

`FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),

`

192

192

`FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),

`

193

``

`-

FloatTy::F128 => unimplemented!("f16_f128"),

`

``

193

`+

FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty),

`

194

194

`};

`

195

195

`Ok(ImmTy::from_scalar(val, cast_to))

`

196

196

`}

`

`@@ -296,18 +296,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

296

296

`Float(fty) if signed => {

`

297

297

`let v = v as i128;

`

298

298

`match fty {

`

299

``

`-

FloatTy::F16 => unimplemented!("f16_f128"),

`

``

299

`+

FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value),

`

300

300

`FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value),

`

301

301

`FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value),

`

302

``

`-

FloatTy::F128 => unimplemented!("f16_f128"),

`

``

302

`+

FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value),

`

303

303

`}

`

304

304

`}

`

305

305

`// unsigned int -> float

`

306

306

`Float(fty) => match fty {

`

307

``

`-

FloatTy::F16 => unimplemented!("f16_f128"),

`

``

307

`+

FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value),

`

308

308

`FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),

`

309

309

`FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),

`

310

``

`-

FloatTy::F128 => unimplemented!("f16_f128"),

`

``

310

`+

FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value),

`

311

311

`},

`

312

312

``

313

313

`// u8 -> char

`

`@@ -321,7 +321,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

321

321

`` /// Low-level cast helper function. Converts an apfloat f into int or float types.

``

322

322

`fn cast_from_float(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::Provenance>

`

323

323

`where

`

324

``

`-

F: Float + Into<Scalar<M::Provenance>> + FloatConvert + FloatConvert,

`

``

324

`+

F: Float

`

``

325

`+

`

``

326

`+

`

``

327

`+

`

``

328

`+

`

``

329

`+

`

325

330

`{

`

326

331

`use rustc_type_ir::TyKind::*;

`

327

332

``

`@@ -358,10 +363,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

`

358

363

`}

`

359

364

`// float -> float

`

360

365

`Float(fty) => match fty {

`

361

``

`-

FloatTy::F16 => unimplemented!("f16_f128"),

`

``

366

`+

FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)),

`

362

367

`FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)),

`

363

368

`FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)),

`

364

``

`-

FloatTy::F128 => unimplemented!("f16_f128"),

`

``

369

`+

FloatTy::F128 => {

`

``

370

`+

Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value))

`

``

371

`+

}

`

365

372

`},

`

366

373

`// That's it.

`

367

374

` _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty),

`