rollup merge of #24921: tamird/bitflags-associated-const
Conflicts: src/librustc/lib.rs
This commit is contained in:
commit
2edb6438cb
24 changed files with 341 additions and 295 deletions
|
|
@ -25,22 +25,23 @@
|
|||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![feature(associated_consts)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(core)]
|
||||
#![feature(fs_canonicalize)]
|
||||
#![feature(hash)]
|
||||
#![feature(into_cow)]
|
||||
#![feature(libc)]
|
||||
#![feature(path_ext)]
|
||||
#![feature(quote)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(std_misc)]
|
||||
#![feature(path_ext)]
|
||||
#![feature(str_char)]
|
||||
#![feature(into_cow)]
|
||||
#![feature(fs_canonicalize)]
|
||||
#![feature(slice_patterns)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
#![allow(trivial_casts)]
|
||||
|
|
|
|||
|
|
@ -46,33 +46,35 @@ bitflags! {
|
|||
#[derive(RustcEncodable, RustcDecodable)]
|
||||
flags ConstQualif: u8 {
|
||||
// Const rvalue which can be placed behind a reference.
|
||||
const PURE_CONST = 0b000000,
|
||||
const PURE_CONST = 0,
|
||||
// Inner mutability (can not be placed behind a reference) or behind
|
||||
// &mut in a non-global expression. Can be copied from static memory.
|
||||
const MUTABLE_MEM = 0b000001,
|
||||
const MUTABLE_MEM = 1 << 0,
|
||||
// Constant value with a type that implements Drop. Can be copied
|
||||
// from static memory, similar to MUTABLE_MEM.
|
||||
const NEEDS_DROP = 0b000010,
|
||||
const NEEDS_DROP = 1 << 1,
|
||||
// Even if the value can be placed in static memory, copying it from
|
||||
// there is more expensive than in-place instantiation, and/or it may
|
||||
// be too large. This applies to [T; N] and everything containing it.
|
||||
// N.B.: references need to clear this flag to not end up on the stack.
|
||||
const PREFER_IN_PLACE = 0b000100,
|
||||
const PREFER_IN_PLACE = 1 << 2,
|
||||
// May use more than 0 bytes of memory, doesn't impact the constness
|
||||
// directly, but is not allowed to be borrowed mutably in a constant.
|
||||
const NON_ZERO_SIZED = 0b001000,
|
||||
const NON_ZERO_SIZED = 1 << 3,
|
||||
// Actually borrowed, has to always be in static memory. Does not
|
||||
// propagate, and requires the expression to behave like a 'static
|
||||
// lvalue. The set of expressions with this flag is the minimum
|
||||
// that have to be promoted.
|
||||
const HAS_STATIC_BORROWS = 0b010000,
|
||||
const HAS_STATIC_BORROWS = 1 << 4,
|
||||
// Invalid const for miscellaneous reasons (e.g. not implemented).
|
||||
const NOT_CONST = 0b100000,
|
||||
const NOT_CONST = 1 << 5,
|
||||
|
||||
// Borrowing the expression won't produce &'static T if any of these
|
||||
// bits are set, though the value could be copied from static memory
|
||||
// if `NOT_CONST` isn't set.
|
||||
const NON_STATIC_BORROWS = MUTABLE_MEM.bits | NEEDS_DROP.bits | NOT_CONST.bits
|
||||
const NON_STATIC_BORROWS = ConstQualif::MUTABLE_MEM.bits |
|
||||
ConstQualif::NEEDS_DROP.bits |
|
||||
ConstQualif::NOT_CONST.bits
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +104,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
|||
{
|
||||
let (old_mode, old_qualif) = (self.mode, self.qualif);
|
||||
self.mode = mode;
|
||||
self.qualif = PURE_CONST;
|
||||
self.qualif = ConstQualif::PURE_CONST;
|
||||
let r = f(self);
|
||||
self.mode = old_mode;
|
||||
self.qualif = old_qualif;
|
||||
|
|
@ -126,7 +128,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
|||
Entry::Occupied(entry) => return *entry.get(),
|
||||
Entry::Vacant(entry) => {
|
||||
// Prevent infinite recursion on re-entry.
|
||||
entry.insert(PURE_CONST);
|
||||
entry.insert(ConstQualif::PURE_CONST);
|
||||
}
|
||||
}
|
||||
self.with_mode(mode, |this| {
|
||||
|
|
@ -271,7 +273,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
|
||||
fn visit_expr(&mut self, ex: &ast::Expr) {
|
||||
let mut outer = self.qualif;
|
||||
self.qualif = PURE_CONST;
|
||||
self.qualif = ConstQualif::PURE_CONST;
|
||||
|
||||
let node_ty = ty::node_id_to_type(self.tcx, ex.id);
|
||||
check_expr(self, ex, node_ty);
|
||||
|
|
@ -287,7 +289,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
self.visit_expr(&**callee);
|
||||
// The callee's size doesn't count in the call.
|
||||
let added = self.qualif - inner;
|
||||
self.qualif = inner | (added - NON_ZERO_SIZED);
|
||||
self.qualif = inner | (added - ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
ast::ExprRepeat(ref element, _) => {
|
||||
self.visit_expr(&**element);
|
||||
|
|
@ -298,7 +300,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
};
|
||||
// [element; 0] is always zero-sized.
|
||||
if count == 0 {
|
||||
self.qualif = self.qualif - (NON_ZERO_SIZED | PREFER_IN_PLACE);
|
||||
self.qualif.remove(ConstQualif::NON_ZERO_SIZED | ConstQualif::PREFER_IN_PLACE);
|
||||
}
|
||||
}
|
||||
ast::ExprMatch(ref discr, ref arms, _) => {
|
||||
|
|
@ -325,7 +327,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
let div_or_rem = op.node == ast::BiDiv || op.node == ast::BiRem;
|
||||
match node_ty.sty {
|
||||
ty::ty_uint(_) | ty::ty_int(_) if div_or_rem => {
|
||||
if !self.qualif.intersects(NOT_CONST) {
|
||||
if !self.qualif.intersects(ConstQualif::NOT_CONST) {
|
||||
match const_eval::eval_const_expr_partial(self.tcx, ex, None) {
|
||||
Ok(_) => {}
|
||||
Err(msg) => {
|
||||
|
|
@ -348,11 +350,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
// Constants cannot be borrowed if they contain interior mutability as
|
||||
// it means that our "silent insertion of statics" could change
|
||||
// initializer values (very bad).
|
||||
// If the type doesn't have interior mutability, then `MUTABLE_MEM` has
|
||||
// If the type doesn't have interior mutability, then `ConstQualif::MUTABLE_MEM` has
|
||||
// propagated from another error, so erroring again would be just noise.
|
||||
let tc = ty::type_contents(self.tcx, node_ty);
|
||||
if self.qualif.intersects(MUTABLE_MEM) && tc.interior_unsafe() {
|
||||
outer = outer | NOT_CONST;
|
||||
if self.qualif.intersects(ConstQualif::MUTABLE_MEM) && tc.interior_unsafe() {
|
||||
outer = outer | ConstQualif::NOT_CONST;
|
||||
if self.mode != Mode::Var {
|
||||
self.tcx.sess.span_err(ex.span,
|
||||
"cannot borrow a constant which contains \
|
||||
|
|
@ -361,32 +363,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
}
|
||||
// If the reference has to be 'static, avoid in-place initialization
|
||||
// as that will end up pointing to the stack instead.
|
||||
if !self.qualif.intersects(NON_STATIC_BORROWS) {
|
||||
self.qualif = self.qualif - PREFER_IN_PLACE;
|
||||
self.add_qualif(HAS_STATIC_BORROWS);
|
||||
if !self.qualif.intersects(ConstQualif::NON_STATIC_BORROWS) {
|
||||
self.qualif = self.qualif - ConstQualif::PREFER_IN_PLACE;
|
||||
self.add_qualif(ConstQualif::HAS_STATIC_BORROWS);
|
||||
}
|
||||
}
|
||||
Some(ast::MutMutable) => {
|
||||
// `&mut expr` means expr could be mutated, unless it's zero-sized.
|
||||
if self.qualif.intersects(NON_ZERO_SIZED) {
|
||||
if self.qualif.intersects(ConstQualif::NON_ZERO_SIZED) {
|
||||
if self.mode == Mode::Var {
|
||||
outer = outer | NOT_CONST;
|
||||
self.add_qualif(MUTABLE_MEM);
|
||||
outer = outer | ConstQualif::NOT_CONST;
|
||||
self.add_qualif(ConstQualif::MUTABLE_MEM);
|
||||
} else {
|
||||
span_err!(self.tcx.sess, ex.span, E0017,
|
||||
"references in {}s may only refer \
|
||||
to immutable values", self.msg())
|
||||
}
|
||||
}
|
||||
if !self.qualif.intersects(NON_STATIC_BORROWS) {
|
||||
self.add_qualif(HAS_STATIC_BORROWS);
|
||||
if !self.qualif.intersects(ConstQualif::NON_STATIC_BORROWS) {
|
||||
self.add_qualif(ConstQualif::HAS_STATIC_BORROWS);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
self.tcx.const_qualif_map.borrow_mut().insert(ex.id, self.qualif);
|
||||
// Don't propagate certain flags.
|
||||
self.qualif = outer | (self.qualif - HAS_STATIC_BORROWS);
|
||||
self.qualif = outer | (self.qualif - ConstQualif::HAS_STATIC_BORROWS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +403,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
match node_ty.sty {
|
||||
ty::ty_struct(did, _) |
|
||||
ty::ty_enum(did, _) if ty::has_dtor(v.tcx, did) => {
|
||||
v.add_qualif(NEEDS_DROP);
|
||||
v.add_qualif(ConstQualif::NEEDS_DROP);
|
||||
if v.mode != Mode::Var {
|
||||
v.tcx.sess.span_err(e.span,
|
||||
&format!("{}s are not allowed to have destructors",
|
||||
|
|
@ -416,7 +418,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
ast::ExprUnary(..) |
|
||||
ast::ExprBinary(..) |
|
||||
ast::ExprIndex(..) if v.tcx.method_map.borrow().contains_key(&method_call) => {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, e.span, E0011,
|
||||
"user-defined operators are not allowed in {}s", v.msg());
|
||||
|
|
@ -424,7 +426,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
}
|
||||
ast::ExprBox(..) |
|
||||
ast::ExprUnary(ast::UnUniq, _) => {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, e.span, E0010,
|
||||
"allocations are not allowed in {}s", v.msg());
|
||||
|
|
@ -434,7 +436,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
match ty::node_id_to_type(v.tcx, ptr.id).sty {
|
||||
ty::ty_ptr(_) => {
|
||||
// This shouldn't be allowed in constants at all.
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -447,7 +449,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
ty::type_is_unsafe_ptr(toty) ||
|
||||
(ty::type_is_bare_fn(toty) && ty::type_is_bare_fn_item(fromty));
|
||||
if !is_legal_cast {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, e.span, E0012,
|
||||
"can not cast to `{}` in {}s",
|
||||
|
|
@ -455,7 +457,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
if ty::type_is_unsafe_ptr(fromty) && ty::type_is_numeric(toty) {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, e.span, E0018,
|
||||
"can not cast a pointer to an integer in {}s", v.msg());
|
||||
|
|
@ -467,17 +469,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
match def {
|
||||
Some(def::DefVariant(_, _, _)) => {
|
||||
// Count the discriminator or function pointer.
|
||||
v.add_qualif(NON_ZERO_SIZED);
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
Some(def::DefStruct(_)) => {
|
||||
if let ty::ty_bare_fn(..) = node_ty.sty {
|
||||
// Count the function pointer.
|
||||
v.add_qualif(NON_ZERO_SIZED);
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
}
|
||||
Some(def::DefFn(..)) | Some(def::DefMethod(..)) => {
|
||||
// Count the function pointer.
|
||||
v.add_qualif(NON_ZERO_SIZED);
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
Some(def::DefStatic(..)) => {
|
||||
match v.mode {
|
||||
|
|
@ -487,7 +489,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
"constants cannot refer to other statics, \
|
||||
insert an intermediate constant instead");
|
||||
}
|
||||
Mode::Var => v.add_qualif(NOT_CONST)
|
||||
Mode::Var => v.add_qualif(ConstQualif::NOT_CONST)
|
||||
}
|
||||
}
|
||||
Some(def::DefConst(did)) |
|
||||
|
|
@ -503,7 +505,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
def => {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
debug!("(checking const) found bad def: {:?}", def);
|
||||
span_err!(v.tcx.sess, e.span, E0014,
|
||||
|
|
@ -530,10 +532,10 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
Some(def::DefStruct(..)) => {}
|
||||
Some(def::DefVariant(..)) => {
|
||||
// Count the discriminator.
|
||||
v.add_qualif(NON_ZERO_SIZED);
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
_ => {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, e.span, E0015,
|
||||
"function calls in {}s are limited to \
|
||||
|
|
@ -545,7 +547,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
ast::ExprBlock(ref block) => {
|
||||
// Check all statements in the block
|
||||
let mut block_span_err = |span| {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, span, E0016,
|
||||
"blocks in {}s are limited to items and \
|
||||
|
|
@ -574,17 +576,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
ast::ExprStruct(..) => {
|
||||
let did = v.tcx.def_map.borrow().get(&e.id).map(|def| def.def_id());
|
||||
if did == v.tcx.lang_items.unsafe_cell_type() {
|
||||
v.add_qualif(MUTABLE_MEM);
|
||||
v.add_qualif(ConstQualif::MUTABLE_MEM);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprLit(_) |
|
||||
ast::ExprAddrOf(..) => {
|
||||
v.add_qualif(NON_ZERO_SIZED);
|
||||
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
|
||||
}
|
||||
|
||||
ast::ExprRepeat(..) => {
|
||||
v.add_qualif(PREFER_IN_PLACE);
|
||||
v.add_qualif(ConstQualif::PREFER_IN_PLACE);
|
||||
}
|
||||
|
||||
ast::ExprClosure(..) => {
|
||||
|
|
@ -593,7 +595,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
if ty::with_freevars(v.tcx, e.id, |fv| !fv.is_empty()) {
|
||||
assert!(v.mode == Mode::Var,
|
||||
"global closures can't capture anything");
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -631,7 +633,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
ast::ExprAssignOp(..) |
|
||||
ast::ExprInlineAsm(_) |
|
||||
ast::ExprMac(_) => {
|
||||
v.add_qualif(NOT_CONST);
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
if v.mode != Mode::Var {
|
||||
span_err!(v.tcx.sess, e.span, E0019,
|
||||
"{} contains unimplemented expression type", v.msg());
|
||||
|
|
@ -644,7 +646,7 @@ pub fn check_crate(tcx: &ty::ctxt) {
|
|||
visit::walk_crate(&mut CheckCrateVisitor {
|
||||
tcx: tcx,
|
||||
mode: Mode::Var,
|
||||
qualif: NOT_CONST,
|
||||
qualif: ConstQualif::NOT_CONST,
|
||||
rvalue_borrows: NodeMap()
|
||||
}, tcx.map.krate());
|
||||
|
||||
|
|
|
|||
|
|
@ -838,20 +838,20 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||
expr_ty: Ty<'tcx>)
|
||||
-> cmt<'tcx> {
|
||||
let qualif = self.tcx().const_qualif_map.borrow().get(&id).cloned()
|
||||
.unwrap_or(check_const::NOT_CONST);
|
||||
.unwrap_or(check_const::ConstQualif::NOT_CONST);
|
||||
|
||||
// Only promote `[T; 0]` before an RFC for rvalue promotions
|
||||
// is accepted.
|
||||
let qualif = match expr_ty.sty {
|
||||
ty::ty_vec(_, Some(0)) => qualif,
|
||||
_ => check_const::NOT_CONST
|
||||
_ => check_const::ConstQualif::NOT_CONST
|
||||
};
|
||||
|
||||
// Compute maximum lifetime of this rvalue. This is 'static if
|
||||
// we can promote to a constant, otherwise equal to enclosing temp
|
||||
// lifetime.
|
||||
let re = match qualif & check_const::NON_STATIC_BORROWS {
|
||||
check_const::PURE_CONST => ty::ReStatic,
|
||||
let re = match qualif & check_const::ConstQualif::NON_STATIC_BORROWS {
|
||||
check_const::ConstQualif::PURE_CONST => ty::ReStatic,
|
||||
_ => self.temporary_scope(id),
|
||||
};
|
||||
let ret = self.cat_rvalue(id, span, re, expr_ty);
|
||||
|
|
|
|||
|
|
@ -848,16 +848,18 @@ impl<'tcx> ctxt<'tcx> {
|
|||
// recursing over the type itself.
|
||||
bitflags! {
|
||||
flags TypeFlags: u32 {
|
||||
const NO_TYPE_FLAGS = 0b0,
|
||||
const HAS_PARAMS = 0b1,
|
||||
const HAS_SELF = 0b10,
|
||||
const HAS_TY_INFER = 0b100,
|
||||
const HAS_RE_INFER = 0b1000,
|
||||
const HAS_RE_LATE_BOUND = 0b10000,
|
||||
const HAS_REGIONS = 0b100000,
|
||||
const HAS_TY_ERR = 0b1000000,
|
||||
const HAS_PROJECTION = 0b10000000,
|
||||
const NEEDS_SUBST = HAS_PARAMS.bits | HAS_SELF.bits | HAS_REGIONS.bits,
|
||||
const NO_TYPE_FLAGS = 0,
|
||||
const HAS_PARAMS = 1 << 0,
|
||||
const HAS_SELF = 1 << 1,
|
||||
const HAS_TY_INFER = 1 << 2,
|
||||
const HAS_RE_INFER = 1 << 3,
|
||||
const HAS_RE_LATE_BOUND = 1 << 4,
|
||||
const HAS_REGIONS = 1 << 5,
|
||||
const HAS_TY_ERR = 1 << 6,
|
||||
const HAS_PROJECTION = 1 << 7,
|
||||
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
|
||||
TypeFlags::HAS_SELF.bits |
|
||||
TypeFlags::HAS_REGIONS.bits,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -890,8 +892,8 @@ macro_rules! sty_debug_print {
|
|||
ty::ty_err => /* unimportant */ continue,
|
||||
$(ty::$variant(..) => &mut $variant,)*
|
||||
};
|
||||
let region = t.flags.intersects(ty::HAS_RE_INFER);
|
||||
let ty = t.flags.intersects(ty::HAS_TY_INFER);
|
||||
let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
|
||||
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
|
||||
|
||||
variant.total += 1;
|
||||
total.total += 1;
|
||||
|
|
@ -993,23 +995,23 @@ impl<'tcx> Borrow<sty<'tcx>> for InternedTy<'tcx> {
|
|||
}
|
||||
|
||||
pub fn type_has_params(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_PARAMS)
|
||||
ty.flags.intersects(TypeFlags::HAS_PARAMS)
|
||||
}
|
||||
pub fn type_has_self(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_SELF)
|
||||
ty.flags.intersects(TypeFlags::HAS_SELF)
|
||||
}
|
||||
pub fn type_has_ty_infer(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_TY_INFER)
|
||||
ty.flags.intersects(TypeFlags::HAS_TY_INFER)
|
||||
}
|
||||
pub fn type_needs_infer(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_TY_INFER | HAS_RE_INFER)
|
||||
ty.flags.intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
pub fn type_has_projection(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_PROJECTION)
|
||||
ty.flags.intersects(TypeFlags::HAS_PROJECTION)
|
||||
}
|
||||
|
||||
pub fn type_has_late_bound_regions(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_RE_LATE_BOUND)
|
||||
ty.flags.intersects(TypeFlags::HAS_RE_LATE_BOUND)
|
||||
}
|
||||
|
||||
/// An "escaping region" is a bound region whose binder is not part of `t`.
|
||||
|
|
@ -2810,7 +2812,7 @@ struct FlagComputation {
|
|||
|
||||
impl FlagComputation {
|
||||
fn new() -> FlagComputation {
|
||||
FlagComputation { flags: NO_TYPE_FLAGS, depth: 0 }
|
||||
FlagComputation { flags: TypeFlags::NO_TYPE_FLAGS, depth: 0 }
|
||||
}
|
||||
|
||||
fn for_sty(st: &sty) -> FlagComputation {
|
||||
|
|
@ -2855,20 +2857,20 @@ impl FlagComputation {
|
|||
|
||||
// You might think that we could just return ty_err for
|
||||
// any type containing ty_err as a component, and get
|
||||
// rid of the HAS_TY_ERR flag -- likewise for ty_bot (with
|
||||
// rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
|
||||
// the exception of function types that return bot).
|
||||
// But doing so caused sporadic memory corruption, and
|
||||
// neither I (tjc) nor nmatsakis could figure out why,
|
||||
// so we're doing it this way.
|
||||
&ty_err => {
|
||||
self.add_flags(HAS_TY_ERR)
|
||||
self.add_flags(TypeFlags::HAS_TY_ERR)
|
||||
}
|
||||
|
||||
&ty_param(ref p) => {
|
||||
if p.space == subst::SelfSpace {
|
||||
self.add_flags(HAS_SELF);
|
||||
self.add_flags(TypeFlags::HAS_SELF);
|
||||
} else {
|
||||
self.add_flags(HAS_PARAMS);
|
||||
self.add_flags(TypeFlags::HAS_PARAMS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2877,7 +2879,7 @@ impl FlagComputation {
|
|||
}
|
||||
|
||||
&ty_infer(_) => {
|
||||
self.add_flags(HAS_TY_INFER)
|
||||
self.add_flags(TypeFlags::HAS_TY_INFER)
|
||||
}
|
||||
|
||||
&ty_enum(_, substs) | &ty_struct(_, substs) => {
|
||||
|
|
@ -2885,7 +2887,7 @@ impl FlagComputation {
|
|||
}
|
||||
|
||||
&ty_projection(ref data) => {
|
||||
self.add_flags(HAS_PROJECTION);
|
||||
self.add_flags(TypeFlags::HAS_PROJECTION);
|
||||
self.add_projection_ty(data);
|
||||
}
|
||||
|
||||
|
|
@ -2949,11 +2951,11 @@ impl FlagComputation {
|
|||
}
|
||||
|
||||
fn add_region(&mut self, r: Region) {
|
||||
self.add_flags(HAS_REGIONS);
|
||||
self.add_flags(TypeFlags::HAS_REGIONS);
|
||||
match r {
|
||||
ty::ReInfer(_) => { self.add_flags(HAS_RE_INFER); }
|
||||
ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
|
||||
ty::ReLateBound(debruijn, _) => {
|
||||
self.add_flags(HAS_RE_LATE_BOUND);
|
||||
self.add_flags(TypeFlags::HAS_RE_LATE_BOUND);
|
||||
self.add_depth(debruijn.depth);
|
||||
}
|
||||
_ => { }
|
||||
|
|
@ -3307,11 +3309,11 @@ pub fn type_is_nil(ty: Ty) -> bool {
|
|||
}
|
||||
|
||||
pub fn type_is_error(ty: Ty) -> bool {
|
||||
ty.flags.intersects(HAS_TY_ERR)
|
||||
ty.flags.intersects(TypeFlags::HAS_TY_ERR)
|
||||
}
|
||||
|
||||
pub fn type_needs_subst(ty: Ty) -> bool {
|
||||
ty.flags.intersects(NEEDS_SUBST)
|
||||
ty.flags.intersects(TypeFlags::NEEDS_SUBST)
|
||||
}
|
||||
|
||||
pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue