use crate::ty::subst::{UserSubsts, UnpackedKind};
use crate::ty::{BoundVar, BindingMode};
use crate::ty::CanonicalPolyFnSig;
-use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap};
+use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet};
use crate::util::nodemap::{FxHashMap, FxHashSet};
use errors::DiagnosticBuilder;
use rustc_data_structures::interner::HashInterner;
/// MIR construction and hence is not serialized to metadata.
fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
- /// Maps a cast expression to its kind. This is keyed on the
- /// *from* expression of the cast, not the cast itself.
- cast_kinds: ItemLocalMap<ty::cast::CastKind>,
+ /// For every coercion cast we add the HIR node ID of the cast
+ /// expression to this set.
+ coercion_casts: ItemLocalSet,
/// Set of trait imports actually used in the method resolution.
/// This is used for warning unused imports. During type
closure_kind_origins: Default::default(),
liberated_fn_sigs: Default::default(),
fru_field_types: Default::default(),
- cast_kinds: Default::default(),
+ coercion_casts: Default::default(),
used_trait_imports: Lrc::new(Default::default()),
tainted_by_errors: false,
free_region_map: Default::default(),
}
}
- pub fn cast_kinds(&self) -> LocalTableInContext<'_, ty::cast::CastKind> {
- LocalTableInContext {
- local_id_root: self.local_id_root,
- data: &self.cast_kinds
- }
+ pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool {
+ validate_hir_id_for_typeck_tables(self.local_id_root, hir_id, true);
+ self.coercion_casts.contains(&hir_id.local_id)
}
- pub fn cast_kinds_mut(&mut self) -> LocalTableInContextMut<'_, ty::cast::CastKind> {
- LocalTableInContextMut {
- local_id_root: self.local_id_root,
- data: &mut self.cast_kinds
- }
+ pub fn set_coercion_cast(&mut self, id: ItemLocalId) {
+ self.coercion_casts.insert(id);
+ }
+
+ pub fn coercion_casts(&self) -> &ItemLocalSet {
+ &self.coercion_casts
}
+
}
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
ref liberated_fn_sigs,
ref fru_field_types,
- ref cast_kinds,
+ ref coercion_casts,
ref used_trait_imports,
tainted_by_errors,
closure_kind_origins.hash_stable(hcx, hasher);
liberated_fn_sigs.hash_stable(hcx, hasher);
fru_field_types.hash_stable(hcx, hasher);
- cast_kinds.hash_stable(hcx, hasher);
+ coercion_casts.hash_stable(hcx, hasher);
used_trait_imports.hash_stable(hcx, hasher);
tainted_by_errors.hash_stable(hcx, hasher);
free_region_map.hash_stable(hcx, hasher);
use rustc::mir::interpret::{GlobalId, ErrorHandled};
use rustc::ty::{self, AdtKind, Ty};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
-use rustc::ty::cast::CastKind as TyCastKind;
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::hir;
use rustc::hir::def_id::LocalDefId;
// Check to see if this cast is a "coercion cast", where the cast is actually done
// using a coercion (or is a no-op).
- let cast = if let Some(&TyCastKind::CoercionCast) =
- cx.tables()
- .cast_kinds()
- .get(source.hir_id)
- {
+ let cast = if cx.tables().is_coercion_cast(source.hir_id) {
// Convert the lexpr to a vexpr.
ExprKind::Use { source: source.to_ref() }
} else {
// - It's not possible to take the address of a static item with unsafe interior. This is enforced
// by borrowck::gather_loans
-use rustc::ty::cast::CastKind;
+use rustc::ty::cast::CastTy;
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::DefId;
use rustc::middle::expr_use_visitor as euv;
hir::ExprKind::Cast(ref from, _) => {
let expr_promotability = v.check_expr(from);
debug!("Checking const cast(id={})", from.hir_id);
- match v.tables.cast_kinds().get(from.hir_id) {
- None => {
- v.tcx.sess.delay_span_bug(e.span, "no kind for cast");
- NotPromotable
- },
- Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => {
- NotPromotable
- }
- _ => expr_promotability
+ let cast_in = CastTy::from_ty(v.tables.expr_ty(from));
+ let cast_out = CastTy::from_ty(v.tables.expr_ty(e));
+ match (cast_in, cast_out) {
+ (Some(CastTy::FnPtr), Some(CastTy::Int(_))) |
+ (Some(CastTy::Ptr(_)), Some(CastTy::Int(_))) => NotPromotable,
+ (_, _) => expr_promotability
}
}
hir::ExprKind::Path(ref qpath) => {
} else if self.try_coercion_cast(fcx) {
self.trivial_cast_lint(fcx);
debug!(" -> CoercionCast");
- fcx.tables.borrow_mut().cast_kinds_mut().insert(self.expr.hir_id,
- CastKind::CoercionCast);
+ fcx.tables.borrow_mut().set_coercion_cast(self.expr.hir_id.local_id);
+
} else {
match self.do_check(fcx) {
Ok(k) => {
debug!(" -> {:?}", k);
- fcx.tables.borrow_mut().cast_kinds_mut().insert(self.expr.hir_id, k);
}
Err(e) => self.report_cast_error(fcx, e),
};
wbcx.visit_liberated_fn_sigs();
wbcx.visit_fru_field_types();
wbcx.visit_opaque_types(body.value.span);
- wbcx.visit_cast_types();
+ wbcx.visit_coercion_casts();
wbcx.visit_free_region_map();
wbcx.visit_user_provided_tys();
wbcx.visit_user_provided_sigs();
}
}
- fn visit_cast_types(&mut self) {
+ fn visit_coercion_casts(&mut self) {
let fcx_tables = self.fcx.tables.borrow();
- let fcx_cast_kinds = fcx_tables.cast_kinds();
+ let fcx_coercion_casts = fcx_tables.coercion_casts();
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
- let mut self_cast_kinds = self.tables.cast_kinds_mut();
- let common_local_id_root = fcx_tables.local_id_root.unwrap();
- for (&local_id, &cast_kind) in fcx_cast_kinds.iter() {
- let hir_id = hir::HirId {
- owner: common_local_id_root.index,
- local_id,
- };
- self_cast_kinds.insert(hir_id, cast_kind);
+ for local_id in fcx_coercion_casts {
+ self.tables.set_coercion_cast(*local_id);
}
}