Skip to content

Commit c298efd

Browse files
committed
Auto merge of #28748 - nikomatsakis:universal-mir, r=pnkfelix
I had to fix a few things. Notable changes: 1. I removed the MIR support for constants, instead falling back to the existing `ConstVal`. I still think we ought to reform how we handle constants, but it's not clear to me that the approach I was taking is correct, and anyway I think we ought to do it separately. 2. I adjusted how we handle bindings in matches: we now *declare* all the bindings up front, rather than doing it as we encounter them. This is not only simpler, since we don't have to check if a binding has already been declared, it avoids ICEs if any of the arms turn out to be unreachable. 3. I do MIR construction *after* `check_match`, because it detects various broken cases. I'd like for `check_match` to be subsumed by MIR construction, but we can do that as a separate PR (if indeed it makes sense). I did a crater run and found no regressions in the wild: https://gist.github.com/nikomatsakis/0038f90e10c8ad00f2f8
2 parents 0db2bc6 + 7e1e830 commit c298efd

File tree

14 files changed

+201
-294
lines changed

14 files changed

+201
-294
lines changed

src/librustc/middle/const_eval.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use std::borrow::{Cow, IntoCow};
3838
use std::num::wrapping::OverflowingOps;
3939
use std::cmp::Ordering;
4040
use std::collections::hash_map::Entry::Vacant;
41+
use std::mem::transmute;
4142
use std::{i8, i16, i32, i64, u8, u16, u32, u64};
4243
use std::rc::Rc;
4344

@@ -242,7 +243,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
242243
}
243244
}
244245

245-
#[derive(Clone, PartialEq)]
246+
#[derive(Clone, Debug)]
246247
pub enum ConstVal {
247248
Float(f64),
248249
Int(i64),
@@ -254,6 +255,27 @@ pub enum ConstVal {
254255
Tuple(ast::NodeId),
255256
}
256257

258+
/// Note that equality for `ConstVal` means that the it is the same
259+
/// constant, not that the rust values are equal. In particular, `NaN
260+
/// == NaN` (at least if it's the same NaN; distinct encodings for NaN
261+
/// are considering unequal).
262+
impl PartialEq for ConstVal {
263+
#[stable(feature = "rust1", since = "1.0.0")]
264+
fn eq(&self, other: &ConstVal) -> bool {
265+
match (self, other) {
266+
(&Float(a), &Float(b)) => unsafe{transmute::<_,u64>(a) == transmute::<_,u64>(b)},
267+
(&Int(a), &Int(b)) => a == b,
268+
(&Uint(a), &Uint(b)) => a == b,
269+
(&Str(ref a), &Str(ref b)) => a == b,
270+
(&ByteStr(ref a), &ByteStr(ref b)) => a == b,
271+
(&Bool(a), &Bool(b)) => a == b,
272+
(&Struct(a), &Struct(b)) => a == b,
273+
(&Tuple(a), &Tuple(b)) => a == b,
274+
_ => false,
275+
}
276+
}
277+
}
278+
257279
impl ConstVal {
258280
pub fn description(&self) -> &'static str {
259281
match *self {

src/librustc_driver/driver.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -718,9 +718,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
718718
// passes are timed inside typeck
719719
typeck::check_crate(tcx, trait_map);
720720

721-
time(time_passes, "MIR dump", ||
722-
mir::dump::dump_crate(tcx));
723-
724721
time(time_passes, "const checking", ||
725722
middle::check_const::check_crate(tcx));
726723

@@ -741,6 +738,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
741738
time(time_passes, "match checking", ||
742739
middle::check_match::check_crate(tcx));
743740

741+
time(time_passes, "MIR dump", ||
742+
mir::dump::dump_crate(tcx));
743+
744744
time(time_passes, "liveness checking", ||
745745
middle::liveness::check_crate(tcx));
746746

src/librustc_mir/build/expr/as_constant.rs

+9-88
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
//! See docs in build/expr/mod.rs
1212
13-
use rustc_data_structures::fnv::FnvHashMap;
14-
1513
use build::{Builder};
1614
use hair::*;
1715
use repr::*;
@@ -28,93 +26,16 @@ impl<H:Hair> Builder<H> {
2826

2927
fn expr_as_constant(&mut self, expr: Expr<H>) -> Constant<H> {
3028
let this = self;
31-
let Expr { ty: _, temp_lifetime: _, span, kind } = expr;
32-
let kind = match kind {
33-
ExprKind::Scope { extent: _, value } => {
34-
return this.as_constant(value);
35-
}
36-
ExprKind::Literal { literal } => {
37-
ConstantKind::Literal(literal)
38-
}
39-
ExprKind::Vec { fields } => {
40-
let fields = this.as_constants(fields);
41-
ConstantKind::Aggregate(AggregateKind::Vec, fields)
42-
}
43-
ExprKind::Tuple { fields } => {
44-
let fields = this.as_constants(fields);
45-
ConstantKind::Aggregate(AggregateKind::Tuple, fields)
46-
}
47-
ExprKind::Adt { adt_def, variant_index, substs, fields, base: None } => {
48-
let field_names = this.hir.fields(adt_def, variant_index);
49-
let fields = this.named_field_constants(field_names, fields);
50-
ConstantKind::Aggregate(AggregateKind::Adt(adt_def, variant_index, substs), fields)
51-
}
52-
ExprKind::Repeat { value, count } => {
53-
let value = Box::new(this.as_constant(value));
54-
let count = Box::new(this.as_constant(count));
55-
ConstantKind::Repeat(value, count)
56-
}
57-
ExprKind::Binary { op, lhs, rhs } => {
58-
let lhs = Box::new(this.as_constant(lhs));
59-
let rhs = Box::new(this.as_constant(rhs));
60-
ConstantKind::BinaryOp(op, lhs, rhs)
61-
}
62-
ExprKind::Unary { op, arg } => {
63-
let arg = Box::new(this.as_constant(arg));
64-
ConstantKind::UnaryOp(op, arg)
65-
}
66-
ExprKind::Field { lhs, name } => {
67-
let lhs = this.as_constant(lhs);
68-
ConstantKind::Projection(
69-
Box::new(ConstantProjection {
70-
base: lhs,
71-
elem: ProjectionElem::Field(name),
72-
}))
73-
}
74-
ExprKind::Deref { arg } => {
75-
let arg = this.as_constant(arg);
76-
ConstantKind::Projection(
77-
Box::new(ConstantProjection {
78-
base: arg,
79-
elem: ProjectionElem::Deref,
80-
}))
81-
}
82-
ExprKind::Call { fun, args } => {
83-
let fun = this.as_constant(fun);
84-
let args = this.as_constants(args);
85-
ConstantKind::Call(Box::new(fun), args)
86-
}
87-
_ => {
29+
let Expr { ty, temp_lifetime: _, span, kind } = expr;
30+
match kind {
31+
ExprKind::Scope { extent: _, value } =>
32+
this.as_constant(value),
33+
ExprKind::Literal { literal } =>
34+
Constant { span: span, ty: ty, literal: literal },
35+
_ =>
8836
this.hir.span_bug(
8937
span,
90-
&format!("expression is not a valid constant {:?}", kind));
91-
}
92-
};
93-
Constant { span: span, kind: kind }
94-
}
95-
96-
fn as_constants(&mut self,
97-
exprs: Vec<ExprRef<H>>)
98-
-> Vec<Constant<H>>
99-
{
100-
exprs.into_iter().map(|expr| self.as_constant(expr)).collect()
101-
}
102-
103-
fn named_field_constants(&mut self,
104-
field_names: Vec<Field<H>>,
105-
field_exprs: Vec<FieldExprRef<H>>)
106-
-> Vec<Constant<H>>
107-
{
108-
let fields_map: FnvHashMap<_, _> =
109-
field_exprs.into_iter()
110-
.map(|f| (f.name, self.as_constant(f.expr)))
111-
.collect();
112-
113-
let fields: Vec<_> =
114-
field_names.into_iter()
115-
.map(|n| fields_map[&n].clone())
116-
.collect();
117-
118-
fields
38+
&format!("expression is not a valid constant {:?}", kind)),
39+
}
11940
}
12041
}

src/librustc_mir/build/expr/into.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,16 @@ impl<H:Hair> Builder<H> {
9999
true_block, expr_span, destination,
100100
Constant {
101101
span: expr_span,
102-
kind: ConstantKind::Literal(Literal::Bool { value: true }),
102+
ty: this.hir.bool_ty(),
103+
literal: this.hir.true_literal(),
103104
});
104105

105106
this.cfg.push_assign_constant(
106107
false_block, expr_span, destination,
107108
Constant {
108109
span: expr_span,
109-
kind: ConstantKind::Literal(Literal::Bool { value: false }),
110+
ty: this.hir.bool_ty(),
111+
literal: this.hir.false_literal(),
110112
});
111113

112114
this.cfg.terminate(true_block, Terminator::Goto { target: join_block });

0 commit comments

Comments
 (0)