use middle::region;
use middle::subst;
use middle::subst::VecPerParamSpace;
-use middle::ty::{self, ToPredicate, Ty};
+use middle::ty::{self, ToPredicate, Ty, HasTypeFlags};
use std::str;
use syntax::abi;
// If there is a closure buried in the type some where, then we
// need to re-convert any def ids (see case 'k', below). That means
// we can't reuse the cached version.
- if !ty::type_has_ty_closure(tt) {
+ if !tt.has_closure_types() {
return tt;
}
}
}
fn fully_normalize<T>(&self, value: &T) -> Result<T,ErrorReported>
- where T : TypeFoldable<'tcx> + ty::HasProjectionTypes
+ where T : TypeFoldable<'tcx> + ty::HasTypeFlags
{
let value =
traits::fully_normalize(self.infcx,
use middle::infer;
use middle::region;
use middle::subst;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty::{Region, ReFree};
use std::cell::{Cell, RefCell};
fn values_str(&self, values: &ValuePairs<'tcx>) -> Option<String>;
- fn expected_found_str<T: fmt::Display + Resolvable<'tcx>>(
+ fn expected_found_str<T: fmt::Display + Resolvable<'tcx> + HasTypeFlags>(
&self,
exp_found: &ty::expected_found<T>)
-> Option<String>;
}
}
- fn expected_found_str<T: fmt::Display + Resolvable<'tcx>>(
+ fn expected_found_str<T: fmt::Display + Resolvable<'tcx> + HasTypeFlags>(
&self,
exp_found: &ty::expected_found<T>)
-> Option<String>
{
let expected = exp_found.expected.resolve(self);
- if expected.contains_error() {
+ if expected.references_error() {
return None;
}
let found = exp_found.found.resolve(self);
- if found.contains_error() {
+ if found.references_error() {
return None;
}
pub trait Resolvable<'tcx> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) -> Self;
- fn contains_error(&self) -> bool;
}
impl<'tcx> Resolvable<'tcx> for Ty<'tcx> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) -> Ty<'tcx> {
infcx.resolve_type_vars_if_possible(self)
}
- fn contains_error(&self) -> bool {
- ty::type_is_error(*self)
- }
}
impl<'tcx> Resolvable<'tcx> for ty::TraitRef<'tcx> {
-> ty::TraitRef<'tcx> {
infcx.resolve_type_vars_if_possible(self)
}
- fn contains_error(&self) -> bool {
- ty::trait_ref_contains_error(self)
- }
}
impl<'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
{
infcx.resolve_type_vars_if_possible(self)
}
-
- fn contains_error(&self) -> bool {
- ty::trait_ref_contains_error(&self.0)
- }
}
fn lifetimes_in_scope(tcx: &ty::ctxt,
//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
//! inferencer knows "so far".
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty_fold;
use middle::ty_fold::TypeFoldable;
use middle::ty_fold::TypeFolder;
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !ty::type_needs_infer(t) && !ty::type_has_erasable_regions(t) {
+ if !t.needs_infer() && !t.has_erasable_regions() {
return t;
}
use middle::subst;
use middle::subst::Substs;
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
use rustc_data_structures::unify::{self, UnificationTable};
let resolved_expected = expected_ty.map(|e_ty| self.resolve_type_vars_if_possible(&e_ty));
- match resolved_expected {
- Some(t) if ty::type_is_error(t) => (),
- _ => {
- let error_str = err.map_or("".to_string(), |t_err| {
- format!(" ({})", t_err)
- });
+ if !resolved_expected.references_error() {
+ let error_str = err.map_or("".to_string(), |t_err| {
+ format!(" ({})", t_err)
+ });
- self.tcx.sess.span_err(sp, &format!("{}{}",
- mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
- error_str));
+ self.tcx.sess.span_err(sp, &format!("{}{}",
+ mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
+ error_str));
- if let Some(err) = err {
- ty::note_and_explain_type_err(self.tcx, err, sp)
- }
+ if let Some(err) = err {
+ ty::note_and_explain_type_err(self.tcx, err, sp)
}
}
}
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
// Don't report an error if actual type is TyError.
- if ty::type_is_error(actual_ty) {
+ if actual_ty.references_error() {
return;
}
// except according to those terms.
use super::{InferCtxt, fixup_err, fres, unresolved_ty, unresolved_int_ty, unresolved_float_ty};
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty_fold::{self, TypeFoldable};
///////////////////////////////////////////////////////////////////////////
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !ty::type_has_ty_infer(t) {
+ if !t.has_infer_types() {
t // micro-optimize -- if there is nothing in this type that this fold affects...
} else {
let t0 = self.infcx.shallow_resolve(t);
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !ty::type_needs_infer(t) {
+ if !t.needs_infer() {
t // micro-optimize -- if there is nothing in this type that this fold affects...
} else {
let t = self.infcx.shallow_resolve(t);
use middle::def::DefFn;
use middle::subst::{Subst, Substs, EnumeratedItems};
use middle::ty::{TransmuteRestriction, ctxt, TyBareFn};
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use std::fmt;
// Simple case: no type parameters involved.
if
- !ty::type_has_params(from) && !ty::type_has_self(from) &&
- !ty::type_has_params(to) && !ty::type_has_self(to)
+ !from.has_param_types() && !from.has_self_ty() &&
+ !to.has_param_types() && !to.has_self_ty()
{
let restriction = TransmuteRestriction {
span: span,
pub use self::ParamSpace::*;
pub use self::RegionSubsts::*;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags, RegionEscape};
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
use std::fmt;
*self.types.get(ty_param_def.space, ty_param_def.index as usize)
}
- pub fn has_regions_escaping_depth(&self, depth: u32) -> bool {
- self.types.iter().any(|&t| ty::type_escapes_depth(t, depth)) || {
- match self.regions {
- ErasedRegions =>
- false,
- NonerasedRegions(ref regions) =>
- regions.iter().any(|r| r.escapes_depth(depth)),
- }
- }
- }
-
pub fn self_ty(&self) -> Option<Ty<'tcx>> {
self.types.get_self().cloned()
}
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !ty::type_needs_subst(t) {
+ if !t.needs_subst() {
return t;
}
/// first case we do not increase the Debruijn index and in the second case we do. The reason
/// is that only in the second case have we passed through a fn binder.
fn shift_regions_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
- debug!("shift_regions(ty={:?}, region_binders_passed={:?}, type_has_escaping_regions={:?})",
- ty, self.region_binders_passed, ty::type_has_escaping_regions(ty));
+ debug!("shift_regions(ty={:?}, region_binders_passed={:?}, has_escaping_regions={:?})",
+ ty, self.region_binders_passed, ty.has_escaping_regions());
- if self.region_binders_passed == 0 || !ty::type_has_escaping_regions(ty) {
+ if self.region_binders_passed == 0 || !ty.has_escaping_regions() {
return ty;
}
use fmt_macros::{Parser, Piece, Position};
use middle::infer::InferCtxt;
-use middle::ty::{self, ToPredicate, ReferencesError, ToPolyTraitRef, TraitRef};
+use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef};
use middle::ty_fold::TypeFoldable;
use std::collections::HashMap;
use std::fmt;
OutputTypeParameterMismatch(ref expected_trait_ref, ref actual_trait_ref, ref e) => {
let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
- if !ty::type_is_error(actual_trait_ref.self_ty()) {
+ if !actual_trait_ref.self_ty().references_error() {
span_err!(infcx.tcx.sess, obligation.cause.span, E0281,
"type mismatch: the type `{}` implements the trait `{}`, \
but the trait `{}` is required ({})",
let trait_ref = data.to_poly_trait_ref();
let self_ty = trait_ref.self_ty();
let all_types = &trait_ref.substs().types;
- if all_types.iter().any(|&t| ty::type_is_error(t)) {
- } else if all_types.iter().any(|&t| ty::type_needs_infer(t)) {
+ if all_types.references_error() {
+ } else if all_types.needs_infer() {
// This is kind of a hack: it frequently happens that some earlier
// error prevents types from being fully inferred, and then we get
// a bunch of uninteresting errors saying something like "<generic
// except according to those terms.
use middle::infer::InferCtxt;
-use middle::ty::{self, RegionEscape, Ty};
+use middle::ty::{self, RegionEscape, Ty, HasTypeFlags};
use std::collections::HashSet;
use std::fmt;
use middle::free_region::FreeRegionMap;
use middle::subst;
-use middle::ty::{self, HasProjectionTypes, Ty};
+use middle::ty::{self, HasTypeFlags, Ty};
use middle::ty_fold::TypeFoldable;
use middle::infer::{self, fixup_err_to_string, InferCtxt};
use std::rc::Rc;
cause: ObligationCause<'tcx>,
value: &T)
-> Result<T, Vec<FulfillmentError<'tcx>>>
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
debug!("normalize_param_env(value={:?})", value);
use middle::infer;
use middle::subst::Subst;
-use middle::ty::{self, ToPredicate, ReferencesError, RegionEscape,
- HasProjectionTypes, ToPolyTraitRef, Ty};
+use middle::ty::{self, ToPredicate, RegionEscape, HasTypeFlags, ToPolyTraitRef, Ty};
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
use syntax::parse::token;
use util::common::FN_OUTPUT_NAME;
cause: ObligationCause<'tcx>,
value: &T)
-> Normalized<'tcx, T>
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
normalize_with_depth(selcx, cause, 0, value)
}
depth: usize,
value: &T)
-> Normalized<'tcx, T>
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
let result = normalizer.fold(value);
}
}
- fn fold<T:TypeFoldable<'tcx> + HasProjectionTypes>(&mut self, value: &T) -> T {
+ fn fold<T:TypeFoldable<'tcx> + HasTypeFlags>(&mut self, value: &T) -> T {
let value = self.selcx.infcx().resolve_type_vars_if_possible(value);
if !value.has_projection_types() {
depth,
obligations);
- if ty::type_has_projection(projected_ty) {
+ if projected_ty.has_projection_types() {
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
let normalized_ty = normalizer.fold(&projected_ty);
use middle::fast_reject;
use middle::subst::{Subst, Substs, TypeSpace};
-use middle::ty::{self, ToPredicate, RegionEscape, ToPolyTraitRef, Ty};
+use middle::ty::{self, ToPredicate, RegionEscape, ToPolyTraitRef, Ty, HasTypeFlags};
use middle::infer;
use middle::infer::{InferCtxt, TypeFreshener};
use middle::ty_fold::TypeFoldable;
stack: &TraitObligationStack<'o, 'tcx>)
-> SelectionResult<'tcx, SelectionCandidate<'tcx>>
{
- if ty::type_is_error(stack.obligation.predicate.0.self_ty()) {
+ if stack.obligation.predicate.0.self_ty().references_error() {
return Ok(Some(ErrorCandidate));
}
match *candidate {
Ok(Some(_)) | Err(_) => true,
Ok(None) => {
- cache_fresh_trait_pred.0.input_types().iter().any(|&t| ty::type_has_ty_infer(t))
+ cache_fresh_trait_pred.0.input_types().has_infer_types()
}
}
}
new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
}
for &ty in fields.init() {
- if ty::type_is_error(ty.subst(tcx, &new_substs)) {
+ if ty.subst(tcx, &new_substs).references_error() {
return Err(Unimplemented);
}
}
}
}
-pub fn type_has_params(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_PARAMS)
-}
-pub fn type_has_self(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_SELF)
-}
-pub fn type_has_ty_infer(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_TY_INFER)
-}
-pub fn type_needs_infer(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
-}
-pub fn type_is_global(ty: Ty) -> bool {
- !ty.flags.get().intersects(TypeFlags::HAS_LOCAL_NAMES)
-}
-pub fn type_has_projection(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_PROJECTION)
-}
-pub fn type_has_ty_closure(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_TY_CLOSURE)
-}
-
-pub fn type_has_erasable_regions(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_RE_EARLY_BOUND |
- TypeFlags::HAS_RE_INFER |
- TypeFlags::HAS_FREE_REGIONS)
-}
-
-/// An "escaping region" is a bound region whose binder is not part of `t`.
-///
-/// So, for example, consider a type like the following, which has two binders:
-///
-/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
-/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
-/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
-///
-/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
-/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
-/// fn type*, that type has an escaping region: `'a`.
-///
-/// Note that what I'm calling an "escaping region" is often just called a "free region". However,
-/// we already use the term "free region". It refers to the regions that we use to represent bound
-/// regions on a fn definition while we are typechecking its body.
-///
-/// To clarify, conceptually there is no particular difference between an "escaping" region and a
-/// "free" region. However, there is a big difference in practice. Basically, when "entering" a
-/// binding level, one is generally required to do some sort of processing to a bound region, such
-/// as replacing it with a fresh/skolemized region, or making an entry in the environment to
-/// represent the scope to which it is attached, etc. An escaping region represents a bound region
-/// for which this processing has not yet been done.
-pub fn type_has_escaping_regions(ty: Ty) -> bool {
- type_escapes_depth(ty, 0)
-}
-
-pub fn type_escapes_depth(ty: Ty, depth: u32) -> bool {
- ty.region_depth > depth
-}
-
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct BareFnTy<'tcx> {
pub unsafety: ast::Unsafety,
pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
impl Region {
- pub fn is_global(&self) -> bool {
- // does this represent a region that can be named in a global
- // way? used in fulfillment caching.
- match *self {
- ty::ReStatic | ty::ReEmpty => true,
- _ => false,
- }
- }
-
pub fn is_bound(&self) -> bool {
match *self {
ty::ReEarlyBound(..) => true,
Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
}
}
-
- // Indicates whether this predicate references only 'global'
- // types/lifetimes that are the same regardless of what fn we are
- // in. This is used for caching. Errs on the side of returning
- // false.
- pub fn is_global(&self) -> bool {
- match *self {
- ty::Predicate::Trait(ref data) => {
- let substs = data.skip_binder().trait_ref.substs;
-
- substs.types.iter().all(|t| ty::type_is_global(t)) && {
- match substs.regions {
- subst::ErasedRegions => true,
- subst::NonerasedRegions(ref r) => r.iter().all(|r| r.is_global()),
- }
- }
- }
-
- _ => {
- false
- }
- }
- }
}
#[derive(Clone, PartialEq, Eq, Hash)]
}
}
-pub fn type_is_error(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::HAS_TY_ERR)
-}
-
-pub fn type_needs_subst(ty: Ty) -> bool {
- ty.flags.get().intersects(TypeFlags::NEEDS_SUBST)
-}
-
-pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
- tref.substs.types.any(|&ty| type_is_error(ty))
-}
-
pub fn type_is_ty_var(ty: Ty) -> bool {
match ty.sty {
TyInfer(TyVar(_)) => true,
return ty.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
}
- assert!(!ty::type_needs_infer(ty));
+ assert!(!ty.needs_infer());
// Fast-path for primitive types
let result = match ty.sty {
ty::BoundCopy,
span));
- if !type_has_params(ty) && !type_has_self(ty) {
+ if !ty.has_param_types() && !ty.has_self_ty() {
ty.flags.set(ty.flags.get() | if result {
TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
} else {
tcx: &ty::ctxt<'tcx>,
span: Span,
ty: Ty<'tcx>) -> bool {
- assert!(!ty::type_needs_infer(ty));
+ assert!(!ty.needs_infer());
// Fast-path for primitive types
let result = match ty.sty {
TyInfer(..) | TyError => None
}.unwrap_or_else(|| type_impls_bound(param_env, tcx, ty, ty::BoundSized, span));
- if !type_has_params(ty) && !type_has_self(ty) {
+ if !ty.has_param_types() && !ty.has_self_ty() {
ty.flags.set(ty.flags.get() | if result {
TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
} else {
AdjustDerefRef(ref adj) => {
let mut adjusted_ty = unadjusted_ty;
- if !ty::type_is_error(adjusted_ty) {
+ if !adjusted_ty.references_error() {
for i in 0..adj.autoderefs {
let method_call = MethodCall::autoderef(expr_id, i as u32);
match method_type(method_call) {
Ok(())
}
-// FIXME(#20298) -- all of these types basically walk various
+// FIXME(#20298) -- all of these traits basically walk various
// structures to test whether types/regions are reachable with various
// properties. It should be possible to express them in terms of one
// common "walker" trait or something.
+/// An "escaping region" is a bound region whose binder is not part of `t`.
+///
+/// So, for example, consider a type like the following, which has two binders:
+///
+/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
+/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
+/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
+///
+/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
+/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
+/// fn type*, that type has an escaping region: `'a`.
+///
+/// Note that what I'm calling an "escaping region" is often just called a "free region". However,
+/// we already use the term "free region". It refers to the regions that we use to represent bound
+/// regions on a fn definition while we are typechecking its body.
+///
+/// To clarify, conceptually there is no particular difference between an "escaping" region and a
+/// "free" region. However, there is a big difference in practice. Basically, when "entering" a
+/// binding level, one is generally required to do some sort of processing to a bound region, such
+/// as replacing it with a fresh/skolemized region, or making an entry in the environment to
+/// represent the scope to which it is attached, etc. An escaping region represents a bound region
+/// for which this processing has not yet been done.
pub trait RegionEscape {
fn has_escaping_regions(&self) -> bool {
self.has_regions_escaping_depth(0)
impl<'tcx> RegionEscape for Ty<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
- ty::type_escapes_depth(*self, depth)
+ self.region_depth > depth
}
}
}
}
-pub trait HasProjectionTypes {
- fn has_projection_types(&self) -> bool;
-}
-
-impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec<T> {
+pub trait HasTypeFlags {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool;
fn has_projection_types(&self) -> bool {
- self.iter().any(|p| p.has_projection_types())
+ self.has_type_flags(TypeFlags::HAS_PROJECTION)
}
-}
-
-impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
- fn has_projection_types(&self) -> bool {
- self.iter().any(|p| p.has_projection_types())
+ fn references_error(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_TY_ERR)
}
-}
-
-impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.sig.has_projection_types()
+ fn has_param_types(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_PARAMS)
}
-}
-
-impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.ty.has_projection_types()
+ fn has_self_ty(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_SELF)
}
-}
-
-impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.predicates.has_projection_types()
+ fn has_infer_types(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
-}
-
-impl<'tcx> HasProjectionTypes for Predicate<'tcx> {
- fn has_projection_types(&self) -> bool {
- match *self {
- Predicate::Trait(ref data) => data.has_projection_types(),
- Predicate::Equate(ref data) => data.has_projection_types(),
- Predicate::RegionOutlives(ref data) => data.has_projection_types(),
- Predicate::TypeOutlives(ref data) => data.has_projection_types(),
- Predicate::Projection(ref data) => data.has_projection_types(),
- }
+ fn needs_infer(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
}
-}
-
-impl<'tcx> HasProjectionTypes for TraitPredicate<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.trait_ref.has_projection_types()
+ fn needs_subst(&self) -> bool {
+ self.has_type_flags(TypeFlags::NEEDS_SUBST)
}
-}
-
-impl<'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.0.has_projection_types() || self.1.has_projection_types()
+ fn has_closure_types(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
}
-}
-
-impl HasProjectionTypes for Region {
- fn has_projection_types(&self) -> bool {
- false
+ fn has_erasable_regions(&self) -> bool {
+ self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND |
+ TypeFlags::HAS_RE_INFER |
+ TypeFlags::HAS_FREE_REGIONS)
}
-}
-
-impl<T:HasProjectionTypes,U:HasProjectionTypes> HasProjectionTypes for OutlivesPredicate<T,U> {
- fn has_projection_types(&self) -> bool {
- self.0.has_projection_types() || self.1.has_projection_types()
+ /// Indicates whether this value references only 'global'
+ /// types/lifetimes that are the same regardless of what fn we are
+ /// in. This is used for caching. Errs on the side of returning
+ /// false.
+ fn is_global(&self) -> bool {
+ !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
}
}
-impl<'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.projection_ty.has_projection_types() || self.ty.has_projection_types()
+impl<'tcx,T:HasTypeFlags> HasTypeFlags for Vec<T> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self[..].has_type_flags(flags)
}
}
-impl<'tcx> HasProjectionTypes for ProjectionTy<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.trait_ref.has_projection_types()
+impl<'tcx,T:HasTypeFlags> HasTypeFlags for [T] {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.iter().any(|p| p.has_type_flags(flags))
}
}
-impl<'tcx> HasProjectionTypes for Ty<'tcx> {
- fn has_projection_types(&self) -> bool {
- ty::type_has_projection(*self)
+impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace<T> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.iter().any(|p| p.has_type_flags(flags))
}
}
-impl<'tcx> HasProjectionTypes for TraitRef<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.substs.has_projection_types()
+impl<'tcx> HasTypeFlags for ClosureTy<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.sig.has_type_flags(flags)
}
}
-impl<'tcx> HasProjectionTypes for subst::Substs<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.types.iter().any(|t| t.has_projection_types())
+impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.ty.has_type_flags(flags)
}
}
-impl<'tcx,T> HasProjectionTypes for Option<T>
- where T : HasProjectionTypes
-{
- fn has_projection_types(&self) -> bool {
- self.iter().any(|t| t.has_projection_types())
+impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.predicates.has_type_flags(flags)
}
}
-impl<'tcx,T> HasProjectionTypes for Rc<T>
- where T : HasProjectionTypes
-{
- fn has_projection_types(&self) -> bool {
- (**self).has_projection_types()
+impl<'tcx> HasTypeFlags for Predicate<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ match *self {
+ Predicate::Trait(ref data) => data.has_type_flags(flags),
+ Predicate::Equate(ref data) => data.has_type_flags(flags),
+ Predicate::RegionOutlives(ref data) => data.has_type_flags(flags),
+ Predicate::TypeOutlives(ref data) => data.has_type_flags(flags),
+ Predicate::Projection(ref data) => data.has_type_flags(flags),
+ }
}
}
-impl<'tcx,T> HasProjectionTypes for Box<T>
- where T : HasProjectionTypes
-{
- fn has_projection_types(&self) -> bool {
- (**self).has_projection_types()
+impl<'tcx> HasTypeFlags for TraitPredicate<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.trait_ref.has_type_flags(flags)
}
}
-impl<T> HasProjectionTypes for Binder<T>
- where T : HasProjectionTypes
-{
- fn has_projection_types(&self) -> bool {
- self.0.has_projection_types()
+impl<'tcx> HasTypeFlags for EquatePredicate<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.0.has_type_flags(flags) || self.1.has_type_flags(flags)
}
}
-impl<'tcx> HasProjectionTypes for FnOutput<'tcx> {
- fn has_projection_types(&self) -> bool {
- match *self {
- FnConverging(t) => t.has_projection_types(),
- FnDiverging => false,
+impl HasTypeFlags for Region {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ if flags.intersects(TypeFlags::HAS_LOCAL_NAMES) {
+ // does this represent a region that cannot be named in a global
+ // way? used in fulfillment caching.
+ match *self {
+ ty::ReStatic | ty::ReEmpty => {}
+ _ => return true
+ }
}
+ if flags.intersects(TypeFlags::HAS_RE_INFER) {
+ if let ty::ReInfer(_) = *self {
+ return true;
+ }
+ }
+ false
}
}
-impl<'tcx> HasProjectionTypes for FnSig<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.inputs.iter().any(|t| t.has_projection_types()) ||
- self.output.has_projection_types()
+impl<T:HasTypeFlags,U:HasTypeFlags> HasTypeFlags for OutlivesPredicate<T,U> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.0.has_type_flags(flags) || self.1.has_type_flags(flags)
}
}
-impl<'tcx> HasProjectionTypes for field<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.mt.ty.has_projection_types()
+impl<'tcx> HasTypeFlags for ProjectionPredicate<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.projection_ty.has_type_flags(flags) || self.ty.has_type_flags(flags)
}
}
-impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> {
- fn has_projection_types(&self) -> bool {
- self.sig.has_projection_types()
+impl<'tcx> HasTypeFlags for ProjectionTy<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.trait_ref.has_type_flags(flags)
}
}
-pub trait ReferencesError {
- fn references_error(&self) -> bool;
+impl<'tcx> HasTypeFlags for Ty<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.flags.get().intersects(flags)
+ }
}
-impl<T:ReferencesError> ReferencesError for Binder<T> {
- fn references_error(&self) -> bool {
- self.0.references_error()
+impl<'tcx> HasTypeFlags for TraitRef<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.substs.has_type_flags(flags)
}
}
-impl<T:ReferencesError> ReferencesError for Rc<T> {
- fn references_error(&self) -> bool {
- (&**self).references_error()
+impl<'tcx> HasTypeFlags for subst::Substs<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.types.has_type_flags(flags) || match self.regions {
+ subst::ErasedRegions => false,
+ subst::NonerasedRegions(ref r) => r.has_type_flags(flags)
+ }
}
}
-impl<'tcx> ReferencesError for TraitPredicate<'tcx> {
- fn references_error(&self) -> bool {
- self.trait_ref.references_error()
+impl<'tcx,T> HasTypeFlags for Option<T>
+ where T : HasTypeFlags
+{
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.iter().any(|t| t.has_type_flags(flags))
}
}
-impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> {
- fn references_error(&self) -> bool {
- self.projection_ty.trait_ref.references_error() || self.ty.references_error()
+impl<'tcx,T> HasTypeFlags for Rc<T>
+ where T : HasTypeFlags
+{
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ (**self).has_type_flags(flags)
}
}
-impl<'tcx> ReferencesError for TraitRef<'tcx> {
- fn references_error(&self) -> bool {
- self.input_types().iter().any(|t| t.references_error())
+impl<'tcx,T> HasTypeFlags for Box<T>
+ where T : HasTypeFlags
+{
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ (**self).has_type_flags(flags)
}
}
-impl<'tcx> ReferencesError for Ty<'tcx> {
- fn references_error(&self) -> bool {
- type_is_error(*self)
+impl<T> HasTypeFlags for Binder<T>
+ where T : HasTypeFlags
+{
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.0.has_type_flags(flags)
}
}
-impl<'tcx> ReferencesError for Predicate<'tcx> {
- fn references_error(&self) -> bool {
+impl<'tcx> HasTypeFlags for FnOutput<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
match *self {
- Predicate::Trait(ref data) => data.references_error(),
- Predicate::Equate(ref data) => data.references_error(),
- Predicate::RegionOutlives(ref data) => data.references_error(),
- Predicate::TypeOutlives(ref data) => data.references_error(),
- Predicate::Projection(ref data) => data.references_error(),
+ FnConverging(t) => t.has_type_flags(flags),
+ FnDiverging => false,
}
}
}
-impl<A,B> ReferencesError for OutlivesPredicate<A,B>
- where A : ReferencesError, B : ReferencesError
-{
- fn references_error(&self) -> bool {
- self.0.references_error() || self.1.references_error()
+impl<'tcx> HasTypeFlags for FnSig<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.inputs.iter().any(|t| t.has_type_flags(flags)) ||
+ self.output.has_type_flags(flags)
}
}
-impl<'tcx> ReferencesError for EquatePredicate<'tcx>
-{
- fn references_error(&self) -> bool {
- self.0.references_error() || self.1.references_error()
+impl<'tcx> HasTypeFlags for field<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.mt.ty.has_type_flags(flags)
}
}
-impl ReferencesError for Region
-{
- fn references_error(&self) -> bool {
- false
+impl<'tcx> HasTypeFlags for BareFnTy<'tcx> {
+ fn has_type_flags(&self, flags: TypeFlags) -> bool {
+ self.sig.has_type_flags(flags)
}
}
use middle::subst;
use middle::subst::VecPerParamSpace;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags, RegionEscape};
use middle::traits;
use std::fmt;
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !ty::type_escapes_depth(t, self.current_depth-1) {
+ if !t.has_regions_escaping_depth(self.current_depth-1) {
return t;
}
fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx }
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
- if !ty::type_has_erasable_regions(t) {
+ if !t.has_erasable_regions() {
return t;
}
use middle::ty::{ReEarlyBound, BrFresh, ctxt};
use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
use middle::ty::{ReSkolemized, ReVar, BrEnv};
-use middle::ty::{mt, Ty};
use middle::ty::{TyBool, TyChar, TyStruct, TyEnum};
use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn};
use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple};
use middle::ty::TyClosure;
use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
-use middle::ty;
+use middle::ty::{self, mt, Ty, HasTypeFlags};
use middle::ty_fold::{self, TypeFoldable};
use std::fmt;
ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
match def.default {
Some(default) => {
- if !has_self && ty::type_has_self(default) {
+ if !has_self && default.has_self_ty() {
// In an object type, there is no `Self`, and
// thus if the default value references Self,
// the user will be required to give an
use rustc_typeck::middle::stability;
use rustc_typeck::middle::subst;
use rustc_typeck::middle::subst::Subst;
-use rustc_typeck::middle::ty::{self, Ty};
+use rustc_typeck::middle::ty::{self, Ty, RegionEscape};
use rustc_typeck::middle::ty_relate::TypeRelation;
use rustc_typeck::middle::infer;
use rustc_typeck::middle::infer::lub::Lub;
// Situation:
// Theta = [A -> &'a foo]
- assert!(!ty::type_has_escaping_regions(env.t_nil()));
+ assert!(!env.t_nil().has_escaping_regions());
let t_rptr_free1 = env.t_rptr_free(0, 1);
- assert!(!ty::type_has_escaping_regions(t_rptr_free1));
+ assert!(!t_rptr_free1.has_escaping_regions());
let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1));
- assert!(ty::type_has_escaping_regions(t_rptr_bound1));
+ assert!(t_rptr_bound1.has_escaping_regions());
let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(2));
- assert!(ty::type_has_escaping_regions(t_rptr_bound2));
+ assert!(t_rptr_bound2.has_escaping_regions());
// t_fn = fn(A)
let t_param = env.t_param(subst::TypeSpace, 0);
- assert!(!ty::type_has_escaping_regions(t_param));
+ assert!(!t_param.has_escaping_regions());
let t_fn = env.t_fn(&[t_param], env.t_nil());
- assert!(!ty::type_has_escaping_regions(t_fn));
+ assert!(!t_fn.has_escaping_regions());
})
}
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
use middle::weak_lang_items;
use middle::subst::Substs;
-use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size};
+use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size, HasTypeFlags};
use rustc::ast_map;
use session::config::{self, NoDebugInfo};
use session::Session;
let _icx = push_ctxt("alloc_ty");
let ccx = bcx.ccx();
let ty = type_of::type_of(ccx, t);
- assert!(!ty::type_has_params(t));
+ assert!(!t.has_param_types());
let val = alloca(bcx, ty, name);
return val;
}
use trans::monomorphize;
use trans::type_::Type;
use trans::type_of;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags, RegionEscape};
use middle::ty::MethodCall;
use rustc::ast_map;
param_substs,
substs);
- assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
- assert!(substs.types.all(|t| !ty::type_has_escaping_regions(*t)));
+ assert!(!substs.types.needs_infer());
+ assert!(!substs.types.has_escaping_regions());
let substs = substs.erase_regions();
// Load the info for the appropriate trait if necessary.
use trans::type_::Type;
use trans::type_of;
use middle::traits;
-use middle::ty::{self, HasProjectionTypes, Ty};
+use middle::ty::{self, HasTypeFlags, Ty};
use middle::ty_fold;
use middle::ty_fold::{TypeFolder, TypeFoldable};
use rustc::ast_map::{PathElem, PathName};
pub type ExternMap = FnvHashMap<String, ValueRef>;
pub fn validate_substs(substs: &Substs) {
- assert!(substs.types.all(|t| !ty::type_needs_infer(*t)));
+ assert!(!substs.types.needs_infer());
}
// work around bizarre resolve errors
}
pub fn monomorphize<T>(&self, value: &T) -> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
monomorphize::apply_param_substs(self.ccx.tcx(),
self.param_substs,
}
pub fn monomorphize<T>(&self, value: &T) -> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
monomorphize::apply_param_substs(self.tcx(),
self.fcx.param_substs,
}
};
- if substs.types.any(|t| ty::type_needs_infer(*t)) {
+ if substs.types.needs_infer() {
tcx.sess.bug(&format!("type parameters for node {:?} include inference types: {:?}",
node, substs));
}
use trans::machine;
use trans::machine::llsize_of;
use trans::type_::Type;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use syntax::abi::RustIntrinsic;
use syntax::ast;
use syntax::parse::token;
debug!("transmute_restriction: {:?}", transmute_restriction);
- assert!(!ty::type_has_params(transmute_restriction.substituted_from));
- assert!(!ty::type_has_params(transmute_restriction.substituted_to));
+ assert!(!transmute_restriction.substituted_from.has_param_types());
+ assert!(!transmute_restriction.substituted_to.has_param_types());
let llfromtype = type_of::sizing_type_of(ccx,
transmute_restriction.substituted_from);
use trans::monomorphize;
use trans::type_::Type;
use trans::type_of::*;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty::MethodCall;
use syntax::abi::{Rust, RustCall};
substs: impl_substs,
nested: _ }) =>
{
- assert!(impl_substs.types.all(|t| !ty::type_needs_infer(*t)));
+ assert!(!impl_substs.types.needs_infer());
// Create the substitutions that are in scope. This combines
// the type parameters from the impl with those declared earlier.
use trans::common::*;
use trans::declare;
use trans::foreign;
-use middle::ty::{self, HasProjectionTypes, Ty};
+use middle::ty::{self, HasTypeFlags, Ty};
use syntax::abi;
use syntax::ast;
psubsts,
ref_id);
- assert!(psubsts.types.all(|t| {
- !ty::type_needs_infer(*t) && !ty::type_has_params(*t)
- }));
+ assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types());
let _icx = push_ctxt("monomorphic_fn");
param_substs: &Substs<'tcx>,
value: &T)
-> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
let substituted = value.subst(tcx, param_substs);
normalize_associated_type(tcx, &substituted)
/// and hence we can be sure that all associated types will be
/// completely normalized away.
pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
debug!("normalize_associated_type(t={:?})", value);
use middle::privacy::{AllPublic, LastMod};
use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
use middle::traits;
-use middle::ty::{self, RegionEscape, Ty, ToPredicate};
+use middle::ty::{self, RegionEscape, Ty, ToPredicate, HasTypeFlags};
use middle::ty_fold;
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, ExplicitRscope,
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
// other type parameters may reference `Self` in their
// defaults. This will lead to an ICE if we are not
// careful!
- if self_ty.is_none() && ty::type_has_self(default) {
+ if self_ty.is_none() && default.has_self_ty() {
span_err!(tcx.sess, span, E0393,
"the type parameter `{}` must be explicitly specified \
in an object type because its default value `{}` references \
use middle::pat_util::pat_is_resolved_const;
use middle::privacy::{AllPublic, LastMod};
use middle::subst::Substs;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use check::{check_expr, check_expr_has_type, check_expr_with_expectation};
use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation};
use check::{check_expr_with_lvalue_pref, LvaluePreference};
check_expr_has_type(fcx, &**e, tcx.types.bool);
}
- if ty::type_is_error(result_ty) || ty::type_is_error(bty) {
+ if result_ty.references_error() || bty.references_error() {
tcx.types.err
} else {
let (origin, expected, found) = match match_src {
use middle::infer::InferCtxt;
use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation,
SelectionContext, ObligationCause};
-use middle::ty::{self, HasProjectionTypes};
+use middle::ty::{self, HasTypeFlags};
use middle::ty_fold::TypeFoldable;
use syntax::ast;
use syntax::codemap::Span;
body_id: ast::NodeId,
value: &T)
-> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
debug!("normalize_associated_types_in(value={:?})", value);
let mut selcx = SelectionContext::new(infcx, typer);
use lint;
use middle::cast::{CastKind, CastTy};
-use middle::ty;
-use middle::ty::Ty;
+use middle::ty::{self, Ty, HasTypeFlags};
use syntax::ast;
use syntax::ast::UintTy::{TyU8};
use syntax::codemap::Span;
debug!("check_cast({}, {:?} as {:?})", self.expr.id, self.expr_ty,
self.cast_ty);
- if ty::type_is_error(self.expr_ty) || ty::type_is_error(self.cast_ty) {
+ if self.expr_ty.references_error() || self.cast_ty.references_error() {
// No sense in giving duplicate error messages
} else if self.try_coercion_cast(fcx) {
self.trivial_cast_lint(fcx);
use middle::subst::Subst;
use middle::traits;
use middle::ty::{self, RegionEscape, Ty, ToPolyTraitRef, TraitRef};
+use middle::ty::HasTypeFlags;
use middle::ty_fold::TypeFoldable;
use middle::infer;
use middle::infer::InferCtxt;
// artifacts. This means it is safe to put into the
// `WhereClauseCandidate` and (eventually) into the
// `WhereClausePick`.
- assert!(trait_ref.substs.types.iter().all(|&t| !ty::type_needs_infer(t)));
+ assert!(!trait_ref.substs.types.needs_infer());
this.inherent_candidates.push(Candidate {
xform_self_ty: xform_self_ty,
fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'tcx>> {
debug!("pick_step: step={:?}", step);
- if ty::type_is_error(step.self_ty) {
+ if step.self_ty.references_error() {
return None;
}
// inference variables or other artifacts. This
// means they are safe to put into the
// `WhereClausePick`.
- assert!(trait_ref.substs().types.iter().all(|&t| !ty::type_needs_infer(t)));
+ assert!(!trait_ref.substs().types.needs_infer());
WhereClausePick((*trait_ref).clone(), index)
}
use astconv::AstConv;
use check::{self, FnCtxt};
-use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate};
+use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, HasTypeFlags};
use middle::def;
use middle::lang_items::FnOnceTraitLangItem;
use middle::subst::Substs;
error: MethodError<'tcx>)
{
// avoid suggestions when we don't know what's going on.
- if ty::type_is_error(rcvr_ty) {
+ if rcvr_ty.references_error() {
return
}
use middle::traits::{self, report_fulfillment_errors};
use middle::ty::{FnSig, GenericPredicates, TypeScheme};
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
-use middle::ty::{self, HasProjectionTypes, RegionEscape, ToPolyTraitRef, Ty};
+use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
use middle::ty::liberate_late_bound_regions;
use middle::ty::{MethodCall, MethodCallee, MethodMap};
use middle::ty_fold::{TypeFolder, TypeFoldable};
body_id: ast::NodeId,
value: &T)
-> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
assoc::normalize_associated_types_in(&self.infcx,
fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
debug!("resolve_type_vars_if_possible(ty={:?})", ty);
- // No ty::infer()? Nothing needs doing.
- if !ty::type_has_ty_infer(ty) {
+ // No TyInfer()? Nothing needs doing.
+ if !ty.has_infer_types() {
debug!("resolve_type_vars_if_possible: ty={:?}", ty);
return ty;
}
// If `ty` is a type variable, see whether we already know what it is.
ty = self.infcx().resolve_type_vars_if_possible(&ty);
- if !ty::type_has_ty_infer(ty) {
+ if !ty.has_infer_types() {
debug!("resolve_type_vars_if_possible: ty={:?}", ty);
return ty;
}
// If not, try resolving any new fcx obligations that have cropped up.
self.select_new_obligations();
ty = self.infcx().resolve_type_vars_if_possible(&ty);
- if !ty::type_has_ty_infer(ty) {
+ if !ty.has_infer_types() {
debug!("resolve_type_vars_if_possible: ty={:?}", ty);
return ty;
}
/// main checking when doing a second pass before writeback. The
/// justification is that writeback will produce an error for
/// these unconstrained type variables.
- fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult<Ty<'tcx>> {
- let t = self.infcx().resolve_type_vars_if_possible(t);
- if ty::type_has_ty_infer(t) || ty::type_is_error(t) { Err(()) } else { Ok(t) }
+ fn resolve_type_vars_or_error(&self, ty: &Ty<'tcx>) -> mc::McResult<Ty<'tcx>> {
+ let ty = self.infcx().resolve_type_vars_if_possible(ty);
+ if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) }
}
fn record_deferred_call_resolution(&self,
substs: &Substs<'tcx>,
value: &T)
-> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
let value = value.subst(self.tcx(), substs);
let result = self.normalize_associated_types_in(span, &value);
fn normalize_associated_types_in<T>(&self, span: Span, value: &T) -> T
- where T : TypeFoldable<'tcx> + HasProjectionTypes
+ where T : TypeFoldable<'tcx> + HasTypeFlags
{
self.inh.normalize_associated_types_in(self, span, self.body_id, value)
}
fcx.resolve_type_vars_if_possible(t)
}
};
- if ty::type_is_error(resolved_t) {
+ if resolved_t.references_error() {
return (resolved_t, autoderefs, None);
}
tuple_arguments: TupleArgumentsFlag,
expected: Expectation<'tcx>)
-> ty::FnOutput<'tcx> {
- if ty::type_is_error(method_fn_ty) {
+ if method_fn_ty.references_error() {
let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
let err_inputs = match tuple_arguments {
/// Invariant:
/// If an expression has any sub-expressions that result in a type error,
-/// inspecting that expression's type with `ty::type_is_error` will return
+/// inspecting that expression's type with `ty.references_error()` will return
/// true. Likewise, if an expression is known to diverge, inspecting its
/// type with `ty::type_is_bot` will return true (n.b.: since Rust is
/// strict, _|_ can appear in the type of an expression that does not,
};
let cond_ty = fcx.expr_ty(cond_expr);
- let if_ty = if ty::type_is_error(cond_ty) {
+ let if_ty = if cond_ty.references_error() {
fcx.tcx().types.err
} else {
branches_ty
fields,
base_expr.is_none(),
None);
- if ty::type_is_error(fcx.node_ty(id)) {
+ if fcx.node_ty(id).references_error() {
struct_type = tcx.types.err;
}
fcx, &**oprnd, expected_inner, lvalue_pref);
let mut oprnd_t = fcx.expr_ty(&**oprnd);
- if !ty::type_is_error(oprnd_t) {
+ if !oprnd_t.references_error() {
match unop {
ast::UnUniq => {
oprnd_t = ty::mk_uniq(tcx, oprnd_t);
lvalue_pref);
let tm = ty::mt { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
- let oprnd_t = if ty::type_is_error(tm.ty) {
+ let oprnd_t = if tm.ty.references_error() {
tcx.types.err
} else {
// Note: at this point, we cannot say what the best lifetime
fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
- if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) {
+ if lhs_ty.references_error() || rhs_ty.references_error() {
fcx.write_error(id);
} else {
fcx.write_nil(id);
check_block_no_value(fcx, &**body);
let cond_ty = fcx.expr_ty(&**cond);
let body_ty = fcx.node_ty(body.id);
- if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) {
+ if cond_ty.references_error() || body_ty.references_error() {
fcx.write_error(id);
}
else {
let arg_tys = args.iter().map(|a| fcx.expr_ty(&**a));
let args_err = arg_tys.fold(false,
|rest_err, a| {
- rest_err || ty::type_is_error(a)});
+ rest_err || a.references_error()});
if args_err {
fcx.write_error(id);
}
let t_expr = fcx.expr_ty(e);
// Eagerly check for some obvious errors.
- if ty::type_is_error(t_expr) {
+ if t_expr.references_error() {
fcx.write_error(id);
} else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
ty::BoundCopy);
}
- if ty::type_is_error(element_ty) {
+ if element_ty.references_error() {
fcx.write_error(id);
} else {
let t = ty::mk_vec(tcx, t, Some(count));
fcx.expr_ty(&**e)
}
};
- err_field = err_field || ty::type_is_error(t);
+ err_field = err_field || t.references_error();
t
}).collect();
if err_field {
// the resulting structure type. This is needed to handle type
// parameters correctly.
let actual_structure_type = fcx.expr_ty(&*expr);
- if !ty::type_is_error(actual_structure_type) {
+ if !actual_structure_type.references_error() {
let type_and_substs = fcx.instantiate_struct_literal_ty(struct_id, path);
match fcx.mk_subty(false,
infer::Misc(path.span),
let base_t = fcx.expr_ty(&**base);
let idx_t = fcx.expr_ty(&**idx);
- if ty::type_is_error(base_t) {
+ if base_t.references_error() {
fcx.write_ty(id, base_t);
- } else if ty::type_is_error(idx_t) {
+ } else if idx_t.references_error() {
fcx.write_ty(id, idx_t);
} else {
let base_t = structurally_resolved_type(fcx, expr.span, base_t);
(Some(ty), None) | (None, Some(ty)) => {
Some(ty)
}
- (Some(t_start), Some(t_end)) if (ty::type_is_error(t_start) ||
- ty::type_is_error(t_end)) => {
+ (Some(t_start), Some(t_end)) if (t_start.references_error() ||
+ t_end.references_error()) => {
Some(fcx.tcx().types.err)
}
(Some(t_start), Some(t_end)) => {
// some bounds, then we'll need to check `t_start` against them here.
let range_type = match idx_type {
- Some(idx_type) if ty::type_is_error(idx_type) => {
+ Some(idx_type) if idx_type.references_error() => {
fcx.tcx().types.err
}
Some(idx_type) => {
node_id: ast::NodeId) -> bool {
match def {
def::DefAssociatedConst(..) => {
- if ty::type_has_params(ty) || ty::type_has_self(ty) {
+ if ty.has_param_types() || ty.has_self_ty() {
span_err!(fcx.sess(), span, E0329,
"Associated consts cannot depend \
on type parameters or Self.");
if let Some(ref init) = local.init {
check_decl_initializer(fcx, local, &**init);
let init_ty = fcx.expr_ty(&**init);
- if ty::type_is_error(init_ty) {
+ if init_ty.references_error() {
fcx.write_ty(local.id, init_ty);
}
}
};
_match::check_pat(&pcx, &*local.pat, t);
let pat_ty = fcx.node_ty(local.pat.id);
- if ty::type_is_error(pat_ty) {
+ if pat_ty.references_error() {
fcx.write_ty(local.id, pat_ty);
}
}
check_decl_local(fcx, &**l);
let l_t = fcx.node_ty(l.id);
saw_bot = saw_bot || fcx.infcx().type_var_diverges(l_t);
- saw_err = saw_err || ty::type_is_error(l_t);
+ saw_err = saw_err || l_t.references_error();
}
ast::DeclItem(_) => {/* ignore for now */ }
}
check_expr_has_type(fcx, &**expr, ty::mk_nil(fcx.tcx()));
let expr_ty = fcx.expr_ty(&**expr);
saw_bot = saw_bot || fcx.infcx().type_var_diverges(expr_ty);
- saw_err = saw_err || ty::type_is_error(expr_ty);
+ saw_err = saw_err || expr_ty.references_error();
}
ast::StmtSemi(ref expr, id) => {
node_id = id;
check_expr(fcx, &**expr);
let expr_ty = fcx.expr_ty(&**expr);
saw_bot |= fcx.infcx().type_var_diverges(expr_ty);
- saw_err |= ty::type_is_error(expr_ty);
+ saw_err |= expr_ty.references_error();
}
ast::StmtMac(..) => fcx.ccx.tcx.sess.bug("unexpanded macro")
}
pub fn check_block_no_value<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, blk: &'tcx ast::Block) {
check_block_with_expected(fcx, blk, ExpectHasType(ty::mk_nil(fcx.tcx())));
let blkty = fcx.node_ty(blk.id);
- if ty::type_is_error(blkty) {
+ if blkty.references_error() {
fcx.write_error(blk.id);
} else {
let nilty = ty::mk_nil(fcx.tcx());
warned = true;
}
any_diverges = any_diverges || fcx.infcx().type_var_diverges(s_ty);
- any_err = any_err || ty::type_is_error(s_ty);
+ any_err = any_err || s_ty.references_error();
}
match blk.expr {
None => if any_err {
pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
let t = ty::node_id_to_type(tcx, id);
- if ty::type_needs_subst(t) {
+ if t.needs_subst() {
span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
return;
}
let alternative = f();
// If not, error.
- if ty::type_is_ty_var(alternative) || ty::type_is_error(alternative) {
+ if ty::type_is_ty_var(alternative) || alternative.references_error() {
fcx.type_error_message(sp, |_actual| {
"the type of this value must be known in this context".to_string()
}, ty, None);
structurally_resolved_type,
};
use middle::traits;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use syntax::ast;
use syntax::ast_util;
use syntax::parse::token;
fcx.write_nil(expr.id);
} else {
// error types are considered "builtin"
- assert!(!ty::type_is_error(lhs_ty) || !ty::type_is_error(rhs_ty));
+ assert!(!lhs_ty.references_error() || !rhs_ty.references_error());
span_err!(tcx.sess, lhs_expr.span, E0368,
"binary assignment operation `{}=` cannot be applied to types `{}` and `{}`",
ast_util::binop_to_string(op.node),
Ok(return_ty) => return_ty,
Err(()) => {
// error types are considered "builtin"
- if !ty::type_is_error(lhs_ty) {
+ if !lhs_ty.references_error() {
span_err!(fcx.tcx().sess, lhs_expr.span, E0369,
"binary operation `{}` cannot be applied to type `{}`",
ast_util::binop_to_string(op.node),
}
BinOpCategory::Shift => {
- ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+ lhs.references_error() || rhs.references_error() ||
ty::type_is_integral(lhs) && ty::type_is_integral(rhs) ||
ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs)
}
BinOpCategory::Math => {
- ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+ lhs.references_error() || rhs.references_error() ||
ty::type_is_integral(lhs) && ty::type_is_integral(rhs) ||
ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) ||
ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs)
}
BinOpCategory::Bitwise => {
- ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+ lhs.references_error() || rhs.references_error() ||
ty::type_is_integral(lhs) && ty::type_is_integral(rhs) ||
ty::type_is_floating_point(lhs) && ty::type_is_floating_point(rhs) ||
ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs) ||
}
BinOpCategory::Comparison => {
- ty::type_is_error(lhs) || ty::type_is_error(rhs) ||
+ lhs.references_error() || rhs.references_error() ||
ty::type_is_scalar(lhs) && ty::type_is_scalar(rhs) ||
ty::type_is_simd(cx, lhs) && ty::type_is_simd(cx, rhs)
}
use middle::region::CodeExtent;
use middle::subst::Substs;
use middle::traits;
-use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall};
+use middle::ty::{self, ClosureTyper, ReScope, Ty, MethodCall, HasTypeFlags};
use middle::infer::{self, GenericKind};
use middle::pat_util;
/// Try to resolve the type for the given node.
pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> Ty<'tcx> {
let ty_unadjusted = self.resolve_node_type(expr.id);
- if ty::type_is_error(ty_unadjusted) {
+ if ty_unadjusted.references_error() {
ty_unadjusted
} else {
let tcx = self.fcx.tcx();
id, mutbl, cmt_borrowed);
let rptr_ty = rcx.resolve_node_type(id);
- if !ty::type_is_error(rptr_ty) {
+ if !rptr_ty.references_error() {
let tcx = rcx.fcx.ccx.tcx;
debug!("rptr_ty={}", rptr_ty);
let r = ty::ty_region(tcx, span, rptr_ty);
use middle::def;
use middle::infer;
use middle::subst;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, HasTypeFlags};
use rustc::ast_map;
use session::config;
use util::common::time;
// Functions that write types into the node type table
fn write_ty_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
debug!("write_ty_to_tcx({}, {:?})", node_id, ty);
- assert!(!ty::type_needs_infer(ty));
+ assert!(!ty.needs_infer());
tcx.node_type_insert(node_id, ty);
}
node_id,
item_substs);
- assert!(item_substs.substs.types.all(|t| !ty::type_needs_infer(*t)));
+ assert!(!item_substs.substs.types.needs_infer());
tcx.item_substs.borrow_mut().insert(node_id, item_substs);
}