Skip to content

Commit afb8cba

Browse files
committed
Move hir::Lit -> ty::Const conversion into its own file
1 parent 40412dc commit afb8cba

File tree

4 files changed

+106
-101
lines changed

4 files changed

+106
-101
lines changed

src/librustc_mir/hair/constant.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use syntax::ast;
2+
use rustc::ty::{self, Ty, TyCtxt, ParamEnv};
3+
use syntax_pos::symbol::Symbol;
4+
use rustc::mir::interpret::{ConstValue, Scalar};
5+
6+
#[derive(PartialEq)]
7+
crate enum LitToConstError {
8+
UnparseableFloat,
9+
Reported,
10+
}
11+
12+
crate fn lit_to_const<'a, 'gcx, 'tcx>(
13+
lit: &'tcx ast::LitKind,
14+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
15+
ty: Ty<'tcx>,
16+
neg: bool,
17+
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
18+
use syntax::ast::*;
19+
20+
let trunc = |n| {
21+
let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
22+
let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
23+
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
24+
let shift = 128 - width.bits();
25+
let result = (n << shift) >> shift;
26+
trace!("trunc result: {}", result);
27+
Ok(ConstValue::Scalar(Scalar::Bits {
28+
bits: result,
29+
size: width.bytes() as u8,
30+
}))
31+
};
32+
33+
use rustc::mir::interpret::*;
34+
let lit = match *lit {
35+
LitKind::Str(ref s, _) => {
36+
let s = s.as_str();
37+
let id = tcx.allocate_bytes(s.as_bytes());
38+
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
39+
},
40+
LitKind::ByteStr(ref data) => {
41+
let id = tcx.allocate_bytes(data);
42+
ConstValue::Scalar(Scalar::Ptr(id.into()))
43+
},
44+
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
45+
bits: n as u128,
46+
size: 1,
47+
}),
48+
LitKind::Int(n, _) if neg => {
49+
let n = n as i128;
50+
let n = n.overflowing_neg().0;
51+
trunc(n as u128)?
52+
},
53+
LitKind::Int(n, _) => trunc(n)?,
54+
LitKind::Float(n, fty) => {
55+
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
56+
}
57+
LitKind::FloatUnsuffixed(n) => {
58+
let fty = match ty.sty {
59+
ty::Float(fty) => fty,
60+
_ => bug!()
61+
};
62+
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
63+
}
64+
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
65+
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
66+
};
67+
Ok(ty::Const::from_const_value(tcx, lit, ty))
68+
}
69+
70+
fn parse_float<'tcx>(
71+
num: Symbol,
72+
fty: ast::FloatTy,
73+
neg: bool,
74+
) -> Result<ConstValue<'tcx>, ()> {
75+
let num = num.as_str();
76+
use rustc_apfloat::ieee::{Single, Double};
77+
use rustc_apfloat::Float;
78+
let (bits, size) = match fty {
79+
ast::FloatTy::F32 => {
80+
num.parse::<f32>().map_err(|_| ())?;
81+
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
82+
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
83+
});
84+
if neg {
85+
f = -f;
86+
}
87+
(f.to_bits(), 4)
88+
}
89+
ast::FloatTy::F64 => {
90+
num.parse::<f64>().map_err(|_| ())?;
91+
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
92+
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
93+
});
94+
if neg {
95+
f = -f;
96+
}
97+
(f.to_bits(), 8)
98+
}
99+
};
100+
101+
Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
102+
}

src/librustc_mir/hair/cx/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use syntax::attr;
3131
use syntax::symbol::Symbol;
3232
use rustc::hir;
3333
use rustc_data_structures::sync::Lrc;
34-
use hair::pattern::{lit_to_const, LitToConstError};
34+
use hair::constant::{lit_to_const, LitToConstError};
3535

3636
#[derive(Clone)]
3737
pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {

src/librustc_mir/hair/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use syntax_pos::Span;
2626
use self::cx::Cx;
2727

2828
pub mod cx;
29+
mod constant;
2930

3031
pub mod pattern;
3132
pub use self::pattern::{BindingMode, Pattern, PatternKind, FieldPattern};

src/librustc_mir/hair/pattern/mod.rs

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ pub(crate) use self::check_match::check_match;
1919
use const_eval::{const_field, const_variant_index};
2020

2121
use hair::util::UserAnnotatedTyHelpers;
22+
use hair::constant::*;
2223

2324
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
2425
use rustc::mir::{ProjectionElem, UserTypeAnnotation, UserTypeProjection, UserTypeProjections};
2526
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
26-
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, ParamEnv};
27+
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
2728
use rustc::ty::subst::{Substs, Kind};
2829
use rustc::ty::layout::VariantIdx;
2930
use rustc::hir::{self, PatKind, RangeEnd};
@@ -37,7 +38,6 @@ use std::fmt;
3738
use syntax::ast;
3839
use syntax::ptr::P;
3940
use syntax_pos::Span;
40-
use syntax_pos::symbol::Symbol;
4141

4242
#[derive(Clone, Debug)]
4343
pub enum PatternError {
@@ -1292,101 +1292,3 @@ pub fn compare_const_vals<'a, 'tcx>(
12921292

12931293
fallback()
12941294
}
1295-
1296-
#[derive(PartialEq)]
1297-
pub enum LitToConstError {
1298-
UnparseableFloat,
1299-
Reported,
1300-
}
1301-
1302-
pub fn lit_to_const<'a, 'gcx, 'tcx>(
1303-
lit: &'tcx ast::LitKind,
1304-
tcx: TyCtxt<'a, 'gcx, 'tcx>,
1305-
ty: Ty<'tcx>,
1306-
neg: bool,
1307-
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
1308-
use syntax::ast::*;
1309-
1310-
let trunc = |n| {
1311-
let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
1312-
let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
1313-
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
1314-
let shift = 128 - width.bits();
1315-
let result = (n << shift) >> shift;
1316-
trace!("trunc result: {}", result);
1317-
Ok(ConstValue::Scalar(Scalar::Bits {
1318-
bits: result,
1319-
size: width.bytes() as u8,
1320-
}))
1321-
};
1322-
1323-
use rustc::mir::interpret::*;
1324-
let lit = match *lit {
1325-
LitKind::Str(ref s, _) => {
1326-
let s = s.as_str();
1327-
let id = tcx.allocate_bytes(s.as_bytes());
1328-
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
1329-
},
1330-
LitKind::ByteStr(ref data) => {
1331-
let id = tcx.allocate_bytes(data);
1332-
ConstValue::Scalar(Scalar::Ptr(id.into()))
1333-
},
1334-
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
1335-
bits: n as u128,
1336-
size: 1,
1337-
}),
1338-
LitKind::Int(n, _) if neg => {
1339-
let n = n as i128;
1340-
let n = n.overflowing_neg().0;
1341-
trunc(n as u128)?
1342-
},
1343-
LitKind::Int(n, _) => trunc(n)?,
1344-
LitKind::Float(n, fty) => {
1345-
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
1346-
}
1347-
LitKind::FloatUnsuffixed(n) => {
1348-
let fty = match ty.sty {
1349-
ty::Float(fty) => fty,
1350-
_ => bug!()
1351-
};
1352-
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
1353-
}
1354-
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
1355-
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
1356-
};
1357-
Ok(ty::Const::from_const_value(tcx, lit, ty))
1358-
}
1359-
1360-
pub fn parse_float<'tcx>(
1361-
num: Symbol,
1362-
fty: ast::FloatTy,
1363-
neg: bool,
1364-
) -> Result<ConstValue<'tcx>, ()> {
1365-
let num = num.as_str();
1366-
use rustc_apfloat::ieee::{Single, Double};
1367-
use rustc_apfloat::Float;
1368-
let (bits, size) = match fty {
1369-
ast::FloatTy::F32 => {
1370-
num.parse::<f32>().map_err(|_| ())?;
1371-
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
1372-
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
1373-
});
1374-
if neg {
1375-
f = -f;
1376-
}
1377-
(f.to_bits(), 4)
1378-
}
1379-
ast::FloatTy::F64 => {
1380-
num.parse::<f64>().map_err(|_| ())?;
1381-
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
1382-
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
1383-
});
1384-
if neg {
1385-
f = -f;
1386-
}
1387-
(f.to_bits(), 8)
1388-
}
1389-
};
1390-
1391-
Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
1392-
}

0 commit comments

Comments
 (0)