Skip to content

Commit

Permalink
rustc_const_eval: always demand typeck_tables for evaluating constants.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Feb 25, 2017
1 parent c832e6f commit e7a4882
Show file tree
Hide file tree
Showing 60 changed files with 705 additions and 1,221 deletions.
73 changes: 0 additions & 73 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,44 +390,6 @@ RFC. It is, however, [currently unimplemented][iss15872].
[iss15872]: https://github.com/rust-lang/rust/issues/15872
"##,

E0109: r##"
You tried to give a type parameter to a type which doesn't need it. Erroneous
code example:
```compile_fail,E0109
type X = u32<i32>; // error: type parameters are not allowed on this type
```
Please check that you used the correct type and recheck its definition. Perhaps
it doesn't need the type parameter.
Example:
```
type X = u32; // this compiles
```
Note that type parameters for enum-variant constructors go after the variant,
not after the enum (Option::None::<u32>, not Option::<u32>::None).
"##,

E0110: r##"
You tried to give a lifetime parameter to a type which doesn't need it.
Erroneous code example:
```compile_fail,E0110
type X = u32<'static>; // error: lifetime parameters are not allowed on
// this type
```
Please check that the correct type was used and recheck its definition; perhaps
it doesn't need the lifetime parameter. Example:
```
type X = u32; // ok!
```
"##,

E0133: r##"
Unsafe code was used outside of an unsafe function or block.
Expand Down Expand Up @@ -627,41 +589,6 @@ attributes:
See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0229: r##"
An associated type binding was done outside of the type parameter declaration
and `where` clause. Erroneous code example:
```compile_fail,E0229
pub trait Foo {
type A;
fn boo(&self) -> <Self as Foo>::A;
}
struct Bar;
impl Foo for isize {
type A = usize;
fn boo(&self) -> usize { 42 }
}
fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
// error: associated type bindings are not allowed here
```
To solve this error, please move the type bindings in the type parameter
declaration:
```ignore
fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
```
Or in the `where` clause:
```ignore
fn baz<I>(x: &<I as Foo>::A) where I: Foo<A=Bar> {}
```
"##,

E0261: r##"
When using a lifetime like `'a` in a type, it must be declared before being
used.
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ pub mod infer;
pub mod lint;

pub mod middle {
pub mod astconv_util;
pub mod expr_use_visitor;
pub mod const_val;
pub mod cstore;
Expand Down
83 changes: 0 additions & 83 deletions src/librustc/middle/astconv_util.rs

This file was deleted.

21 changes: 11 additions & 10 deletions src/librustc/middle/const_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,30 @@ use syntax::symbol::InternedString;
use syntax::ast;
use std::rc::Rc;
use hir::def_id::DefId;
use ty::subst::Substs;
use rustc_const_math::*;

use self::ConstVal::*;
pub use rustc_const_math::ConstInt;

use std::collections::BTreeMap;

#[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq)]
pub enum ConstVal {
pub enum ConstVal<'tcx> {
Float(ConstFloat),
Integral(ConstInt),
Str(InternedString),
ByteStr(Rc<Vec<u8>>),
Bool(bool),
Function(DefId),
Struct(BTreeMap<ast::Name, ConstVal>),
Tuple(Vec<ConstVal>),
Array(Vec<ConstVal>),
Repeat(Box<ConstVal>, u64),
Function(DefId, &'tcx Substs<'tcx>),
Struct(BTreeMap<ast::Name, ConstVal<'tcx>>),
Tuple(Vec<ConstVal<'tcx>>),
Array(Vec<ConstVal<'tcx>>),
Repeat(Box<ConstVal<'tcx>>, u64),
Char(char),
}

impl ConstVal {
impl<'tcx> ConstVal<'tcx> {
pub fn description(&self) -> &'static str {
match *self {
Float(f) => f.description(),
Expand All @@ -43,7 +45,7 @@ impl ConstVal {
Bool(_) => "boolean",
Struct(_) => "struct",
Tuple(_) => "tuple",
Function(_) => "function definition",
Function(..) => "function definition",
Array(..) => "array",
Repeat(..) => "repeat",
Char(..) => "char",
Expand All @@ -53,8 +55,7 @@ impl ConstVal {
pub fn to_const_int(&self) -> Option<ConstInt> {
match *self {
ConstVal::Integral(i) => Some(i),
ConstVal::Bool(true) => Some(ConstInt::Infer(1)),
ConstVal::Bool(false) => Some(ConstInt::Infer(0)),
ConstVal::Bool(b) => Some(ConstInt::U8(b as u8)),
ConstVal::Char(ch) => Some(ConstInt::U32(ch as u32)),
_ => None
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ impl<'tcx> Terminator<'tcx> {
impl<'tcx> TerminatorKind<'tcx> {
pub fn if_<'a, 'gcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>,
t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> {
static BOOL_SWITCH_FALSE: &'static [ConstInt] = &[ConstInt::Infer(0)];
static BOOL_SWITCH_FALSE: &'static [ConstInt] = &[ConstInt::U8(0)];
TerminatorKind::SwitchInt {
discr: cond,
switch_ty: tcx.types.bool,
Expand Down Expand Up @@ -1224,7 +1224,7 @@ pub enum Literal<'tcx> {
substs: &'tcx Substs<'tcx>,
},
Value {
value: ConstVal,
value: ConstVal<'tcx>,
},
Promoted {
// Index into the `promoted` vector of `Mir`.
Expand Down Expand Up @@ -1271,7 +1271,7 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
write!(fmt, "b\"{}\"", escaped)
}
Bool(b) => write!(fmt, "{:?}", b),
Function(def_id) => write!(fmt, "{}", item_path_str(def_id)),
Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
Struct(_) | Tuple(_) | Array(_) | Repeat(..) =>
bug!("ConstVal `{:?}` should not be in MIR", const_val),
Char(c) => write!(fmt, "{:?}", c),
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ pub struct TypeckTables<'tcx> {
/// Set of trait imports actually used in the method resolution.
/// This is used for warning unused imports.
pub used_trait_imports: DefIdSet,

/// If any errors occurred while type-checking this body,
/// this field will be set to `true`.
pub tainted_by_errors: bool,
}

impl<'tcx> TypeckTables<'tcx> {
Expand All @@ -262,6 +266,7 @@ impl<'tcx> TypeckTables<'tcx> {
cast_kinds: NodeMap(),
lints: lint::LintTable::new(),
used_trait_imports: DefIdSet(),
tainted_by_errors: false,
}
}

Expand Down
7 changes: 1 addition & 6 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
use syntax::ast::{FloatTy, IntTy, UintTy};
use syntax::attr;
use syntax_pos::DUMMY_SP;
use rustc_const_math::ConstInt;

use std::cmp;
use std::fmt;
Expand Down Expand Up @@ -1183,11 +1182,7 @@ impl<'a, 'gcx, 'tcx> Layout {
i64::min_value(),
true);
for discr in def.discriminants(tcx) {
let x = match discr.erase_type() {
ConstInt::InferSigned(i) => i as i64,
ConstInt::Infer(i) => i as u64 as i64,
_ => bug!()
};
let x = discr.to_u128_unchecked() as i64;
if x == 0 { non_zero = false; }
if x < min { min = x; }
if x > max { max = x; }
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ define_maps! { <'tcx>

/// Results of evaluating monomorphic constants embedded in
/// other items, such as enum variant explicit discriminants.
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal, ()>
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>
}

fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
Expand Down
56 changes: 31 additions & 25 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,35 @@ type Disr = ConstInt;
}


macro_rules! typed_literal {
($tcx:expr, $ty:expr, $lit:expr) => {
match $ty {
SignedInt(ast::IntTy::I8) => ConstInt::I8($lit),
SignedInt(ast::IntTy::I16) => ConstInt::I16($lit),
SignedInt(ast::IntTy::I32) => ConstInt::I32($lit),
SignedInt(ast::IntTy::I64) => ConstInt::I64($lit),
SignedInt(ast::IntTy::I128) => ConstInt::I128($lit),
SignedInt(ast::IntTy::Is) => match $tcx.sess.target.int_type {
ast::IntTy::I16 => ConstInt::Isize(ConstIsize::Is16($lit)),
ast::IntTy::I32 => ConstInt::Isize(ConstIsize::Is32($lit)),
ast::IntTy::I64 => ConstInt::Isize(ConstIsize::Is64($lit)),
_ => bug!(),
},
UnsignedInt(ast::UintTy::U8) => ConstInt::U8($lit),
UnsignedInt(ast::UintTy::U16) => ConstInt::U16($lit),
UnsignedInt(ast::UintTy::U32) => ConstInt::U32($lit),
UnsignedInt(ast::UintTy::U64) => ConstInt::U64($lit),
UnsignedInt(ast::UintTy::U128) => ConstInt::U128($lit),
UnsignedInt(ast::UintTy::Us) => match $tcx.sess.target.uint_type {
ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16($lit)),
ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32($lit)),
ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64($lit)),
_ => bug!(),
},
}
}
}

impl IntTypeExt for attr::IntType {
fn to_ty<'a, 'gcx, 'tcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
match *self {
Expand All @@ -66,30 +95,7 @@ impl IntTypeExt for attr::IntType {
}

fn initial_discriminant<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Disr {
match *self {
SignedInt(ast::IntTy::I8) => ConstInt::I8(0),
SignedInt(ast::IntTy::I16) => ConstInt::I16(0),
SignedInt(ast::IntTy::I32) => ConstInt::I32(0),
SignedInt(ast::IntTy::I64) => ConstInt::I64(0),
SignedInt(ast::IntTy::I128) => ConstInt::I128(0),
SignedInt(ast::IntTy::Is) => match tcx.sess.target.int_type {
ast::IntTy::I16 => ConstInt::Isize(ConstIsize::Is16(0)),
ast::IntTy::I32 => ConstInt::Isize(ConstIsize::Is32(0)),
ast::IntTy::I64 => ConstInt::Isize(ConstIsize::Is64(0)),
_ => bug!(),
},
UnsignedInt(ast::UintTy::U8) => ConstInt::U8(0),
UnsignedInt(ast::UintTy::U16) => ConstInt::U16(0),
UnsignedInt(ast::UintTy::U32) => ConstInt::U32(0),
UnsignedInt(ast::UintTy::U64) => ConstInt::U64(0),
UnsignedInt(ast::UintTy::U128) => ConstInt::U128(0),
UnsignedInt(ast::UintTy::Us) => match tcx.sess.target.uint_type {
ast::UintTy::U16 => ConstInt::Usize(ConstUsize::Us16(0)),
ast::UintTy::U32 => ConstInt::Usize(ConstUsize::Us32(0)),
ast::UintTy::U64 => ConstInt::Usize(ConstUsize::Us64(0)),
_ => bug!(),
},
}
typed_literal!(tcx, *self, 0)
}

fn assert_ty_matches(&self, val: Disr) {
Expand All @@ -114,7 +120,7 @@ impl IntTypeExt for attr::IntType {
-> Option<Disr> {
if let Some(val) = val {
self.assert_ty_matches(val);
(val + ConstInt::Infer(1)).ok()
(val + typed_literal!(tcx, *self, 1)).ok()
} else {
Some(self.initial_discriminant(tcx))
}
Expand Down
Loading

0 comments on commit e7a4882

Please sign in to comment.