From 9902f8c3c2e89c87ab25a543e12c851bef955608 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 23 Feb 2019 16:11:34 +0530 Subject: [PATCH] fixes rust-lang#52482 --- src/librustc/ty/context.rs | 34 ++++++++++++------------- src/librustc_mir/hair/cx/expr.rs | 7 +---- src/librustc_passes/rvalue_promotion.rs | 17 +++++-------- src/librustc_typeck/check/cast.rs | 5 ++-- src/librustc_typeck/check/writeback.rs | 16 ++++-------- 5 files changed, 32 insertions(+), 47 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b37b632f4beec..621a596118371 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -40,7 +40,7 @@ use crate::ty::steal::Steal; 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; @@ -409,9 +409,9 @@ pub struct TypeckTables<'tcx> { /// MIR construction and hence is not serialized to metadata. fru_field_types: ItemLocalMap>>, - /// Maps a cast expression to its kind. This is keyed on the - /// *from* expression of the cast, not the cast itself. - cast_kinds: ItemLocalMap, + /// 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 @@ -456,7 +456,7 @@ impl<'tcx> TypeckTables<'tcx> { 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(), @@ -718,19 +718,19 @@ impl<'tcx> TypeckTables<'tcx> { } } - 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> for TypeckTables<'gcx> { @@ -753,7 +753,7 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { ref liberated_fn_sigs, ref fru_field_types, - ref cast_kinds, + ref coercion_casts, ref used_trait_imports, tainted_by_errors, @@ -798,7 +798,7 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { 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); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 5548366db66ec..ff5f3018acc08 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -8,7 +8,6 @@ use rustc::hir::def::{Def, CtorKind}; 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; @@ -656,11 +655,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // 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 { diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 6b8e37b3b3133..b0dd72030cc51 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -14,7 +14,7 @@ // - 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; @@ -319,15 +319,12 @@ fn check_expr_kind<'a, 'tcx>( 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) => { diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 87276b8c66ca4..cad9e73bd2ac9 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -428,13 +428,12 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } 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), }; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 7c1283a6d2108..73eadf6f275dd 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -50,7 +50,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { 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(); @@ -355,19 +355,13 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } - 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); } }