rustc: combine type-flag-checking traits and fns and into one trait.
This commit is contained in:
parent
378a370ff2
commit
aa03871a6e
33 changed files with 313 additions and 438 deletions
|
|
@ -21,7 +21,7 @@ pub use self::DefIdSource::*;
|
|||
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;
|
||||
|
|
@ -534,7 +534,7 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
|
|||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -400,7 +400,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> {
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ use middle::def;
|
|||
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};
|
||||
|
|
@ -226,7 +226,7 @@ pub trait ErrorReporting<'tcx> {
|
|||
|
||||
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>;
|
||||
|
|
@ -504,18 +504,18 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1793,16 +1793,12 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
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> {
|
||||
|
|
@ -1810,9 +1806,6 @@ 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> {
|
||||
|
|
@ -1822,10 +1815,6 @@ 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,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
//! 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;
|
||||
|
|
@ -104,7 +104,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use middle::free_region::FreeRegionMap;
|
|||
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};
|
||||
|
|
@ -973,20 +973,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1001,7 +998,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// 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};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -36,7 +36,7 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for OpportunisticTypeResolver<'a, 'tcx>
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
@ -75,7 +75,7 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use metadata::csearch;
|
|||
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;
|
||||
|
||||
|
|
@ -92,8 +92,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
|
|||
|
||||
// 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,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
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;
|
||||
|
|
@ -100,17 +100,6 @@ impl<'tcx> Substs<'tcx> {
|
|||
*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()
|
||||
}
|
||||
|
|
@ -632,7 +621,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if !ty::type_needs_subst(t) {
|
||||
if !t.needs_subst() {
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
@ -729,10 +718,10 @@ impl<'a,'tcx> SubstFolder<'a,'tcx> {
|
|||
/// 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use super::{
|
|||
|
||||
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;
|
||||
|
|
@ -245,7 +245,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
|||
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 ({})",
|
||||
|
|
@ -325,8 +325,8 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
|||
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
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// 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;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub use self::ObligationCauseCode::*;
|
|||
|
||||
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;
|
||||
|
|
@ -432,7 +432,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ use super::util;
|
|||
|
||||
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;
|
||||
|
|
@ -195,7 +194,7 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
|
|||
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)
|
||||
}
|
||||
|
|
@ -206,7 +205,7 @@ pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tc
|
|||
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);
|
||||
|
|
@ -238,7 +237,7 @@ impl<'a,'b,'tcx> AssociatedTypeNormalizer<'a,'b,'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
|
|
@ -374,7 +373,7 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ use super::util;
|
|||
|
||||
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;
|
||||
|
|
@ -675,7 +675,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
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));
|
||||
}
|
||||
|
||||
|
|
@ -886,7 +886,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2558,7 +2558,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1180,64 +1180,6 @@ impl<'tcx> Borrow<TypeVariants<'tcx>> for InternedTy<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -1497,15 +1439,6 @@ pub struct UpvarBorrow {
|
|||
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,
|
||||
|
|
@ -2254,29 +2187,6 @@ impl<'tcx> Predicate<'tcx> {
|
|||
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)]
|
||||
|
|
@ -3711,18 +3621,6 @@ pub fn type_is_nil(ty: Ty) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -4255,7 +4153,7 @@ pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
|
|||
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 {
|
||||
|
|
@ -4277,7 +4175,7 @@ pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
|
|||
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 {
|
||||
|
|
@ -4307,7 +4205,7 @@ fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'t
|
|||
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 {
|
||||
|
|
@ -4321,7 +4219,7 @@ fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'t
|
|||
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 {
|
||||
|
|
@ -5028,7 +4926,7 @@ pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
|
|||
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) {
|
||||
|
|
@ -7362,11 +7260,33 @@ pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tc
|
|||
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)
|
||||
|
|
@ -7377,7 +7297,7 @@ pub trait RegionEscape {
|
|||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7491,237 +7411,221 @@ impl<'tcx> RegionEscape for ProjectionTy<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
fn references_error(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_ERR)
|
||||
}
|
||||
fn has_param_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PARAMS)
|
||||
}
|
||||
fn has_self_ty(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_SELF)
|
||||
}
|
||||
fn has_infer_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INFER)
|
||||
}
|
||||
fn needs_infer(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
fn needs_subst(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::NEEDS_SUBST)
|
||||
}
|
||||
fn has_closure_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
|
||||
}
|
||||
fn has_erasable_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND |
|
||||
TypeFlags::HAS_RE_INFER |
|
||||
TypeFlags::HAS_FREE_REGIONS)
|
||||
}
|
||||
/// 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,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.iter().any(|p| p.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 ClosureTy<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.sig.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 ClosureUpvar<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.ty.has_projection_types()
|
||||
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 ty::InstantiatedPredicates<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.predicates.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 Predicate<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.ty.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.predicates.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasTypeFlags for Predicate<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> 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(),
|
||||
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> HasProjectionTypes for TraitPredicate<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.trait_ref.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<'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.0.has_projection_types() || self.1.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 HasProjectionTypes for Region {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
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<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()
|
||||
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 ProjectionPredicate<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.projection_ty.has_projection_types() || self.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 ProjectionTy<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.trait_ref.has_projection_types()
|
||||
impl<'tcx> HasTypeFlags for ProjectionTy<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.trait_ref.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for Ty<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
ty::type_has_projection(*self)
|
||||
impl<'tcx> HasTypeFlags for Ty<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.flags.get().intersects(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for TraitRef<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.substs.has_projection_types()
|
||||
impl<'tcx> HasTypeFlags for TraitRef<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.substs.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 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,T> HasProjectionTypes for Option<T>
|
||||
where T : HasProjectionTypes
|
||||
impl<'tcx,T> HasTypeFlags for Option<T>
|
||||
where T : HasTypeFlags
|
||||
{
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.iter().any(|t| t.has_projection_types())
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.iter().any(|t| t.has_type_flags(flags))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx,T> HasProjectionTypes for Rc<T>
|
||||
where T : HasProjectionTypes
|
||||
impl<'tcx,T> HasTypeFlags for Rc<T>
|
||||
where T : HasTypeFlags
|
||||
{
|
||||
fn has_projection_types(&self) -> bool {
|
||||
(**self).has_projection_types()
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
(**self).has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx,T> HasProjectionTypes for Box<T>
|
||||
where T : HasProjectionTypes
|
||||
impl<'tcx,T> HasTypeFlags for Box<T>
|
||||
where T : HasTypeFlags
|
||||
{
|
||||
fn has_projection_types(&self) -> bool {
|
||||
(**self).has_projection_types()
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
(**self).has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HasProjectionTypes for Binder<T>
|
||||
where T : HasProjectionTypes
|
||||
impl<T> HasTypeFlags for Binder<T>
|
||||
where T : HasTypeFlags
|
||||
{
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.0.has_projection_types()
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.0.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for FnOutput<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
impl<'tcx> HasTypeFlags for FnOutput<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
match *self {
|
||||
FnConverging(t) => t.has_projection_types(),
|
||||
FnConverging(t) => t.has_type_flags(flags),
|
||||
FnDiverging => 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<'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> HasProjectionTypes for field<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.mt.ty.has_projection_types()
|
||||
impl<'tcx> HasTypeFlags for field<'tcx> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
self.mt.ty.has_type_flags(flags)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for BareFnTy<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.sig.has_projection_types()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ReferencesError {
|
||||
fn references_error(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<T:ReferencesError> ReferencesError for Binder<T> {
|
||||
fn references_error(&self) -> bool {
|
||||
self.0.references_error()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:ReferencesError> ReferencesError for Rc<T> {
|
||||
fn references_error(&self) -> bool {
|
||||
(&**self).references_error()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ReferencesError for TraitPredicate<'tcx> {
|
||||
fn references_error(&self) -> bool {
|
||||
self.trait_ref.references_error()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ReferencesError for ProjectionPredicate<'tcx> {
|
||||
fn references_error(&self) -> bool {
|
||||
self.projection_ty.trait_ref.references_error() || self.ty.references_error()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ReferencesError for TraitRef<'tcx> {
|
||||
fn references_error(&self) -> bool {
|
||||
self.input_types().iter().any(|t| t.references_error())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ReferencesError for Ty<'tcx> {
|
||||
fn references_error(&self) -> bool {
|
||||
type_is_error(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ReferencesError for Predicate<'tcx> {
|
||||
fn references_error(&self) -> 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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> ReferencesError for EquatePredicate<'tcx>
|
||||
{
|
||||
fn references_error(&self) -> bool {
|
||||
self.0.references_error() || self.1.references_error()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
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;
|
||||
|
|
@ -896,7 +896,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx>
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -946,7 +946,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,13 +14,12 @@ use middle::ty::{BoundRegion, BrAnon, BrNamed};
|
|||
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;
|
||||
|
|
@ -155,7 +154,7 @@ fn parameterized<GG>(f: &mut fmt::Formatter,
|
|||
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
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use rustc_typeck::middle::resolve_lifetime;
|
|||
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;
|
||||
|
|
@ -745,22 +745,22 @@ fn escaping() {
|
|||
// 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());
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ use middle::cfg;
|
|||
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;
|
||||
|
|
@ -1007,7 +1007,7 @@ pub fn alloc_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, name: &str) ->
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ use trans::meth;
|
|||
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;
|
||||
|
||||
|
|
@ -402,8 +402,8 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ use trans::monomorphize;
|
|||
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};
|
||||
|
|
@ -336,7 +336,7 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
|
|||
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
|
||||
|
|
@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
@ -610,7 +610,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
|
|||
}
|
||||
|
||||
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,
|
||||
|
|
@ -1194,7 +1194,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
}
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use trans::type_of;
|
|||
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;
|
||||
|
|
@ -103,8 +103,8 @@ pub fn check_intrinsics(ccx: &CrateContext) {
|
|||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ use trans::machine;
|
|||
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};
|
||||
|
|
@ -248,7 +248,7 @@ pub fn trans_static_method_callee<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use trans::base;
|
|||
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;
|
||||
|
|
@ -47,9 +47,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
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");
|
||||
|
||||
|
|
@ -302,7 +300,7 @@ pub fn apply_param_substs<'tcx,T>(tcx: &ty::ctxt<'tcx>,
|
|||
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)
|
||||
|
|
@ -313,7 +311,7 @@ pub fn apply_param_substs<'tcx,T>(tcx: &ty::ctxt<'tcx>,
|
|||
/// 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ use middle::resolve_lifetime as rl;
|
|||
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};
|
||||
|
|
@ -439,7 +439,7 @@ fn create_substs_for_ast_path<'tcx>(
|
|||
// 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 \
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding};
|
|||
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};
|
||||
|
|
@ -499,7 +499,7 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
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;
|
||||
|
|
@ -23,7 +23,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ use super::structurally_resolved_type;
|
|||
|
||||
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;
|
||||
|
|
@ -199,7 +198,7 @@ impl<'tcx> CastCheck<'tcx> {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use middle::subst;
|
|||
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;
|
||||
|
|
@ -528,7 +529,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
// 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,
|
||||
|
|
@ -928,7 +929,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1357,7 +1358,7 @@ impl<'tcx> Candidate<'tcx> {
|
|||
// 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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use CrateCtxt;
|
|||
|
||||
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;
|
||||
|
|
@ -40,7 +40,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace
|
|||
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};
|
||||
|
|
@ -397,7 +397,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
|
|||
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,
|
||||
|
|
@ -1296,15 +1296,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
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;
|
||||
}
|
||||
|
|
@ -1312,7 +1312,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// 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;
|
||||
}
|
||||
|
|
@ -1333,9 +1333,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
/// 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,
|
||||
|
|
@ -1443,7 +1443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
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);
|
||||
|
|
@ -1469,7 +1469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
@ -1954,7 +1954,7 @@ pub fn autoderef<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
fcx.resolve_type_vars_if_possible(t)
|
||||
}
|
||||
};
|
||||
if ty::type_is_error(resolved_t) {
|
||||
if resolved_t.references_error() {
|
||||
return (resolved_t, autoderefs, None);
|
||||
}
|
||||
|
||||
|
|
@ -2186,7 +2186,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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 {
|
||||
|
|
@ -2607,7 +2607,7 @@ fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
|
||||
/// 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,
|
||||
|
|
@ -2710,7 +2710,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
};
|
||||
|
||||
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
|
||||
|
|
@ -3022,7 +3022,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -3153,7 +3153,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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);
|
||||
|
|
@ -3232,7 +3232,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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
|
||||
|
|
@ -3352,7 +3352,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
|
||||
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);
|
||||
|
|
@ -3370,7 +3370,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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 {
|
||||
|
|
@ -3409,7 +3409,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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);
|
||||
}
|
||||
|
|
@ -3427,7 +3427,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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);
|
||||
|
|
@ -3504,7 +3504,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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));
|
||||
|
|
@ -3532,7 +3532,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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 {
|
||||
|
|
@ -3592,7 +3592,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
// 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),
|
||||
|
|
@ -3630,9 +3630,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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);
|
||||
|
|
@ -3671,8 +3671,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
(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)) => {
|
||||
|
|
@ -3690,7 +3690,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
// 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) => {
|
||||
|
|
@ -3765,7 +3765,7 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
|
|||
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.");
|
||||
|
|
@ -3933,7 +3933,7 @@ pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -3944,7 +3944,7 @@ pub fn check_decl_local<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, local: &'tcx ast::Local)
|
|||
};
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
|
@ -3961,7 +3961,7 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
|
|||
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 */ }
|
||||
}
|
||||
|
|
@ -3972,14 +3972,14 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
|
|||
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")
|
||||
}
|
||||
|
|
@ -3997,7 +3997,7 @@ pub fn check_stmt<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, stmt: &'tcx ast::Stmt) {
|
|||
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());
|
||||
|
|
@ -4041,7 +4041,7 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, '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 {
|
||||
|
|
@ -4184,7 +4184,7 @@ pub fn check_instantiable(tcx: &ty::ctxt,
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -4874,7 +4874,7 @@ fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use super::{
|
|||
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;
|
||||
|
|
@ -46,7 +46,7 @@ pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
|||
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),
|
||||
|
|
@ -228,7 +228,7 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
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),
|
||||
|
|
@ -428,20 +428,20 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
|
|||
}
|
||||
|
||||
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) ||
|
||||
|
|
@ -449,7 +449,7 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
|
|||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ use middle::mem_categorization as mc;
|
|||
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;
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
|
|||
/// 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();
|
||||
|
|
@ -1172,7 +1172,7 @@ fn link_region_from_node_type<'a, 'tcx>(rcx: &Rcx<'a, '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);
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ pub use rustc::util;
|
|||
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;
|
||||
|
|
@ -148,7 +148,7 @@ pub struct CrateCtxt<'a, 'tcx: 'a> {
|
|||
// 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);
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue