diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 62aa6522a7bdc..38af6c3d0da54 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -525,6 +525,20 @@ pub struct GlobalCtxt<'tcx> { stability_interner: RefCell>, layout_interner: RefCell>, + + /// A vector of every trait accessible in the whole crate + /// (i.e. including those from subcrates). This is used only for + /// error reporting, and so is lazily initialised and generally + /// shouldn't taint the common path (hence the RefCell). + pub all_traits: RefCell>>, + + /// Obligations which will have to be checked at the end of + /// type-checking, after all functions have been inferred. + /// The key is the NodeId of the item the obligations were from. + pub deferred_obligations: RefCell>>>, + + /// HIR Ty -> Ty lowering cache. + pub ast_ty_to_ty_cache: RefCell>>, } impl<'tcx> GlobalCtxt<'tcx> { @@ -720,6 +734,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { layout_depth: Cell::new(0), derive_macros: RefCell::new(NodeMap()), stability_interner: RefCell::new(FxHashSet()), + all_traits: RefCell::new(None), + deferred_obligations: RefCell::new(NodeMap()), + ast_ty_to_ty_cache: RefCell::new(NodeMap()), }, f) } } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 4a91cdd24fcaa..aeb7a207c447e 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -37,6 +37,7 @@ macro_rules! define_maps { pub $name:ident: $node:ident($K:ty) -> $V:ty),*) => { pub struct Maps<$tcx> { providers: IndexVec>, + pub query_stack: RefCell>, $($(#[$attr])* pub $name: RefCell>>),* } @@ -46,11 +47,18 @@ macro_rules! define_maps { -> Self { Maps { providers, + query_stack: RefCell::new(vec![]), $($name: RefCell::new(DepTrackingMap::new(dep_graph.clone()))),* } } } + #[allow(bad_style)] + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub enum Query { + $($(#[$attr])* $name($K)),* + } + pub mod queries { use std::marker::PhantomData; @@ -119,6 +127,11 @@ define_maps! { <'tcx> /// additional acyclicity requirements). pub super_predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx>, + /// To avoid cycles within the predicates of a single item we compute + /// per-type-parameter predicates for resolving `T::AssocTy`. + pub type_param_predicates: ItemSignature(DefId) + -> ty::GenericPredicates<'tcx>, + pub trait_def: ItemSignature(DefId) -> &'tcx ty::TraitDef, pub adt_def: ItemSignature(DefId) -> &'tcx ty::AdtDef, pub adt_sized_constraint: SizedConstraint(DefId) -> Ty<'tcx>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index dd3ed2d9c2cd8..97476489a8adb 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -31,7 +31,7 @@ use ty::subst::{Subst, Substs}; use ty::util::IntTypeExt; use ty::walk::TypeWalker; use util::common::MemoizationMap; -use util::nodemap::{NodeSet, NodeMap, FxHashMap}; +use util::nodemap::{NodeSet, FxHashMap}; use serialize::{self, Encodable, Encoder}; use std::borrow::Cow; @@ -104,13 +104,12 @@ mod sty; /// The complete set of all analyses described in this module. This is /// produced by the driver and fed to trans and later passes. #[derive(Clone)] -pub struct CrateAnalysis<'tcx> { +pub struct CrateAnalysis { pub export_map: ExportMap, pub access_levels: middle::privacy::AccessLevels, pub reachable: NodeSet, pub name: String, pub glob_map: Option, - pub hir_ty_to_ty: NodeMap>, } #[derive(Clone)] @@ -1383,7 +1382,7 @@ pub struct ReprOptions { } impl ReprOptions { - pub fn new<'a, 'gcx, 'tcx>(tcx: &TyCtxt<'a, 'gcx, 'tcx>, did: DefId) -> ReprOptions { + pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions { let mut ret = ReprOptions::default(); let attrs = tcx.lookup_repr_hints(did); for r in attrs.iter() { @@ -1400,7 +1399,7 @@ impl ReprOptions { } impl<'a, 'gcx, 'tcx> AdtDef { - fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, + fn new(tcx: TyCtxt, did: DefId, kind: AdtKind, variants: Vec, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c1cfc0234e141..b80402a15f67d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -21,7 +21,7 @@ use rustc::middle::{self, dependency_format, stability, reachable}; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas}; use rustc::util::common::time; -use rustc::util::nodemap::{NodeSet, NodeMap}; +use rustc::util::nodemap::NodeSet; use rustc::util::fs::rename_or_copy_remove; use rustc_borrowck as borrowck; use rustc_incremental::{self, IncrementalHashesMap}; @@ -343,7 +343,7 @@ pub struct CompileState<'a, 'tcx: 'a> { pub hir_crate: Option<&'a hir::Crate>, pub hir_map: Option<&'a hir_map::Map<'tcx>>, pub resolutions: Option<&'a Resolutions>, - pub analysis: Option<&'a ty::CrateAnalysis<'tcx>>, + pub analysis: Option<&'a ty::CrateAnalysis>, pub tcx: Option>, pub trans: Option<&'a trans::CrateTranslation>, } @@ -417,7 +417,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { arenas: &'tcx GlobalArenas<'tcx>, cstore: &'a CStore, hir_map: &'a hir_map::Map<'tcx>, - analysis: &'a ty::CrateAnalysis<'static>, + analysis: &'a ty::CrateAnalysis, resolutions: &'a Resolutions, krate: &'a ast::Crate, hir_crate: &'a hir::Crate, @@ -444,7 +444,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { out_file: &'a Option, krate: Option<&'a ast::Crate>, hir_crate: &'a hir::Crate, - analysis: &'a ty::CrateAnalysis<'tcx>, + analysis: &'a ty::CrateAnalysis, tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_name: &'a str) -> Self { @@ -534,7 +534,7 @@ fn count_nodes(krate: &ast::Crate) -> usize { pub struct ExpansionResult { pub expanded_crate: ast::Crate, pub defs: hir_map::Definitions, - pub analysis: ty::CrateAnalysis<'static>, + pub analysis: ty::CrateAnalysis, pub resolutions: Resolutions, pub hir_forest: hir_map::Forest, } @@ -797,7 +797,6 @@ pub fn phase_2_configure_and_expand(sess: &Session, reachable: NodeSet(), name: crate_name.to_string(), glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None }, - hir_ty_to_ty: NodeMap(), }, resolutions: Resolutions { freevars: resolver.freevars, @@ -813,7 +812,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, /// structures carrying the results of the analysis. pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, hir_map: hir_map::Map<'tcx>, - mut analysis: ty::CrateAnalysis<'tcx>, + mut analysis: ty::CrateAnalysis, resolutions: Resolutions, arena: &'tcx DroplessArena, arenas: &'tcx GlobalArenas<'tcx>, @@ -821,7 +820,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, f: F) -> Result where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>, - ty::CrateAnalysis<'tcx>, + ty::CrateAnalysis, IncrementalHashesMap, CompileResult) -> R { @@ -908,8 +907,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, || stability::check_unstable_api_usage(tcx)); // passes are timed inside typeck - analysis.hir_ty_to_ty = - try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map)); + try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map)); time(time_passes, "const checking", diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 429e4ffef0c2a..064c4982ef00e 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -201,7 +201,7 @@ impl PpSourceMode { fn call_with_pp_support_hir<'tcx, A, B, F>(&self, sess: &'tcx Session, hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis<'tcx>, + analysis: &ty::CrateAnalysis, resolutions: &Resolutions, arena: &'tcx DroplessArena, arenas: &'tcx GlobalArenas<'tcx>, @@ -838,7 +838,7 @@ pub fn print_after_parsing(sess: &Session, pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis<'tcx>, + analysis: &ty::CrateAnalysis, resolutions: &Resolutions, input: &Input, krate: &ast::Crate, @@ -958,7 +958,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, // Instead, we call that function ourselves. fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, hir_map: &hir_map::Map<'tcx>, - analysis: &ty::CrateAnalysis<'tcx>, + analysis: &ty::CrateAnalysis, resolutions: &Resolutions, crate_name: &str, arena: &'tcx DroplessArena, diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index ddc60fe5f81d8..b1e435dcc751c 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -85,7 +85,7 @@ pub mod recorder { pub struct SaveContext<'l, 'tcx: 'l> { tcx: TyCtxt<'l, 'tcx, 'tcx>, tables: &'l ty::TypeckTables<'tcx>, - analysis: &'l ty::CrateAnalysis<'tcx>, + analysis: &'l ty::CrateAnalysis, span_utils: SpanUtils<'tcx>, } @@ -550,7 +550,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { match *qpath { hir::QPath::Resolved(_, ref path) => path.def, hir::QPath::TypeRelative(..) => { - if let Some(ty) = self.analysis.hir_ty_to_ty.get(&id) { + if let Some(ty) = self.tcx.ast_ty_to_ty_cache.borrow().get(&id) { if let ty::TyProjection(proj) = ty.sty { for item in self.tcx.associated_items(proj.trait_ref.def_id) { if item.kind == ty::AssociatedKind::Type { @@ -854,7 +854,7 @@ impl Format { pub fn process_crate<'l, 'tcx>(tcx: TyCtxt<'l, 'tcx, 'tcx>, krate: &ast::Crate, - analysis: &'l ty::CrateAnalysis<'tcx>, + analysis: &'l ty::CrateAnalysis, cratename: &str, odir: Option<&Path>, format: Format) { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 11ad47eef7159..cf93ef21f5d4a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -897,7 +897,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // FIXME: Self type is not always computed when we are here because type parameter // bounds may affect Self type and have to be converted before it. let trait_ref = if impl_def_id.is_local() { - tcx.impl_trait_refs.borrow().get(&impl_def_id).cloned().and_then(|x| x) + tcx.maps.impl_trait_ref.borrow().get(&impl_def_id) + .cloned().and_then(|x| x) } else { tcx.impl_trait_ref(impl_def_id) }; diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 3a980c8e7642b..8f1135adbb454 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -10,11 +10,10 @@ use super::{DeferredCallResolution, Expectation, FnCtxt, TupleArgumentsFlag}; -use CrateCtxt; use hir::def::Def; use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::{infer, traits}; -use rustc::ty::{self, LvaluePreference, Ty}; +use rustc::ty::{self, TyCtxt, LvaluePreference, Ty}; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -23,12 +22,9 @@ use rustc::hir; /// Check that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific /// method that is called) -pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id: DefId) { - if ccx.tcx.lang_items.drop_trait() == Some(trait_id) { - struct_span_err!(ccx.tcx.sess, - span, - E0040, - "explicit use of destructor method") +pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefId) { + if tcx.lang_items.drop_trait() == Some(trait_id) { + struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method") .span_label(span, &format!("explicit destructor calls not allowed")) .emit(); } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index bdeb716535655..2d4749331c08a 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -11,7 +11,7 @@ use rustc::hir::{self, ImplItemKind, TraitItemKind}; use rustc::infer::{self, InferOk}; use rustc::middle::free_region::FreeRegionMap; -use rustc::ty; +use rustc::ty::{self, TyCtxt}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; use rustc::ty::error::{ExpectedFound, TypeError}; use rustc::ty::subst::{Subst, Substs}; @@ -20,7 +20,6 @@ use rustc::util::common::ErrorReported; use syntax::ast; use syntax_pos::Span; -use CrateCtxt; use super::assoc; use super::{Inherited, FnCtxt}; use astconv::ExplicitSelf; @@ -36,7 +35,7 @@ use astconv::ExplicitSelf; /// - trait_m: the method in the trait /// - impl_trait_ref: the TraitRef corresponding to the trait implementation -pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, impl_m_body_id: ast::NodeId, @@ -47,7 +46,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, debug!("compare_impl_method(impl_trait_ref={:?})", impl_trait_ref); - if let Err(ErrorReported) = compare_self_type(ccx, + if let Err(ErrorReported) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, @@ -55,7 +54,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, return; } - if let Err(ErrorReported) = compare_number_of_generics(ccx, + if let Err(ErrorReported) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, @@ -63,7 +62,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, return; } - if let Err(ErrorReported) = compare_number_of_method_arguments(ccx, + if let Err(ErrorReported) = compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, @@ -71,7 +70,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, return; } - if let Err(ErrorReported) = compare_predicate_entailment(ccx, + if let Err(ErrorReported) = compare_predicate_entailment(tcx, impl_m, impl_m_span, impl_m_body_id, @@ -82,7 +81,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } -fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, impl_m_body_id: ast::NodeId, @@ -90,8 +89,6 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, impl_trait_ref: ty::TraitRef<'tcx>, old_broken_mode: bool) -> Result<(), ErrorReported> { - let tcx = ccx.tcx; - let trait_to_impl_substs = impl_trait_ref.substs; let cause = ObligationCause { @@ -190,7 +187,7 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let trait_m_predicates = tcx.item_predicates(trait_m.def_id); // Check region bounds. - check_region_bounds_on_impl_method(ccx, + check_region_bounds_on_impl_method(tcx, impl_m_span, impl_m, &trait_m_generics, @@ -228,7 +225,7 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, normalize_cause.clone()); tcx.infer_ctxt(trait_param_env, Reveal::NotSpecializable).enter(|infcx| { - let inh = Inherited::new(ccx, infcx); + let inh = Inherited::new(infcx); let infcx = &inh.infcx; let fulfillment_cx = &inh.fulfillment_cx; @@ -383,7 +380,7 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }) } -fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, impl_m: &ty::AssociatedItem, trait_generics: &ty::Generics, @@ -414,7 +411,7 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // are zero. Since I don't quite know how to phrase things at // the moment, give a kind of vague error message. if trait_params.len() != impl_params.len() { - struct_span_err!(ccx.tcx.sess, + struct_span_err!(tcx.sess, span, E0195, "lifetime parameters or bounds on method `{}` do not match the \ @@ -510,14 +507,13 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a } } -fn compare_self_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, trait_m: &ty::AssociatedItem, impl_trait_ref: ty::TraitRef<'tcx>) -> Result<(), ErrorReported> { - let tcx = ccx.tcx; // Try to give more informative error messages about self typing // mismatches. Note that any mismatch will also be detected // below, where we construct a canonical function type that @@ -583,13 +579,12 @@ fn compare_self_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, Ok(()) } -fn compare_number_of_generics<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, trait_m: &ty::AssociatedItem, trait_item_span: Option) -> Result<(), ErrorReported> { - let tcx = ccx.tcx; let impl_m_generics = tcx.item_generics(impl_m.def_id); let trait_m_generics = tcx.item_generics(trait_m.def_id); let num_impl_m_type_params = impl_m_generics.types.len(); @@ -653,13 +648,12 @@ fn compare_number_of_generics<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, Ok(()) } -fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn compare_number_of_method_arguments<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_m: &ty::AssociatedItem, impl_m_span: Span, trait_m: &ty::AssociatedItem, trait_item_span: Option) -> Result<(), ErrorReported> { - let tcx = ccx.tcx; let m_fty = |method: &ty::AssociatedItem| { match tcx.item_type(method.def_id).sty { ty::TyFnDef(_, _, f) => f, @@ -739,14 +733,13 @@ fn compare_number_of_method_arguments<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, Ok(()) } -pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_c: &ty::AssociatedItem, impl_c_span: Span, trait_c: &ty::AssociatedItem, impl_trait_ref: ty::TraitRef<'tcx>) { debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); - let tcx = ccx.tcx; tcx.infer_ctxt((), Reveal::NotSpecializable).enter(|infcx| { let mut fulfillment_cx = traits::FulfillmentContext::new(); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index f701bc3220848..385ea7d52e1ce 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use CrateCtxt; use check::regionck::RegionCtxt; use hir::def_id::DefId; @@ -40,17 +39,18 @@ use syntax_pos::Span; /// struct/enum definition for the nominal type itself (i.e. /// cannot do `struct S; impl Drop for S { ... }`). /// -pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()> { - let dtor_self_type = ccx.tcx.item_type(drop_impl_did); - let dtor_predicates = ccx.tcx.item_predicates(drop_impl_did); +pub fn check_drop_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + drop_impl_did: DefId) -> Result<(), ()> { + let dtor_self_type = tcx.item_type(drop_impl_did); + let dtor_predicates = tcx.item_predicates(drop_impl_did); match dtor_self_type.sty { ty::TyAdt(adt_def, self_to_impl_substs) => { - ensure_drop_params_and_item_params_correspond(ccx, + ensure_drop_params_and_item_params_correspond(tcx, drop_impl_did, dtor_self_type, adt_def.did)?; - ensure_drop_predicates_are_implied_by_item_defn(ccx, + ensure_drop_predicates_are_implied_by_item_defn(tcx, drop_impl_did, &dtor_predicates, adt_def.did, @@ -59,7 +59,7 @@ pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()> _ => { // Destructors only work on nominal types. This was // already checked by coherence, so we can panic here. - let span = ccx.tcx.def_span(drop_impl_did); + let span = tcx.def_span(drop_impl_did); span_bug!(span, "should have been rejected by coherence check: {}", dtor_self_type); @@ -68,13 +68,12 @@ pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()> } fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( - ccx: &CrateCtxt<'a, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, drop_impl_did: DefId, drop_impl_ty: Ty<'tcx>, self_type_did: DefId) -> Result<(), ()> { - let tcx = ccx.tcx; let drop_impl_node_id = tcx.hir.as_local_node_id(drop_impl_did).unwrap(); let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap(); @@ -126,7 +125,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( /// Confirms that every predicate imposed by dtor_predicates is /// implied by assuming the predicates attached to self_type_did. fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( - ccx: &CrateCtxt<'a, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, drop_impl_did: DefId, dtor_predicates: &ty::GenericPredicates<'tcx>, self_type_did: DefId, @@ -169,8 +168,6 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( // absent. So we report an error that the Drop impl injected a // predicate that is not present on the struct definition. - let tcx = ccx.tcx; - let self_type_node_id = tcx.hir.as_local_node_id(self_type_did).unwrap(); let drop_impl_span = tcx.def_span(drop_impl_did); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index cb4e85e842c2a..4d4e312dab37c 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -14,9 +14,9 @@ use intrinsics; use rustc::traits::{ObligationCause, ObligationCauseCode}; use rustc::ty::subst::Substs; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, TyCtxt, Ty}; use rustc::util::nodemap::FxHashMap; -use {CrateCtxt, require_same_types}; +use require_same_types; use syntax::abi::Abi; use syntax::ast; @@ -27,13 +27,12 @@ use rustc::hir; use std::iter; -fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem, n_tps: usize, abi: Abi, inputs: Vec>, output: Ty<'tcx>) { - let tcx = ccx.tcx; let def_id = tcx.hir.local_def_id(it.id); let substs = Substs::for_item(tcx, def_id, @@ -59,7 +58,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, .span_label(span, &format!("expected {} type parameter", n_tps)) .emit(); } else { - require_same_types(ccx, + require_same_types(tcx, &ObligationCause::new(it.span, it.id, ObligationCauseCode::IntrinsicType), @@ -70,13 +69,9 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, /// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs, /// and in libcore/intrinsics.rs -pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { - fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> { - let name = Symbol::intern(&format!("P{}", n)); - ccx.tcx.mk_param(n, name) - } - - let tcx = ccx.tcx; +pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + it: &hir::ForeignItem) { + let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n))); let name = it.name.as_str(); let (n_tps, inputs, output) = if name.starts_with("atomic_") { let split : Vec<&str> = name.split('_').collect(); @@ -84,19 +79,19 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { //We only care about the operation here let (n_tps, inputs, output) = match split[1] { - "cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(ccx, 0)), - param(ccx, 0), - param(ccx, 0)], - tcx.intern_tup(&[param(ccx, 0), tcx.types.bool], false)), - "load" => (1, vec![tcx.mk_imm_ptr(param(ccx, 0))], - param(ccx, 0)), - "store" => (1, vec![tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)], + "cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(0)), + param(0), + param(0)], + tcx.intern_tup(&[param(0), tcx.types.bool], false)), + "load" => (1, vec![tcx.mk_imm_ptr(param(0))], + param(0)), + "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_nil()), "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | "min" | "umax" | "umin" => { - (1, vec![tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0)], - param(ccx, 0)) + (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], + param(0)) } "fence" | "singlethreadfence" => { (0, Vec::new(), tcx.mk_nil()) @@ -116,45 +111,45 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), tcx.mk_nil()), "size_of" | - "pref_align_of" | "min_align_of" => (1, Vec::new(), ccx.tcx.types.usize), + "pref_align_of" | "min_align_of" => (1, Vec::new(), tcx.types.usize), "size_of_val" | "min_align_of_val" => { (1, vec![ tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(0))), - param(ccx, 0)) - ], ccx.tcx.types.usize) + param(0)) + ], tcx.types.usize) } - "rustc_peek" => (1, vec![param(ccx, 0)], param(ccx, 0)), - "init" => (1, Vec::new(), param(ccx, 0)), - "uninit" => (1, Vec::new(), param(ccx, 0)), - "forget" => (1, vec![ param(ccx, 0) ], tcx.mk_nil()), - "transmute" => (2, vec![ param(ccx, 0) ], param(ccx, 1)), + "rustc_peek" => (1, vec![param(0)], param(0)), + "init" => (1, Vec::new(), param(0)), + "uninit" => (1, Vec::new(), param(0)), + "forget" => (1, vec![ param(0) ], tcx.mk_nil()), + "transmute" => (2, vec![ param(0) ], param(1)), "move_val_init" => { (1, vec![ - tcx.mk_mut_ptr(param(ccx, 0)), - param(ccx, 0) + tcx.mk_mut_ptr(param(0)), + param(0) ], tcx.mk_nil()) } "drop_in_place" => { - (1, vec![tcx.mk_mut_ptr(param(ccx, 0))], tcx.mk_nil()) + (1, vec![tcx.mk_mut_ptr(param(0))], tcx.mk_nil()) } - "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool), + "needs_drop" => (1, Vec::new(), tcx.types.bool), "type_name" => (1, Vec::new(), tcx.mk_static_str()), - "type_id" => (1, Vec::new(), ccx.tcx.types.u64), + "type_id" => (1, Vec::new(), tcx.types.u64), "offset" | "arith_offset" => { (1, vec![ tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutImmutable }), - ccx.tcx.types.isize + tcx.types.isize ], tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutImmutable })) } @@ -162,11 +157,11 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { (1, vec![ tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutImmutable }), tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutMutable }), tcx.types.usize, @@ -177,11 +172,11 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { (1, vec![ tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutMutable }), tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutImmutable }), tcx.types.usize, @@ -192,7 +187,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { (1, vec![ tcx.mk_ptr(ty::TypeAndMut { - ty: param(ccx, 0), + ty: param(0), mutbl: hir::MutMutable }), tcx.types.u8, @@ -264,23 +259,23 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { "roundf64" => (0, vec![ tcx.types.f64 ], tcx.types.f64), "volatile_load" => - (1, vec![ tcx.mk_imm_ptr(param(ccx, 0)) ], param(ccx, 0)), + (1, vec![ tcx.mk_imm_ptr(param(0)) ], param(0)), "volatile_store" => - (1, vec![ tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ], tcx.mk_nil()), + (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()), - "ctpop" | "ctlz" | "cttz" | "bswap" => (1, vec![param(ccx, 0)], param(ccx, 0)), + "ctpop" | "ctlz" | "cttz" | "bswap" => (1, vec![param(0)], param(0)), "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => - (1, vec![param(ccx, 0), param(ccx, 0)], - tcx.intern_tup(&[param(ccx, 0), tcx.types.bool], false)), + (1, vec![param(0), param(0)], + tcx.intern_tup(&[param(0), tcx.types.bool], false)), "unchecked_div" | "unchecked_rem" => - (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), + (1, vec![param(0), param(0)], param(0)), "overflowing_add" | "overflowing_sub" | "overflowing_mul" => - (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), + (1, vec![param(0), param(0)], param(0)), "fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => - (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)), + (1, vec![param(0), param(0)], param(0)), "assume" => (0, vec![tcx.types.bool], tcx.mk_nil()), "likely" => (0, vec![tcx.types.bool], tcx.types.bool), @@ -289,7 +284,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { "discriminant_value" => (1, vec![ tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(0))), - param(ccx, 0))], tcx.types.u64), + param(0))], tcx.types.u64), "try" => { let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8); @@ -312,18 +307,17 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) { }; (n_tps, inputs, output) }; - equate_intrinsic_type(ccx, it, n_tps, Abi::RustIntrinsic, inputs, output) + equate_intrinsic_type(tcx, it, n_tps, Abi::RustIntrinsic, inputs, output) } /// Type-check `extern "platform-intrinsic" { ... }` functions. -pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, - it: &hir::ForeignItem) { +pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + it: &hir::ForeignItem) { let param = |n| { let name = Symbol::intern(&format!("P{}", n)); - ccx.tcx.mk_param(n, name) + tcx.mk_param(n, name) }; - let tcx = ccx.tcx; let def_id = tcx.hir.local_def_id(it.id); let i_n_tps = tcx.item_generics(def_id).types.len(); let name = it.name.as_str(); @@ -379,10 +373,10 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, } let input_pairs = intr.inputs.iter().zip(sig.inputs()); for (i, (expected_arg, arg)) in input_pairs.enumerate() { - match_intrinsic_type_to_type(ccx, &format!("argument {}", i + 1), it.span, + match_intrinsic_type_to_type(tcx, &format!("argument {}", i + 1), it.span, &mut structural_to_nomimal, expected_arg, arg); } - match_intrinsic_type_to_type(ccx, "return value", it.span, + match_intrinsic_type_to_type(tcx, "return value", it.span, &mut structural_to_nomimal, &intr.output, sig.output()); return @@ -396,15 +390,15 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt, } }; - equate_intrinsic_type(ccx, it, n_tps, Abi::PlatformIntrinsic, + equate_intrinsic_type(tcx, it, n_tps, Abi::PlatformIntrinsic, inputs, output) } // walk the expected type and the actual type in lock step, checking they're // the same, in a kinda-structural way, i.e. `Vector`s have to be simd structs with // exactly the right element type -fn match_intrinsic_type_to_type<'tcx, 'a>( - ccx: &CrateCtxt<'a, 'tcx>, +fn match_intrinsic_type_to_type<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, position: &str, span: Span, structural_to_nominal: &mut FxHashMap<&'a intrinsics::Type, ty::Ty<'tcx>>, @@ -413,7 +407,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( use intrinsics::Type::*; let simple_error = |real: &str, expected: &str| { - span_err!(ccx.tcx.sess, span, E0442, + span_err!(tcx.sess, span, E0442, "intrinsic {} has wrong type: found {}, expected {}", position, real, expected) }; @@ -453,7 +447,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( simple_error(&format!("`{}`", t), if const_ {"const pointer"} else {"mut pointer"}) } - match_intrinsic_type_to_type(ccx, position, span, structural_to_nominal, + match_intrinsic_type_to_type(tcx, position, span, structural_to_nominal, inner_expected, ty) } _ => simple_error(&format!("`{}`", t), "raw pointer"), @@ -464,19 +458,19 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( simple_error(&format!("non-simd type `{}`", t), "simd type"); return; } - let t_len = t.simd_size(ccx.tcx); + let t_len = t.simd_size(tcx); if len as usize != t_len { simple_error(&format!("vector with length {}", t_len), &format!("length {}", len)); return; } - let t_ty = t.simd_type(ccx.tcx); + let t_ty = t.simd_type(tcx); { // check that a given structural type always has the same an intrinsic definition let previous = structural_to_nominal.entry(expected).or_insert(t); if *previous != t { // this gets its own error code because it is non-trivial - span_err!(ccx.tcx.sess, span, E0443, + span_err!(tcx.sess, span, E0443, "intrinsic {} has wrong type: found `{}`, expected `{}` which \ was used for this vector type previously in this signature", position, @@ -485,7 +479,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( return; } } - match_intrinsic_type_to_type(ccx, + match_intrinsic_type_to_type(tcx, position, span, structural_to_nominal, @@ -501,7 +495,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( return } for (e, c) in expected_contents.iter().zip(contents) { - match_intrinsic_type_to_type(ccx, position, span, structural_to_nominal, + match_intrinsic_type_to_type(tcx, position, span, structural_to_nominal, e, c) } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 2d90394025d21..917607aab6b5a 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -566,7 +566,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // Disallow calls to the method `drop` defined in the `Drop` trait. match pick.item.container { ty::TraitContainer(trait_def_id) => { - callee::check_legal_trait_for_method_call(self.ccx, self.span, trait_def_id) + callee::check_legal_trait_for_method_call(self.tcx, self.span, trait_def_id) } ty::ImplContainer(..) => {} } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 468a38cd2bace..b6071d01ff1cf 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -653,7 +653,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_extension_candidates_for_all_traits(&mut self) -> Result<(), MethodError<'tcx>> { let mut duplicates = FxHashSet(); - for trait_info in suggest::all_traits(self.ccx) { + for trait_info in suggest::all_traits(self.tcx) { if duplicates.insert(trait_info.def_id) { self.assemble_extension_candidates_for_trait(None, trait_info.def_id)?; } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f6345e6e262db..6ce50d91124d4 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -11,11 +11,9 @@ //! Give useful errors and suggestions to users when an item can't be //! found or is otherwise invalid. -use CrateCtxt; - use check::FnCtxt; use rustc::hir::map as hir_map; -use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable}; +use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable}; use hir::def::Def; use hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::lang_items::FnOnceTraitLangItem; @@ -343,7 +341,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // there's no implemented traits, so lets suggest some traits to // implement, by finding ones that have the item name, and are // legal to implement. - let mut candidates = all_traits(self.ccx) + let mut candidates = all_traits(self.tcx) .filter(|info| { // we approximate the coherence rules to only suggest // traits that are legal to implement by requiring that @@ -423,7 +421,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } -pub type AllTraitsVec = Vec; +pub type AllTraitsVec = Vec; #[derive(Copy, Clone)] pub struct TraitInfo { @@ -458,8 +456,8 @@ impl Ord for TraitInfo { } /// Retrieve all traits in this crate and any dependent crates. -pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { - if ccx.all_traits.borrow().is_none() { +pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a> { + if tcx.all_traits.borrow().is_none() { use rustc::hir::itemlikevisit; let mut traits = vec![]; @@ -476,7 +474,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { match i.node { hir::ItemTrait(..) => { let def_id = self.map.local_def_id(i.id); - self.traits.push(TraitInfo::new(def_id)); + self.traits.push(def_id); } _ => {} } @@ -488,45 +486,45 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) { } } - ccx.tcx.hir.krate().visit_all_item_likes(&mut Visitor { - map: &ccx.tcx.hir, + tcx.hir.krate().visit_all_item_likes(&mut Visitor { + map: &tcx.hir, traits: &mut traits, }); // Cross-crate: let mut external_mods = FxHashSet(); - fn handle_external_def(ccx: &CrateCtxt, + fn handle_external_def(tcx: TyCtxt, traits: &mut AllTraitsVec, external_mods: &mut FxHashSet, def: Def) { let def_id = def.def_id(); match def { Def::Trait(..) => { - traits.push(TraitInfo::new(def_id)); + traits.push(def_id); } Def::Mod(..) => { if !external_mods.insert(def_id) { return; } - for child in ccx.tcx.sess.cstore.item_children(def_id) { - handle_external_def(ccx, traits, external_mods, child.def) + for child in tcx.sess.cstore.item_children(def_id) { + handle_external_def(tcx, traits, external_mods, child.def) } } _ => {} } } - for cnum in ccx.tcx.sess.cstore.crates() { + for cnum in tcx.sess.cstore.crates() { let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX, }; - handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(def_id)); + handle_external_def(tcx, &mut traits, &mut external_mods, Def::Mod(def_id)); } - *ccx.all_traits.borrow_mut() = Some(traits); + *tcx.all_traits.borrow_mut() = Some(traits); } - let borrow = ccx.all_traits.borrow(); + let borrow = tcx.all_traits.borrow(); assert!(borrow.is_some()); AllTraits { borrow: borrow, @@ -547,7 +545,7 @@ impl<'a> Iterator for AllTraits<'a> { // ugh. borrow.as_ref().unwrap().get(*idx).map(|info| { *idx += 1; - *info + TraitInfo::new(*info) }) } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 6a003ef734020..d52516e0ae500 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -56,7 +56,7 @@ stored in `fcx.node_types` and `fcx.item_substs`. These types may contain unresolved type variables. After type checking is complete, the functions in the writeback module are used to take the types from this table, resolve them, and then write them into their -permanent home in the type context `ccx.tcx`. +permanent home in the type context `tcx`. This means that during inferencing you should use `fcx.write_ty()` and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of @@ -98,7 +98,6 @@ use rustc::ty::fold::{BottomUpFolder, TypeFoldable}; use rustc::ty::util::{Representability, IntTypeExt}; use require_c_abi_if_variadic; use session::{Session, CompileResult}; -use CrateCtxt; use TypeAndSubsts; use lint; use util::common::{ErrorReported, indenter}; @@ -154,8 +153,8 @@ mod op; /// `bar()` will each have their own `FnCtxt`, but they will /// share the inherited fields. pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - ccx: &'a CrateCtxt<'a, 'gcx>, infcx: InferCtxt<'a, 'gcx, 'tcx>, + locals: RefCell>>, fulfillment_cx: RefCell>, @@ -474,22 +473,20 @@ impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> { } } -/// Helper type of a temporary returned by ccx.inherited(...). +/// Helper type of a temporary returned by Inherited::build(...). /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>). pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - ccx: &'a CrateCtxt<'a, 'gcx>, infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx> } -impl<'a, 'gcx, 'tcx> CrateCtxt<'a, 'gcx> { - pub fn inherited(&'a self, id: ast::NodeId) - -> InheritedBuilder<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { + pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId) + -> InheritedBuilder<'a, 'gcx, 'tcx> { let tables = ty::TypeckTables::empty(); - let param_env = ParameterEnvironment::for_item(self.tcx, id); + let param_env = ParameterEnvironment::for_item(tcx, id); InheritedBuilder { - ccx: self, - infcx: self.tcx.infer_ctxt((tables, param_env), Reveal::NotSpecializable) + infcx: tcx.infer_ctxt((tables, param_env), Reveal::NotSpecializable) } } } @@ -498,17 +495,13 @@ impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> { fn enter(&'tcx mut self, f: F) -> R where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R { - let ccx = self.ccx; - self.infcx.enter(|infcx| f(Inherited::new(ccx, infcx))) + self.infcx.enter(|infcx| f(Inherited::new(infcx))) } } impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { - pub fn new(ccx: &'a CrateCtxt<'a, 'gcx>, - infcx: InferCtxt<'a, 'gcx, 'tcx>) - -> Self { + pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self { Inherited { - ccx: ccx, infcx: infcx, fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()), locals: RefCell::new(NodeMap()), @@ -536,23 +529,23 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { } -struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } -struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } +struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } +struct CheckItemBodiesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> } impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.ccx.tcx.hir) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_item(&mut self, i: &'tcx hir::Item) { - check_item_type(self.ccx, i); + check_item_type(self.tcx, i); intravisit::walk_item(self, i); } fn visit_ty(&mut self, t: &'tcx hir::Ty) { match t.node { hir::TyArray(_, length) => { - check_const_with_type(self.ccx, length, self.ccx.tcx.types.usize, length.node_id); + check_const_with_type(self.tcx, length, self.tcx.types.usize, length.node_id); } _ => {} } @@ -563,7 +556,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemTypesVisitor<'a, 'tcx> { fn visit_expr(&mut self, e: &'tcx hir::Expr) { match e.node { hir::ExprRepeat(_, count) => { - check_const_with_type(self.ccx, count, self.ccx.tcx.types.usize, count.node_id); + check_const_with_type(self.tcx, count, self.tcx.types.usize, count.node_id); } _ => {} } @@ -576,7 +569,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { hir::ItemFn(ref decl, .., body_id) => { - check_bare_fn(self.ccx, &decl, body_id, item.id, item.span); + check_bare_fn(self.tcx, &decl, body_id, item.id, item.span); } _ => { } } @@ -585,10 +578,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { match trait_item.node { hir::TraitItemKind::Const(_, Some(expr)) => { - check_const(self.ccx, expr, trait_item.id) + check_const(self.tcx, expr, trait_item.id) } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body_id)) => { - check_bare_fn(self.ccx, &sig.decl, body_id, trait_item.id, trait_item.span); + check_bare_fn(self.tcx, &sig.decl, body_id, trait_item.id, trait_item.span); } hir::TraitItemKind::Method(_, hir::TraitMethod::Required(_)) | hir::TraitItemKind::Const(_, None) | @@ -601,10 +594,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { match impl_item.node { hir::ImplItemKind::Const(_, expr) => { - check_const(self.ccx, expr, impl_item.id) + check_const(self.tcx, expr, impl_item.id) } hir::ImplItemKind::Method(ref sig, body_id) => { - check_bare_fn(self.ccx, &sig.decl, body_id, impl_item.id, impl_item.span); + check_bare_fn(self.tcx, &sig.decl, body_id, impl_item.id, impl_item.span); } hir::ImplItemKind::Type(_) => { // Nothing to do here. @@ -613,35 +606,35 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { } } -pub fn check_wf_new(ccx: &CrateCtxt) -> CompileResult { - ccx.tcx.sess.track_errors(|| { - let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx); - ccx.tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut visit.as_deep_visitor()); +pub fn check_wf_new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult { + tcx.sess.track_errors(|| { + let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx); + tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut visit.as_deep_visitor()); }) } -pub fn check_item_types(ccx: &CrateCtxt) -> CompileResult { - ccx.tcx.sess.track_errors(|| { - let mut visit = CheckItemTypesVisitor { ccx: ccx }; - ccx.tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemType, +pub fn check_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult { + tcx.sess.track_errors(|| { + let mut visit = CheckItemTypesVisitor { tcx: tcx }; + tcx.visit_all_item_likes_in_krate(DepNode::TypeckItemType, &mut visit.as_deep_visitor()); }) } -pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult { - ccx.tcx.sess.track_errors(|| { - let mut visit = CheckItemBodiesVisitor { ccx: ccx }; - ccx.tcx.visit_all_item_likes_in_krate(DepNode::TypeckTables, &mut visit); +pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult { + tcx.sess.track_errors(|| { + let mut visit = CheckItemBodiesVisitor { tcx: tcx }; + tcx.visit_all_item_likes_in_krate(DepNode::TypeckTables, &mut visit); // Process deferred obligations, now that all functions // bodies have been fully inferred. - for (&item_id, obligations) in ccx.deferred_obligations.borrow().iter() { + for (&item_id, obligations) in tcx.deferred_obligations.borrow().iter() { // Use the same DepNode as for the body of the original function/item. - let def_id = ccx.tcx.hir.local_def_id(item_id); - let _task = ccx.tcx.dep_graph.in_task(DepNode::TypeckTables(def_id)); + let def_id = tcx.hir.local_def_id(item_id); + let _task = tcx.dep_graph.in_task(DepNode::TypeckTables(def_id)); - let param_env = ParameterEnvironment::for_item(ccx.tcx, item_id); - ccx.tcx.infer_ctxt(param_env, Reveal::NotSpecializable).enter(|infcx| { + let param_env = ParameterEnvironment::for_item(tcx, item_id); + tcx.infer_ctxt(param_env, Reveal::NotSpecializable).enter(|infcx| { let mut fulfillment_cx = traits::FulfillmentContext::new(); for obligation in obligations.iter().map(|o| o.to_obligation()) { fulfillment_cx.register_predicate_obligation(&infcx, obligation); @@ -655,19 +648,19 @@ pub fn check_item_bodies(ccx: &CrateCtxt) -> CompileResult { }) } -pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult { - ccx.tcx.sess.track_errors(|| { - let _task = ccx.tcx.dep_graph.in_task(DepNode::Dropck); - let drop_trait = match ccx.tcx.lang_items.drop_trait() { - Some(id) => ccx.tcx.lookup_trait_def(id), None => { return } +pub fn check_drop_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult { + tcx.sess.track_errors(|| { + let _task = tcx.dep_graph.in_task(DepNode::Dropck); + let drop_trait = match tcx.lang_items.drop_trait() { + Some(id) => tcx.lookup_trait_def(id), None => { return } }; - drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| { - let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did)); + drop_trait.for_each_impl(tcx, |drop_impl_did| { + let _task = tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did)); if drop_impl_did.is_local() { - match dropck::check_drop_impl(ccx, drop_impl_did) { + match dropck::check_drop_impl(tcx, drop_impl_did) { Ok(()) => {} Err(()) => { - assert!(ccx.tcx.sess.has_errors()); + assert!(tcx.sess.has_errors()); } } } @@ -675,22 +668,22 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult { }) } -fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn check_bare_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, decl: &'tcx hir::FnDecl, body_id: hir::BodyId, fn_id: ast::NodeId, span: Span) { - let body = ccx.tcx.hir.body(body_id); + let body = tcx.hir.body(body_id); - let raw_fty = ccx.tcx.item_type(ccx.tcx.hir.local_def_id(fn_id)); + let raw_fty = tcx.item_type(tcx.hir.local_def_id(fn_id)); let fn_ty = match raw_fty.sty { ty::TyFnDef(.., f) => f, _ => span_bug!(body.value.span, "check_bare_fn: function type expected") }; - check_abi(ccx, span, fn_ty.abi); + check_abi(tcx, span, fn_ty.abi); - ccx.inherited(fn_id).enter(|inh| { + Inherited::build(tcx, fn_id).enter(|inh| { // Compute the fty from point of view of inside fn. let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body_id.node_id); let fn_sig = @@ -713,9 +706,9 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }); } -fn check_abi<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, abi: Abi) { - if !ccx.tcx.sess.target.target.is_abi_supported(abi) { - struct_span_err!(ccx.tcx.sess, span, E0570, +fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) { + if !tcx.sess.target.target.is_abi_supported(abi) { + struct_span_err!(tcx.sess, span, E0570, "The ABI `{}` is not supported for the current target", abi).emit() } } @@ -837,30 +830,34 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fcx } -fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { - let def_id = ccx.tcx.hir.local_def_id(id); - check_representable(ccx.tcx, span, def_id); +fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + id: ast::NodeId, + span: Span) { + let def_id = tcx.hir.local_def_id(id); + check_representable(tcx, span, def_id); - if ccx.tcx.lookup_simd(def_id) { - check_simd(ccx.tcx, span, def_id); + if tcx.lookup_simd(def_id) { + check_simd(tcx, span, def_id); } } -fn check_union(ccx: &CrateCtxt, id: ast::NodeId, span: Span) { - check_representable(ccx.tcx, span, ccx.tcx.hir.local_def_id(id)); +fn check_union<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + id: ast::NodeId, + span: Span) { + check_representable(tcx, span, tcx.hir.local_def_id(id)); } -pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { +pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item) { debug!("check_item_type(it.id={}, it.name={})", it.id, - ccx.tcx.item_path_str(ccx.tcx.hir.local_def_id(it.id))); + tcx.item_path_str(tcx.hir.local_def_id(it.id))); let _indenter = indenter(); match it.node { // Consts can play a role in type-checking, so they are included here. hir::ItemStatic(.., e) | - hir::ItemConst(_, e) => check_const(ccx, e, it.id), + hir::ItemConst(_, e) => check_const(tcx, e, it.id), hir::ItemEnum(ref enum_definition, _) => { - check_enum_variants(ccx, + check_enum_variants(tcx, it.span, &enum_definition.variants, it.id); @@ -868,48 +865,48 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { hir::ItemFn(..) => {} // entirely within check_item_body hir::ItemImpl(.., ref impl_item_refs) => { debug!("ItemImpl {} with id {}", it.name, it.id); - let impl_def_id = ccx.tcx.hir.local_def_id(it.id); - if let Some(impl_trait_ref) = ccx.tcx.impl_trait_ref(impl_def_id) { - check_impl_items_against_trait(ccx, + let impl_def_id = tcx.hir.local_def_id(it.id); + if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) { + check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, impl_item_refs); let trait_def_id = impl_trait_ref.def_id; - check_on_unimplemented(ccx, trait_def_id, it); + check_on_unimplemented(tcx, trait_def_id, it); } } hir::ItemTrait(..) => { - let def_id = ccx.tcx.hir.local_def_id(it.id); - check_on_unimplemented(ccx, def_id, it); + let def_id = tcx.hir.local_def_id(it.id); + check_on_unimplemented(tcx, def_id, it); } hir::ItemStruct(..) => { - check_struct(ccx, it.id, it.span); + check_struct(tcx, it.id, it.span); } hir::ItemUnion(..) => { - check_union(ccx, it.id, it.span); + check_union(tcx, it.id, it.span); } hir::ItemTy(_, ref generics) => { - let def_id = ccx.tcx.hir.local_def_id(it.id); - let pty_ty = ccx.tcx.item_type(def_id); - check_bounds_are_used(ccx, generics, pty_ty); + let def_id = tcx.hir.local_def_id(it.id); + let pty_ty = tcx.item_type(def_id); + check_bounds_are_used(tcx, generics, pty_ty); } hir::ItemForeignMod(ref m) => { - check_abi(ccx, it.span, m.abi); + check_abi(tcx, it.span, m.abi); if m.abi == Abi::RustIntrinsic { for item in &m.items { - intrinsic::check_intrinsic_type(ccx, item); + intrinsic::check_intrinsic_type(tcx, item); } } else if m.abi == Abi::PlatformIntrinsic { for item in &m.items { - intrinsic::check_platform_intrinsic_type(ccx, item); + intrinsic::check_platform_intrinsic_type(tcx, item); } } else { for item in &m.items { - let generics = ccx.tcx.item_generics(ccx.tcx.hir.local_def_id(item.id)); + let generics = tcx.item_generics(tcx.hir.local_def_id(item.id)); if !generics.types.is_empty() { - let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044, + let mut err = struct_span_err!(tcx.sess, item.span, E0044, "foreign items may not have type parameters"); span_help!(&mut err, item.span, "consider using specialization instead of \ @@ -918,7 +915,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } if let hir::ForeignItemFn(ref fn_decl, _, _) = item.node { - require_c_abi_if_variadic(ccx.tcx, fn_decl, m.abi, item.span); + require_c_abi_if_variadic(tcx, fn_decl, m.abi, item.span); } } } @@ -927,10 +924,10 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) { } } -fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, item: &hir::Item) { - let generics = ccx.tcx.item_generics(def_id); + let generics = tcx.item_generics(def_id); if let Some(ref attr) = item.attrs.iter().find(|a| { a.check_name("rustc_on_unimplemented") }) { @@ -950,8 +947,8 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }) { Some(_) => (), None => { - let name = ccx.tcx.item_name(def_id); - span_err!(ccx.tcx.sess, attr.span, E0230, + let name = tcx.item_name(def_id); + span_err!(tcx.sess, attr.span, E0230, "there is no type parameter \ {} on trait {}", s, name); @@ -959,7 +956,7 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }, // `{:1}` and `{}` are not to be used Position::ArgumentIs(_) => { - span_err!(ccx.tcx.sess, attr.span, E0231, + span_err!(tcx.sess, attr.span, E0231, "only named substitution \ parameters are allowed"); } @@ -968,7 +965,7 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } else { struct_span_err!( - ccx.tcx.sess, attr.span, E0232, + tcx.sess, attr.span, E0232, "this attribute must have a value") .span_label(attr.span, &format!("attribute requires a value")) .note(&format!("eg `#[rustc_on_unimplemented = \"foo\"]`")) @@ -1026,7 +1023,7 @@ fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } -fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_span: Span, impl_id: DefId, impl_trait_ref: ty::TraitRef<'tcx>, @@ -1037,11 +1034,10 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, if impl_trait_ref.references_error() { return; } // Locate trait definition and items - let tcx = ccx.tcx; let trait_def = tcx.lookup_trait_def(impl_trait_ref.def_id); let mut overridden_associated_type = None; - let impl_items = || impl_item_refs.iter().map(|iiref| ccx.tcx.hir.impl_item(iiref.id)); + let impl_items = || impl_item_refs.iter().map(|iiref| tcx.hir.impl_item(iiref.id)); // Check existing impl methods to see if they are both present in trait // and compatible with trait signature @@ -1056,7 +1052,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, hir::ImplItemKind::Const(..) => { // Find associated const definition. if ty_trait_item.kind == ty::AssociatedKind::Const { - compare_const_impl(ccx, + compare_const_impl(tcx, &ty_impl_item, impl_item.span, &ty_trait_item, @@ -1080,7 +1076,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let trait_span = tcx.hir.span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssociatedKind::Method { let err_count = tcx.sess.err_count(); - compare_impl_method(ccx, + compare_impl_method(tcx, &ty_impl_item, impl_item.span, body_id.node_id, @@ -1090,7 +1086,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, true); // start with old-broken-mode if err_count == tcx.sess.err_count() { // old broken mode did not report an error. Try with the new mode. - compare_impl_method(ccx, + compare_impl_method(tcx, &ty_impl_item, impl_item.span, body_id.node_id, @@ -1203,12 +1199,12 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } /// Checks a constant with a given type. -fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, +fn check_const_with_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, body: hir::BodyId, expected_type: Ty<'tcx>, id: ast::NodeId) { - let body = ccx.tcx.hir.body(body); - ccx.inherited(id).enter(|inh| { + let body = tcx.hir.body(body); + Inherited::build(tcx, id).enter(|inh| { let fcx = FnCtxt::new(&inh, None, body.value.id); fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized); @@ -1231,11 +1227,11 @@ fn check_const_with_type<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, }); } -fn check_const<'a, 'tcx>(ccx: &CrateCtxt<'a,'tcx>, +fn check_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, body: hir::BodyId, id: ast::NodeId) { - let decl_ty = ccx.tcx.item_type(ccx.tcx.hir.local_def_id(id)); - check_const_with_type(ccx, body, decl_ty, id); + let decl_ty = tcx.item_type(tcx.hir.local_def_id(id)); + check_const_with_type(tcx, body, decl_ty, id); } /// Checks whether a type can be represented in memory. In particular, it @@ -1293,53 +1289,53 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId } #[allow(trivial_numeric_casts)] -pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, - sp: Span, - vs: &'tcx [hir::Variant], - id: ast::NodeId) { - let def_id = ccx.tcx.hir.local_def_id(id); - let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny); +pub fn check_enum_variants<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + sp: Span, + vs: &'tcx [hir::Variant], + id: ast::NodeId) { + let def_id = tcx.hir.local_def_id(id); + let hint = *tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny); if hint != attr::ReprAny && vs.is_empty() { struct_span_err!( - ccx.tcx.sess, sp, E0084, + tcx.sess, sp, E0084, "unsupported representation for zero-variant enum") .span_label(sp, &format!("unsupported enum representation")) .emit(); } - let repr_type_ty = ccx.tcx.enum_repr_type(Some(&hint)).to_ty(ccx.tcx); - if repr_type_ty == ccx.tcx.types.i128 || repr_type_ty == ccx.tcx.types.u128 { - if !ccx.tcx.sess.features.borrow().i128_type { - emit_feature_err(&ccx.tcx.sess.parse_sess, + let repr_type_ty = tcx.enum_repr_type(Some(&hint)).to_ty(tcx); + if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 { + if !tcx.sess.features.borrow().i128_type { + emit_feature_err(&tcx.sess.parse_sess, "i128_type", sp, GateIssue::Language, "128-bit type is unstable"); } } for v in vs { if let Some(e) = v.node.disr_expr { - check_const_with_type(ccx, e, repr_type_ty, e.node_id); + check_const_with_type(tcx, e, repr_type_ty, e.node_id); } } - let def_id = ccx.tcx.hir.local_def_id(id); + let def_id = tcx.hir.local_def_id(id); - let def = ccx.tcx.lookup_adt_def(def_id); + let def = tcx.lookup_adt_def(def_id); let mut disr_vals: Vec = Vec::new(); - for (discr, v) in def.discriminants(ccx.tcx).zip(vs) { + for (discr, v) in def.discriminants(tcx).zip(vs) { // Check for duplicate discriminant values if let Some(i) = disr_vals.iter().position(|&x| x == discr) { - let variant_i_node_id = ccx.tcx.hir.as_local_node_id(def.variants[i].did).unwrap(); - let variant_i = ccx.tcx.hir.expect_variant(variant_i_node_id); + let variant_i_node_id = tcx.hir.as_local_node_id(def.variants[i].did).unwrap(); + let variant_i = tcx.hir.expect_variant(variant_i_node_id); let i_span = match variant_i.node.disr_expr { - Some(expr) => ccx.tcx.hir.span(expr.node_id), - None => ccx.tcx.hir.span(variant_i_node_id) + Some(expr) => tcx.hir.span(expr.node_id), + None => tcx.hir.span(variant_i_node_id) }; let span = match v.node.disr_expr { - Some(expr) => ccx.tcx.hir.span(expr.node_id), + Some(expr) => tcx.hir.span(expr.node_id), None => v.span }; - struct_span_err!(ccx.tcx.sess, span, E0081, + struct_span_err!(tcx.sess, span, E0081, "discriminant value `{}` already exists", disr_vals[i]) .span_label(i_span, &format!("first use of `{}`", disr_vals[i])) .span_label(span , &format!("enum already has `{}`", disr_vals[i])) @@ -1348,7 +1344,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, disr_vals.push(discr); } - check_representable(ccx.tcx, sp, def_id); + check_representable(tcx, sp, def_id); } impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { @@ -1504,10 +1500,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - pub fn param_env(&self) -> &ty::ParameterEnvironment<'gcx> { - &self.parameter_environment - } - pub fn sess(&self) -> &Session { &self.tcx.sess } @@ -1754,10 +1746,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.write_ty(node_id, self.tcx.mk_nil()); } - pub fn write_never(&self, node_id: ast::NodeId) { - self.write_ty(node_id, self.tcx.types.never); - } - pub fn write_error(&self, node_id: ast::NodeId) { self.write_ty(node_id, self.tcx.types.err); } @@ -4303,7 +4291,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let container = self.tcx.associated_item(def_id).container; match container { ty::TraitContainer(trait_did) => { - callee::check_legal_trait_for_method_call(self.ccx, span, trait_did) + callee::check_legal_trait_for_method_call(self.tcx, span, trait_did) } ty::ImplContainer(_) => {} } @@ -4624,7 +4612,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } -pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, generics: &hir::Generics, ty: Ty<'tcx>) { debug!("check_bounds_are_used(n_tps={}, ty={:?})", @@ -4643,7 +4631,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, for (&used, param) in tps_used.iter().zip(&generics.ty_params) { if !used { - struct_span_err!(ccx.tcx.sess, param.span, E0091, + struct_span_err!(tcx.sess, param.span, E0091, "type parameter `{}` is unused", param.name) .span_label(param.span, &format!("unused type parameter")) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index d84e9d3fd3731..a120e3c343155 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -102,8 +102,6 @@ use syntax_pos::Span; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::{self, PatKind}; -use self::SubjectNode::Subject; - // a variation on try that just returns unit macro_rules! ignore_err { ($e:expr) => (match $e { Ok(e) => e, Err(_) => return () }) @@ -183,7 +181,7 @@ pub struct RegionCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { repeating_scope: ast::NodeId, // id of AST node being analyzed (the subject of the analysis). - subject: SubjectNode, + subject: ast::NodeId, } @@ -195,14 +193,13 @@ impl<'a, 'gcx, 'tcx> Deref for RegionCtxt<'a, 'gcx, 'tcx> { } pub struct RepeatingScope(ast::NodeId); -pub enum SubjectNode { Subject(ast::NodeId), None } +pub struct Subject(ast::NodeId); impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { pub fn new(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, - initial_repeating_scope: RepeatingScope, + RepeatingScope(initial_repeating_scope): RepeatingScope, initial_body_id: ast::NodeId, - subject: SubjectNode) -> RegionCtxt<'a, 'gcx, 'tcx> { - let RepeatingScope(initial_repeating_scope) = initial_repeating_scope; + Subject(subject): Subject) -> RegionCtxt<'a, 'gcx, 'tcx> { RegionCtxt { fcx: fcx, repeating_scope: initial_repeating_scope, @@ -416,13 +413,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } fn resolve_regions_and_report_errors(&self) { - let subject_node_id = match self.subject { - Subject(s) => s, - SubjectNode::None => { - bug!("cannot resolve_regions_and_report_errors \ - without subject node"); - } - }; + let subject_node_id = self.subject; self.fcx.resolve_regions_and_report_errors(&self.free_region_map, subject_node_id); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index cef6a75e58dc9..533223546ad56 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -9,9 +9,8 @@ // except according to those terms. use astconv::ExplicitSelf; -use check::FnCtxt; +use check::{Inherited, FnCtxt}; use constrained_type_params::{identify_constrained_type_params, Parameter}; -use CrateCtxt; use hir::def_id::DefId; use middle::region::{CodeExtent}; @@ -27,8 +26,8 @@ use errors::DiagnosticBuilder; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> { - ccx: &'ccx CrateCtxt<'ccx, 'tcx>, +pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, code: ObligationCauseCode<'tcx>, } @@ -51,9 +50,9 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { let id = self.id; let span = self.span; self.inherited.enter(|inh| { - let fcx = FnCtxt::new(&inh, Some(inh.ccx.tcx.types.never), id); + let fcx = FnCtxt::new(&inh, None, id); let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor { - ccx: fcx.ccx, + tcx: fcx.tcx.global_tcx(), code: code }); fcx.select_all_obligations_or_error(); @@ -62,19 +61,15 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { } } -impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { - pub fn new(ccx: &'ccx CrateCtxt<'ccx, 'gcx>) - -> CheckTypeWellFormedVisitor<'ccx, 'gcx> { +impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) + -> CheckTypeWellFormedVisitor<'a, 'gcx> { CheckTypeWellFormedVisitor { - ccx: ccx, + tcx: tcx, code: ObligationCauseCode::MiscObligation } } - fn tcx(&self) -> TyCtxt<'ccx, 'gcx, 'gcx> { - self.ccx.tcx - } - /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are /// well-formed, meaning that they do not require any constraints not declared in the struct /// definition itself. For example, this definition would be illegal: @@ -87,10 +82,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. fn check_item_well_formed(&mut self, item: &hir::Item) { - let ccx = self.ccx; + let tcx = self.tcx; debug!("check_item_well_formed(it.id={}, it.name={})", item.id, - ccx.tcx.item_path_str(ccx.tcx.hir.local_def_id(item.id))); + tcx.item_path_str(tcx.hir.local_def_id(item.id))); match item.node { /// Right now we check that every default trait implementation @@ -117,9 +112,9 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { hir::ItemImpl(_, hir::ImplPolarity::Negative, _, Some(_), ..) => { // FIXME(#27579) what amount of WF checking do we need for neg impls? - let trait_ref = ccx.tcx.impl_trait_ref(ccx.tcx.hir.local_def_id(item.id)).unwrap(); - if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) { - error_192(ccx, item.span); + let trait_ref = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)).unwrap(); + if !tcx.trait_has_default_impl(trait_ref.def_id) { + error_192(tcx, item.span); } } hir::ItemFn(.., body_id) => { @@ -211,14 +206,14 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } fn for_item<'tcx>(&self, item: &hir::Item) - -> CheckWfFcxBuilder<'ccx, 'gcx, 'tcx> { + -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { self.for_id(item.id, item.span) } fn for_id<'tcx>(&self, id: ast::NodeId, span: Span) - -> CheckWfFcxBuilder<'ccx, 'gcx, 'tcx> { + -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { CheckWfFcxBuilder { - inherited: self.ccx.inherited(id), + inherited: Inherited::build(self.tcx, id), code: self.code.clone(), id: id, span: span @@ -270,7 +265,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { // // 3) that the trait definition does not have any type parameters - let predicates = self.tcx().item_predicates(trait_def_id); + let predicates = self.tcx.item_predicates(trait_def_id); // We must exclude the Self : Trait predicate contained by all // traits. @@ -285,7 +280,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } }); - let has_ty_params = self.tcx().item_generics(trait_def_id).types.len() > 1; + let has_ty_params = self.tcx.item_generics(trait_def_id).types.len() > 1; // We use an if-else here, since the generics will also trigger // an extraneous error message when we find predicates like @@ -296,14 +291,14 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { // extraneous predicates created by things like // an associated type inside the trait. let mut err = None; - if !self.tcx().associated_item_def_ids(trait_def_id).is_empty() { - error_380(self.ccx, span); + if !self.tcx.associated_item_def_ids(trait_def_id).is_empty() { + error_380(self.tcx, span); } else if has_ty_params { - err = Some(struct_span_err!(self.tcx().sess, span, E0567, + err = Some(struct_span_err!(self.tcx.sess, span, E0567, "traits with auto impls (`e.g. impl \ Trait for ..`) can not have type parameters")); } else if has_predicates { - err = Some(struct_span_err!(self.tcx().sess, span, E0568, + err = Some(struct_span_err!(self.tcx.sess, span, E0568, "traits with auto impls (`e.g. impl \ Trait for ..`) cannot have predicates")); } @@ -321,9 +316,9 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { } fn check_trait(&mut self, item: &hir::Item) { - let trait_def_id = self.tcx().hir.local_def_id(item.id); + let trait_def_id = self.tcx.hir.local_def_id(item.id); - if self.tcx().trait_has_default_impl(trait_def_id) { + if self.tcx.trait_has_default_impl(trait_def_id) { self.check_auto_trait(trait_def_id, item.span); } @@ -514,15 +509,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { item: &hir::Item, ast_generics: &hir::Generics) { - let item_def_id = self.tcx().hir.local_def_id(item.id); - let ty = self.tcx().item_type(item_def_id); - if self.tcx().has_error_field(ty) { + let item_def_id = self.tcx.hir.local_def_id(item.id); + let ty = self.tcx.item_type(item_def_id); + if self.tcx.has_error_field(ty) { return; } - let ty_predicates = self.tcx().item_predicates(item_def_id); + let ty_predicates = self.tcx.item_predicates(item_def_id); assert_eq!(ty_predicates.parent, None); - let variances = self.tcx().item_variances(item_def_id); + let variances = self.tcx.item_variances(item_def_id); let mut constrained_parameters: FxHashSet<_> = variances.iter().enumerate() @@ -555,15 +550,15 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> { span: Span, param_name: ast::Name) { - let mut err = error_392(self.ccx, span, param_name); + let mut err = error_392(self.tcx, span, param_name); - let suggested_marker_id = self.tcx().lang_items.phantom_data(); + let suggested_marker_id = self.tcx.lang_items.phantom_data(); match suggested_marker_id { Some(def_id) => { err.help( &format!("consider removing `{}` or using a marker such as `{}`", param_name, - self.tcx().item_path_str(def_id))); + self.tcx.item_path_str(def_id))); } None => { // no lang items, no help! @@ -595,7 +590,7 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { } } -impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { +impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { NestedVisitorMap::None } @@ -681,21 +676,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } -fn error_192(ccx: &CrateCtxt, span: Span) { - span_err!(ccx.tcx.sess, span, E0192, +fn error_192(tcx: TyCtxt, span: Span) { + span_err!(tcx.sess, span, E0192, "negative impls are only allowed for traits with \ default impls (e.g., `Send` and `Sync`)") } -fn error_380(ccx: &CrateCtxt, span: Span) { - span_err!(ccx.tcx.sess, span, E0380, +fn error_380(tcx: TyCtxt, span: Span) { + span_err!(tcx.sess, span, E0380, "traits with default impls (`e.g. impl \ Trait for ..`) must have no methods or associated items") } -fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name) +fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name) -> DiagnosticBuilder<'tcx> { - let mut err = struct_span_err!(ccx.tcx.sess, span, E0392, + let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name); err.span_label(span, &format!("unused type parameter")); err diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 650f32eb6b216..f7f004fbaef12 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -491,7 +491,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { }).collect(); if !obligations.is_empty() { - assert!(self.fcx.ccx.deferred_obligations.borrow_mut() + assert!(self.fcx.tcx.deferred_obligations.borrow_mut() .insert(item_id, obligations).is_none()); } } @@ -499,7 +499,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { fn visit_type_nodes(&self) { for (&id, ty) in self.fcx.ast_ty_to_ty_cache.borrow().iter() { let ty = self.resolve(ty, ResolvingTyNode(id)); - self.fcx.ccx.ast_ty_to_ty_cache.borrow_mut().insert(id, ty); + self.fcx.tcx.ast_ty_to_ty_cache.borrow_mut().insert(id, ty); } } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 4aa0650e57f71..ed5ca79a70661 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -24,7 +24,6 @@ use rustc::ty::{TyRef, TyAdt, TyDynamic, TyNever, TyTuple}; use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt}; use rustc::ty::{TyUint, TyClosure, TyFnDef, TyFnPtr}; use rustc::ty::{TyProjection, TyAnon}; -use CrateCtxt; use syntax_pos::Span; use rustc::dep_graph::DepNode; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -176,12 +175,12 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, sp: Span, trait_def_id: Def err.emit(); } -pub fn check_coherence(ccx: &CrateCtxt) { - CoherenceCollect::check(ccx.tcx); +pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + CoherenceCollect::check(tcx); - let _task = ccx.tcx.dep_graph.in_task(DepNode::Coherence); - unsafety::check(ccx.tcx); - orphan::check(ccx.tcx); - overlap::check(ccx.tcx); - builtin::check(ccx.tcx); + let _task = tcx.dep_graph.in_task(DepNode::Coherence); + unsafety::check(tcx); + orphan::check(tcx); + overlap::check(tcx); + builtin::check(tcx); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 90d12b26c6a62..95fd123b7df4c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -72,7 +72,6 @@ use rustc::ty::util::IntTypeExt; use rustc::dep_graph::DepNode; use util::common::{ErrorReported, MemoizationMap}; use util::nodemap::{NodeMap, FxHashMap}; -use CrateCtxt; use rustc_const_math::ConstInt; @@ -91,9 +90,9 @@ use rustc::hir::def_id::DefId; /////////////////////////////////////////////////////////////////////////// // Main entry point -pub fn collect_item_types(ccx: &CrateCtxt) { - let mut visitor = CollectItemTypesVisitor { ccx: ccx }; - ccx.tcx.visit_all_item_likes_in_krate(DepNode::CollectItem, &mut visitor.as_deep_visitor()); +pub fn collect_item_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + let mut visitor = CollectItemTypesVisitor { tcx: tcx }; + tcx.visit_all_item_likes_in_krate(DepNode::CollectItem, &mut visitor.as_deep_visitor()); } /////////////////////////////////////////////////////////////////////////// @@ -108,21 +107,14 @@ pub fn collect_item_types(ccx: &CrateCtxt) { /// `get_type_parameter_bounds` requests, drawing the information from /// the AST (`hir::Generics`), recursively. struct ItemCtxt<'a,'tcx:'a> { - ccx: &'a CrateCtxt<'a,'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId, } -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum AstConvRequest { - GetItemType(DefId), - EnsureSuperPredicates(DefId), - GetTypeParameterBounds(ast::NodeId), -} - /////////////////////////////////////////////////////////////////////////// struct CollectItemTypesVisitor<'a, 'tcx: 'a> { - ccx: &'a CrateCtxt<'a, 'tcx> + tcx: TyCtxt<'a, 'tcx, 'tcx> } impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> { @@ -166,9 +158,9 @@ impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> { fn with_collect_item_sig(&self, id: ast::NodeId, op: OP) where OP: FnOnce() { - let def_id = self.ccx.tcx.hir.local_def_id(id); - self.ccx.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), || { - self.ccx.tcx.hir.read(id); + let def_id = self.tcx.hir.local_def_id(id); + self.tcx.dep_graph.with_task(DepNode::CollectItemSig(def_id), || { + self.tcx.hir.read(id); op(); }); } @@ -176,19 +168,19 @@ impl<'a, 'tcx> CollectItemTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::OnlyBodies(&self.ccx.tcx.hir) + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { - self.with_collect_item_sig(item.id, || convert_item(self.ccx, item)); + self.with_collect_item_sig(item.id, || convert_item(self.tcx, item)); intravisit::walk_item(self, item); } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { for param in &generics.ty_params { if param.default.is_some() { - let def_id = self.ccx.tcx.hir.local_def_id(param.id); - type_of_def_id(self.ccx, def_id); + let def_id = self.tcx.hir.local_def_id(param.id); + type_of_def_id(self.tcx, def_id); } } intravisit::walk_generics(self, generics); @@ -196,31 +188,31 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr) { if let hir::ExprClosure(..) = expr.node { - let def_id = self.ccx.tcx.hir.local_def_id(expr.id); - generics_of_def_id(self.ccx, def_id); - type_of_def_id(self.ccx, def_id); + let def_id = self.tcx.hir.local_def_id(expr.id); + generics_of_def_id(self.tcx, def_id); + type_of_def_id(self.tcx, def_id); } intravisit::walk_expr(self, expr); } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { if let hir::TyImplTrait(..) = ty.node { - let def_id = self.ccx.tcx.hir.local_def_id(ty.id); - generics_of_def_id(self.ccx, def_id); + let def_id = self.tcx.hir.local_def_id(ty.id); + generics_of_def_id(self.tcx, def_id); } intravisit::walk_ty(self, ty); } fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { self.with_collect_item_sig(trait_item.id, || { - convert_trait_item(self.ccx, trait_item) + convert_trait_item(self.tcx, trait_item) }); intravisit::walk_trait_item(self, trait_item); } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { self.with_collect_item_sig(impl_item.id, || { - convert_impl_item(self.ccx, impl_item) + convert_impl_item(self.tcx, impl_item) }); intravisit::walk_impl_item(self, impl_item); } @@ -229,127 +221,100 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // Utility types and common code for the above passes. -impl<'a,'tcx> CrateCtxt<'a,'tcx> { - fn icx(&'a self, item_def_id: DefId) -> ItemCtxt<'a,'tcx> { +impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { + fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) + -> ItemCtxt<'a,'tcx> { ItemCtxt { - ccx: self, + tcx: tcx, item_def_id: item_def_id, } } +} - fn cycle_check(&self, + fn cycle_check(tcx: TyCtxt, span: Span, - request: AstConvRequest, + query: ty::maps::Query, code: F) -> Result where F: FnOnce() -> Result { { - let mut stack = self.stack.borrow_mut(); - if let Some((i, _)) = stack.iter().enumerate().rev().find(|&(_, r)| *r == request) { + let mut stack = tcx.maps.query_stack.borrow_mut(); + if let Some((i, _)) = stack.iter().enumerate().rev().find(|&(_, q)| *q == query) { let cycle = &stack[i..]; - self.report_cycle(span, cycle); + report_cycle(tcx, span, cycle); return Err(ErrorReported); } - stack.push(request); + stack.push(query); } let result = code(); - self.stack.borrow_mut().pop(); + tcx.maps.query_stack.borrow_mut().pop(); result } - fn report_cycle(&self, + fn report_cycle(tcx: TyCtxt, span: Span, - cycle: &[AstConvRequest]) + cycle: &[ty::maps::Query]) { assert!(!cycle.is_empty()); - let tcx = self.tcx; let mut err = struct_span_err!(tcx.sess, span, E0391, "unsupported cyclic reference between types/traits detected"); err.span_label(span, &format!("cyclic reference")); - match cycle[0] { - AstConvRequest::GetItemType(def_id) => { - err.note( - &format!("the cycle begins when processing `{}`...", - tcx.item_path_str(def_id))); - } - AstConvRequest::EnsureSuperPredicates(def_id) => { - err.note( - &format!("the cycle begins when computing the supertraits of `{}`...", - tcx.item_path_str(def_id))); - } - AstConvRequest::GetTypeParameterBounds(id) => { - err.note( - &format!("the cycle begins when computing the bounds \ - for type parameter `{}`...", - ::ty_param_name(tcx, id))); - } - } - - for request in &cycle[1..] { - match *request { - AstConvRequest::GetItemType(def_id) => { - err.note( - &format!("...which then requires processing `{}`...", - tcx.item_path_str(def_id))); + let describe = |query: ty::maps::Query| { + match query { + ty::maps::Query::ty(def_id) => { + format!("processing `{}`", tcx.item_path_str(def_id)) } - AstConvRequest::EnsureSuperPredicates(def_id) => { - err.note( - &format!("...which then requires computing the supertraits of `{}`...", - tcx.item_path_str(def_id))); + ty::maps::Query::super_predicates(def_id) => { + format!("computing the supertraits of `{}`", + tcx.item_path_str(def_id)) } - AstConvRequest::GetTypeParameterBounds(id) => { - err.note( - &format!("...which then requires computing the bounds \ - for type parameter `{}`...", - ::ty_param_name(tcx, id))); + ty::maps::Query::type_param_predicates(def_id) => { + let id = tcx.hir.as_local_node_id(def_id).unwrap(); + format!("the cycle begins when computing the bounds \ + for type parameter `{}`", + ::ty_param_name(tcx, id)) } + query => span_bug!(span, "unexpected `{:?}`", query) } - } + }; - match cycle[0] { - AstConvRequest::GetItemType(def_id) => { - err.note( - &format!("...which then again requires processing `{}`, completing the cycle.", - tcx.item_path_str(def_id))); - } - AstConvRequest::EnsureSuperPredicates(def_id) => { - err.note( - &format!("...which then again requires computing the supertraits of `{}`, \ - completing the cycle.", - tcx.item_path_str(def_id))); - } - AstConvRequest::GetTypeParameterBounds(id) => { - err.note( - &format!("...which then again requires computing the bounds \ - for type parameter `{}`, completing the cycle.", - ::ty_param_name(tcx, id))); - } + err.note(&format!("the cycle begins when {}...", + describe(cycle[0]))); + + for &query in &cycle[1..] { + err.note(&format!("...which then requires {}...", + describe(query))); } + + err.note(&format!("...which then again requires {}, completing the cycle.", + describe(cycle[0]))); + err.emit(); } /// Ensure that the (transitive) super predicates for /// `trait_def_id` are available. This will report a cycle error /// if a trait `X` (transitively) extends itself in some form. - fn ensure_super_predicates(&self, span: Span, trait_def_id: DefId) - -> Result<(), ErrorReported> + fn ensure_super_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + span: Span, + trait_def_id: DefId) + -> Result<(), ErrorReported> { - self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || { - let def_ids = ensure_super_predicates_step(self, trait_def_id); + cycle_check(tcx, span, ty::maps::Query::super_predicates(trait_def_id), || { + let def_ids = ensure_super_predicates_step(tcx, trait_def_id); for def_id in def_ids { - self.ensure_super_predicates(span, def_id)?; + ensure_super_predicates(tcx, span, def_id)?; } Ok(()) }) } -} impl<'a,'tcx> ItemCtxt<'a,'tcx> { fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> { @@ -358,27 +323,27 @@ impl<'a,'tcx> ItemCtxt<'a,'tcx> { } impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.ccx.tcx } + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { self.tcx } fn ast_ty_to_ty_cache(&self) -> &RefCell>> { - &self.ccx.ast_ty_to_ty_cache + &self.tcx.ast_ty_to_ty_cache } fn get_generics(&self, id: DefId) -> &'tcx ty::Generics { - generics_of_def_id(self.ccx, id) + generics_of_def_id(self.tcx, id) } fn get_item_type(&self, span: Span, id: DefId) -> Ty<'tcx> { - self.ccx.cycle_check(span, AstConvRequest::GetItemType(id), || { - Ok(type_of_def_id(self.ccx, id)) - }).unwrap_or(self.ccx.tcx.types.err) + cycle_check(self.tcx, span, ty::maps::Query::ty(id), || { + Ok(type_of_def_id(self.tcx, id)) + }).unwrap_or(self.tcx.types.err) } fn get_trait_def(&self, def_id: DefId) -> &'tcx ty::TraitDef { - let tcx = self.ccx.tcx; + let tcx = self.tcx; if let Some(trait_id) = tcx.hir.as_local_node_id(def_id) { - trait_def_of_item(self.ccx, tcx.hir.expect_item(trait_id)) + trait_def_of_item(self.tcx, tcx.hir.expect_item(trait_id)) } else { tcx.lookup_trait_def(def_id) } @@ -392,7 +357,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { debug!("ensure_super_predicates(trait_def_id={:?})", trait_def_id); - self.ccx.ensure_super_predicates(span, trait_def_id) + ensure_super_predicates(self.tcx, span, trait_def_id) } fn get_type_parameter_bounds(&self, @@ -400,8 +365,9 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { node_id: ast::NodeId) -> Result>, ErrorReported> { - self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || { - let v = self.ccx.get_type_parameter_bounds(self.item_def_id, node_id) + let def_id = self.tcx.hir.local_def_id(node_id); + cycle_check(self.tcx, span, ty::maps::Query::type_param_predicates(def_id), || { + let v = get_type_parameter_bounds(self.tcx, self.item_def_id, node_id) .into_iter() .filter_map(|p| p.to_opt_poly_trait_ref()) .collect(); @@ -460,11 +426,10 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { } } -impl<'a, 'tcx> CrateCtxt<'a, 'tcx> { - fn get_type_parameter_bounds(&self, - item_def_id: DefId, - param_id: ast::NodeId) - -> Vec> + fn get_type_parameter_bounds<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_def_id: DefId, + param_id: ast::NodeId) + -> Vec> { use rustc::hir::map::*; use rustc::hir::*; @@ -473,9 +438,8 @@ impl<'a, 'tcx> CrateCtxt<'a, 'tcx> { // written inline like `` or in a where clause like // `where T:Foo`. - let tcx = self.tcx; let param_owner_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, param_id)); - let generics = generics_of_def_id(self, param_owner_def_id); + let generics = generics_of_def_id(tcx, param_owner_def_id); let index = generics.type_param_to_index[&tcx.hir.local_def_id(param_id).index]; let ty = tcx.mk_param(index, ::ty_param_name(tcx, param_id)); @@ -483,11 +447,11 @@ impl<'a, 'tcx> CrateCtxt<'a, 'tcx> { let parent = if item_def_id == param_owner_def_id { None } else { - generics_of_def_id(self, item_def_id).parent + generics_of_def_id(tcx, item_def_id).parent }; let mut results = parent.map_or(vec![], |def_id| { - self.get_type_parameter_bounds(def_id, param_id) + get_type_parameter_bounds(tcx, def_id, param_id) }); let item_node_id = tcx.hir.as_local_node_id(item_def_id).unwrap(); @@ -519,7 +483,7 @@ impl<'a, 'tcx> CrateCtxt<'a, 'tcx> { if param_id == item_node_id { results.push(ty::TraitRef { def_id: item_def_id, - substs: mk_item_substs(self, item_def_id) + substs: mk_item_substs(tcx, item_def_id) }.to_predicate()); } generics @@ -538,11 +502,10 @@ impl<'a, 'tcx> CrateCtxt<'a, 'tcx> { _ => return results }; - let icx = self.icx(item_def_id); + let icx = ItemCtxt::new(tcx, item_def_id); results.extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty)); results } -} impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { /// Find bounds from hir::Generics. This requires scanning through the @@ -570,7 +533,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { hir::WherePredicate::BoundPredicate(ref bp) => Some(bp), _ => None }) - .filter(|bp| is_param(self.ccx.tcx, &bp.bounded_ty, param_id)) + .filter(|bp| is_param(self.tcx, &bp.bounded_ty, param_id)) .flat_map(|bp| bp.bounds.iter()) .flat_map(|b| predicates_from_bound(self, ty, b)); @@ -600,31 +563,33 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_field<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, field: &hir::StructField, ty_f: &'tcx ty::FieldDef) { - generics_of_def_id(ccx, ty_f.did); - let tt = ccx.icx(ty_f.did).to_ty(&field.ty); - ccx.tcx.maps.ty.borrow_mut().insert(ty_f.did, tt); - ccx.tcx.maps.predicates.borrow_mut().insert(ty_f.did, ty::GenericPredicates { - parent: Some(ccx.tcx.hir.get_parent_did(field.id)), + generics_of_def_id(tcx, ty_f.did); + let tt = ItemCtxt::new(tcx, ty_f.did).to_ty(&field.ty); + tcx.maps.ty.borrow_mut().insert(ty_f.did, tt); + tcx.maps.predicates.borrow_mut().insert(ty_f.did, ty::GenericPredicates { + parent: Some(tcx.hir.get_parent_did(field.id)), predicates: vec![] }); } -fn convert_method(ccx: &CrateCtxt, id: ast::NodeId, sig: &hir::MethodSig) { - let def_id = ccx.tcx.hir.local_def_id(id); +fn convert_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + id: ast::NodeId, + sig: &hir::MethodSig) { + let def_id = tcx.hir.local_def_id(id); - let fty = AstConv::ty_of_fn(&ccx.icx(def_id), sig.unsafety, sig.abi, &sig.decl); - let substs = mk_item_substs(ccx, def_id); - let fty = ccx.tcx.mk_fn_def(def_id, substs, fty); - ccx.tcx.maps.ty.borrow_mut().insert(def_id, fty); + let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), sig.unsafety, sig.abi, &sig.decl); + let substs = mk_item_substs(tcx, def_id); + let fty = tcx.mk_fn_def(def_id, substs, fty); + tcx.maps.ty.borrow_mut().insert(def_id, fty); - ty_generic_predicates(ccx, def_id, &sig.generics); + ty_generic_predicates(tcx, def_id, &sig.generics); } -fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_associated_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, container: AssociatedItemContainer, id: ast::NodeId, ty: ty::Ty<'tcx>) @@ -633,12 +598,12 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, parent: Some(container.id()), predicates: vec![] }; - let def_id = ccx.tcx.hir.local_def_id(id); - ccx.tcx.maps.predicates.borrow_mut().insert(def_id, predicates); - ccx.tcx.maps.ty.borrow_mut().insert(def_id, ty); + let def_id = tcx.hir.local_def_id(id); + tcx.maps.predicates.borrow_mut().insert(def_id, predicates); + tcx.maps.ty.borrow_mut().insert(def_id, ty); } -fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_associated_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, container: AssociatedItemContainer, id: ast::NodeId, ty: Option>) @@ -647,18 +612,18 @@ fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, parent: Some(container.id()), predicates: vec![] }; - let def_id = ccx.tcx.hir.local_def_id(id); - ccx.tcx.maps.predicates.borrow_mut().insert(def_id, predicates); + let def_id = tcx.hir.local_def_id(id); + tcx.maps.predicates.borrow_mut().insert(def_id, predicates); if let Some(ty) = ty { - ccx.tcx.maps.ty.borrow_mut().insert(def_id, ty); + tcx.maps.ty.borrow_mut().insert(def_id, ty); } } -fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, - span: Span, - generics: &hir::Generics, - thing: &'static str) { +fn ensure_no_ty_param_bounds(tcx: TyCtxt, + span: Span, + generics: &hir::Generics, + thing: &'static str) { let mut warn = false; for ty_param in generics.ty_params.iter() { @@ -687,33 +652,32 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, // eventually accept these, but it will not be // part of this PR. Still, convert to warning to // make bootstrapping easier. - span_warn!(ccx.tcx.sess, span, E0122, + span_warn!(tcx.sess, span, E0122, "trait bounds are not (yet) enforced \ in {} definitions", thing); } } -fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { - let tcx = ccx.tcx; +fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::Item) { debug!("convert: item {} with id {}", it.name, it.id); - let def_id = ccx.tcx.hir.local_def_id(it.id); - let icx = ccx.icx(def_id); + let def_id = tcx.hir.local_def_id(it.id); + let icx = ItemCtxt::new(tcx, def_id); match it.node { // These don't define types. hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => { } hir::ItemForeignMod(ref foreign_mod) => { for item in &foreign_mod.items { - convert_foreign_item(ccx, item); + convert_foreign_item(tcx, item); } } hir::ItemEnum(ref enum_definition, _) => { - generics_of_def_id(ccx, def_id); - predicates_of_item(ccx, it); - let ty = type_of_def_id(ccx, def_id); - convert_enum_variant_types(ccx, - tcx.lookup_adt_def(ccx.tcx.hir.local_def_id(it.id)), + generics_of_def_id(tcx, def_id); + predicates_of_item(tcx, it); + let ty = type_of_def_id(tcx, def_id); + convert_enum_variant_types(tcx, + tcx.lookup_adt_def(tcx.hir.local_def_id(it.id)), ty, &enum_definition.variants); }, @@ -725,157 +689,151 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { tcx.record_trait_has_default_impl(trait_ref.def_id); - tcx.maps.impl_trait_ref.borrow_mut().insert(ccx.tcx.hir.local_def_id(it.id), + tcx.maps.impl_trait_ref.borrow_mut().insert(tcx.hir.local_def_id(it.id), Some(trait_ref)); } hir::ItemImpl(.., ref opt_trait_ref, _, _) => { - generics_of_def_id(ccx, def_id); - let selfty = type_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); + let selfty = type_of_def_id(tcx, def_id); let trait_ref = opt_trait_ref.as_ref().map(|ast_trait_ref| { AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) }); tcx.maps.impl_trait_ref.borrow_mut().insert(def_id, trait_ref); - predicates_of_item(ccx, it); + predicates_of_item(tcx, it); }, hir::ItemTrait(..) => { - generics_of_def_id(ccx, def_id); - trait_def_of_item(ccx, it); + generics_of_def_id(tcx, def_id); + trait_def_of_item(tcx, it); let _: Result<(), ErrorReported> = // any error is already reported, can ignore - ccx.ensure_super_predicates(it.span, def_id); - predicates_of_item(ccx, it); + ensure_super_predicates(tcx, it.span, def_id); + predicates_of_item(tcx, it); }, hir::ItemStruct(ref struct_def, _) | hir::ItemUnion(ref struct_def, _) => { - generics_of_def_id(ccx, def_id); - predicates_of_item(ccx, it); - let ty = type_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); + predicates_of_item(tcx, it); + let ty = type_of_def_id(tcx, def_id); let variant = tcx.lookup_adt_def(def_id).struct_variant(); for (f, ty_f) in struct_def.fields().iter().zip(variant.fields.iter()) { - convert_field(ccx, f, ty_f) + convert_field(tcx, f, ty_f) } if !struct_def.is_struct() { - convert_variant_ctor(ccx, struct_def.id(), variant, ty); + convert_variant_ctor(tcx, struct_def.id(), variant, ty); } }, hir::ItemTy(_, ref generics) => { - ensure_no_ty_param_bounds(ccx, it.span, generics, "type"); - generics_of_def_id(ccx, def_id); - predicates_of_item(ccx, it); - type_of_def_id(ccx, def_id); + ensure_no_ty_param_bounds(tcx, it.span, generics, "type"); + generics_of_def_id(tcx, def_id); + predicates_of_item(tcx, it); + type_of_def_id(tcx, def_id); }, _ => { - generics_of_def_id(ccx, def_id); - predicates_of_item(ccx, it); - type_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); + predicates_of_item(tcx, it); + type_of_def_id(tcx, def_id); }, } } -fn convert_trait_item(ccx: &CrateCtxt, trait_item: &hir::TraitItem) { - let tcx = ccx.tcx; - +fn convert_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_item: &hir::TraitItem) { // we can lookup details about the trait because items are visited // before trait-items let trait_def_id = tcx.hir.get_parent_did(trait_item.id); - let def_id = ccx.tcx.hir.local_def_id(trait_item.id); + let def_id = tcx.hir.local_def_id(trait_item.id); match trait_item.node { hir::TraitItemKind::Const(ref ty, _) => { - generics_of_def_id(ccx, def_id); - let ty = ccx.icx(def_id).to_ty(&ty); - convert_associated_const(ccx, + generics_of_def_id(tcx, def_id); + let ty = ItemCtxt::new(tcx, def_id).to_ty(&ty); + convert_associated_const(tcx, TraitContainer(trait_def_id), trait_item.id, ty); } hir::TraitItemKind::Type(_, ref opt_ty) => { - generics_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); - let typ = opt_ty.as_ref().map(|ty| ccx.icx(def_id).to_ty(&ty)); + let typ = opt_ty.as_ref().map(|ty| ItemCtxt::new(tcx, def_id).to_ty(&ty)); - convert_associated_type(ccx, TraitContainer(trait_def_id), trait_item.id, typ); + convert_associated_type(tcx, TraitContainer(trait_def_id), trait_item.id, typ); } hir::TraitItemKind::Method(ref sig, _) => { - convert_method(ccx, trait_item.id, sig); + convert_method(tcx, trait_item.id, sig); } } } -fn convert_impl_item(ccx: &CrateCtxt, impl_item: &hir::ImplItem) { - let tcx = ccx.tcx; - +fn convert_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item: &hir::ImplItem) { // we can lookup details about the impl because items are visited // before impl-items let impl_def_id = tcx.hir.get_parent_did(impl_item.id); - let def_id = ccx.tcx.hir.local_def_id(impl_item.id); + let def_id = tcx.hir.local_def_id(impl_item.id); match impl_item.node { hir::ImplItemKind::Const(ref ty, _) => { - generics_of_def_id(ccx, def_id); - let ty = ccx.icx(def_id).to_ty(&ty); - convert_associated_const(ccx, + generics_of_def_id(tcx, def_id); + let ty = ItemCtxt::new(tcx, def_id).to_ty(&ty); + convert_associated_const(tcx, ImplContainer(impl_def_id), impl_item.id, ty); } hir::ImplItemKind::Type(ref ty) => { - generics_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); if tcx.impl_trait_ref(impl_def_id).is_none() { span_err!(tcx.sess, impl_item.span, E0202, "associated types are not allowed in inherent impls"); } - let typ = ccx.icx(def_id).to_ty(ty); + let typ = ItemCtxt::new(tcx, def_id).to_ty(ty); - convert_associated_type(ccx, ImplContainer(impl_def_id), impl_item.id, Some(typ)); + convert_associated_type(tcx, ImplContainer(impl_def_id), impl_item.id, Some(typ)); } hir::ImplItemKind::Method(ref sig, _) => { - convert_method(ccx, impl_item.id, sig); + convert_method(tcx, impl_item.id, sig); } } } -fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_variant_ctor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ctor_id: ast::NodeId, variant: &'tcx ty::VariantDef, ty: Ty<'tcx>) { - let tcx = ccx.tcx; let def_id = tcx.hir.local_def_id(ctor_id); - generics_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); let ctor_ty = match variant.ctor_kind { CtorKind::Fictive | CtorKind::Const => ty, CtorKind::Fn => { let inputs = variant.fields.iter().map(|field| tcx.item_type(field.did)); - let substs = mk_item_substs(ccx, def_id); + let substs = mk_item_substs(tcx, def_id); tcx.mk_fn_def(def_id, substs, tcx.mk_bare_fn(ty::BareFnTy { unsafety: hir::Unsafety::Normal, abi: abi::Abi::Rust, - sig: ty::Binder(ccx.tcx.mk_fn_sig(inputs, ty, false)) + sig: ty::Binder(tcx.mk_fn_sig(inputs, ty, false)) })) } }; tcx.maps.ty.borrow_mut().insert(def_id, ctor_ty); tcx.maps.predicates.borrow_mut().insert(def_id, ty::GenericPredicates { - parent: Some(ccx.tcx.hir.get_parent_did(ctor_id)), + parent: Some(tcx.hir.get_parent_did(ctor_id)), predicates: vec![] }); } -fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_enum_variant_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def: &'tcx ty::AdtDef, ty: Ty<'tcx>, variants: &[hir::Variant]) { - let tcx = ccx.tcx; let repr_hints = tcx.lookup_repr_hints(def.did); let repr_type = tcx.enum_repr_type(repr_hints.get(0)); let initial = repr_type.initial_discriminant(tcx); @@ -885,7 +843,7 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, for (variant, ty_variant) in variants.iter().zip(def.variants.iter()) { let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr()); prev_discr = Some(if let Some(e) = variant.node.disr_expr { - let result = evaluate_disr_expr(ccx, repr_type, e); + let result = evaluate_disr_expr(tcx, repr_type, e); let expr_did = tcx.hir.local_def_id(e.node_id); tcx.maps.monomorphic_const_eval.borrow_mut() @@ -906,28 +864,28 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }.unwrap_or(wrapped_discr)); for (f, ty_f) in variant.node.data.fields().iter().zip(ty_variant.fields.iter()) { - convert_field(ccx, f, ty_f) + convert_field(tcx, f, ty_f) } // Convert the ctor, if any. This also registers the variant as // an item. - convert_variant_ctor(ccx, variant.node.data.id(), ty_variant, ty); + convert_variant_ctor(tcx, variant.node.data.id(), ty_variant, ty); } } -fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_struct_variant<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId, name: ast::Name, discr: ty::VariantDiscr, def: &hir::VariantData) -> ty::VariantDef { let mut seen_fields: FxHashMap = FxHashMap(); - let node_id = ccx.tcx.hir.as_local_node_id(did).unwrap(); + let node_id = tcx.hir.as_local_node_id(did).unwrap(); let fields = def.fields().iter().map(|f| { - let fid = ccx.tcx.hir.local_def_id(f.id); + let fid = tcx.hir.local_def_id(f.id); let dup_span = seen_fields.get(&f.name).cloned(); if let Some(prev_span) = dup_span { - struct_span_err!(ccx.tcx.sess, f.span, E0124, + struct_span_err!(tcx.sess, f.span, E0124, "field `{}` is already declared", f.name) .span_label(f.span, &"field already declared") @@ -940,7 +898,7 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty::FieldDef { did: fid, name: f.name, - vis: ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx) + vis: ty::Visibility::from_hir(&f.vis, node_id, tcx) } }).collect(); ty::VariantDef { @@ -952,56 +910,58 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } -fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_struct_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::Item, def: &hir::VariantData) -> &'tcx ty::AdtDef { - let did = ccx.tcx.hir.local_def_id(it.id); + let did = tcx.hir.local_def_id(it.id); // Use separate constructor id for unit/tuple structs and reuse did for braced structs. - let ctor_id = if !def.is_struct() { Some(ccx.tcx.hir.local_def_id(def.id())) } else { None }; - let variants = vec![convert_struct_variant(ccx, ctor_id.unwrap_or(did), it.name, + let ctor_id = if !def.is_struct() { Some(tcx.hir.local_def_id(def.id())) } else { None }; + let variants = vec![convert_struct_variant(tcx, ctor_id.unwrap_or(did), it.name, ty::VariantDiscr::Relative(0), def)]; - let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Struct, variants, - ReprOptions::new(&ccx.tcx, did)); + let adt = tcx.alloc_adt_def(did, AdtKind::Struct, variants, + ReprOptions::new(tcx, did)); if let Some(ctor_id) = ctor_id { // Make adt definition available through constructor id as well. - ccx.tcx.maps.adt_def.borrow_mut().insert(ctor_id, adt); + tcx.maps.adt_def.borrow_mut().insert(ctor_id, adt); } - ccx.tcx.maps.adt_def.borrow_mut().insert(did, adt); + tcx.maps.adt_def.borrow_mut().insert(did, adt); adt } -fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_union_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::Item, def: &hir::VariantData) -> &'tcx ty::AdtDef { - let did = ccx.tcx.hir.local_def_id(it.id); - let variants = vec![convert_struct_variant(ccx, did, it.name, + let did = tcx.hir.local_def_id(it.id); + let variants = vec![convert_struct_variant(tcx, did, it.name, ty::VariantDiscr::Relative(0), def)]; - let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants, ReprOptions::new(&ccx.tcx, did)); - ccx.tcx.maps.adt_def.borrow_mut().insert(did, adt); + let adt = tcx.alloc_adt_def(did, AdtKind::Union, variants, ReprOptions::new(tcx, did)); + tcx.maps.adt_def.borrow_mut().insert(did, adt); adt } -fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, body: hir::BodyId) +fn evaluate_disr_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + repr_ty: attr::IntType, + body: hir::BodyId) -> Result { - let e = &ccx.tcx.hir.body(body).value; - debug!("disr expr, checking {}", ccx.tcx.hir.node_to_pretty_string(e.id)); + let e = &tcx.hir.body(body).value; + debug!("disr expr, checking {}", tcx.hir.node_to_pretty_string(e.id)); - let ty_hint = repr_ty.to_ty(ccx.tcx); + let ty_hint = repr_ty.to_ty(tcx); let print_err = |cv: ConstVal| { - struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types") + struct_span_err!(tcx.sess, e.span, E0079, "mismatched types") .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description())) .span_label(e.span, &format!("expected '{}' type", ty_hint)) .emit(); }; let hint = UncheckedExprHint(ty_hint); - match ConstContext::new(ccx.tcx, body).eval(e, hint) { + match ConstContext::new(tcx, body).eval(e, hint) { Ok(ConstVal::Integral(i)) => { // FIXME: eval should return an error if the hint does not match the type of the body. // i.e. eventually the match below would not exist. @@ -1032,19 +992,18 @@ fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, body: hir::BodyId // so we need to report the real error Err(err) => { let mut diag = report_const_eval_err( - ccx.tcx, &err, e.span, "enum discriminant"); + tcx, &err, e.span, "enum discriminant"); diag.emit(); Err(()) } } } -fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_enum_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::Item, def: &hir::EnumDef) -> &'tcx ty::AdtDef { - let tcx = ccx.tcx; let mut distance_from_explicit = 0; let variants = def.variants.iter().map(|v| { let did = tcx.hir.local_def_id(v.node.data.id()); @@ -1056,11 +1015,11 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }; distance_from_explicit += 1; - convert_struct_variant(ccx, did, v.node.name, discr, &v.node.data) + convert_struct_variant(tcx, did, v.node.name, discr, &v.node.data) }).collect(); let did = tcx.hir.local_def_id(it.id); - let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants, ReprOptions::new(&ccx.tcx, did)); + let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants, ReprOptions::new(tcx, did)); tcx.maps.adt_def.borrow_mut().insert(did, adt); adt } @@ -1072,12 +1031,10 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, /// above. Returns a list of trait def-ids that must be ensured as /// well to guarantee that the transitive superpredicates are /// converted. -fn ensure_super_predicates_step(ccx: &CrateCtxt, - trait_def_id: DefId) - -> Vec +fn ensure_super_predicates_step<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + trait_def_id: DefId) + -> Vec { - let tcx = ccx.tcx; - debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id); let trait_node_id = if let Some(n) = tcx.hir.as_local_node_id(trait_def_id) { @@ -1093,7 +1050,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, let superpredicates = tcx.maps.super_predicates.borrow().get(&trait_def_id).cloned(); let superpredicates = superpredicates.unwrap_or_else(|| { - let item = match ccx.tcx.hir.get(trait_node_id) { + let item = match tcx.hir.get(trait_node_id) { hir_map::NodeItem(item) => item, _ => bug!("trait_node_id {} is not an item", trait_node_id) }; @@ -1104,7 +1061,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, "ensure_super_predicates_step invoked on non-trait"), }; - let icx = ccx.icx(trait_def_id); + let icx = ItemCtxt::new(tcx, trait_def_id); // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`. let self_param_ty = tcx.mk_self_type(); @@ -1146,8 +1103,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt, def_ids } -fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'tcx ty::TraitDef { - let tcx = ccx.tcx; +fn trait_def_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::Item) -> &'tcx ty::TraitDef { let def_id = tcx.hir.local_def_id(it.id); tcx.maps.trait_def.memoize(def_id, || { @@ -1173,10 +1129,9 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'t }) } -fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn generics_of_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Generics { - let tcx = ccx.tcx; let node_id = if let Some(id) = tcx.hir.as_local_node_id(def_id) { id } else { @@ -1284,7 +1239,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let mut parent_has_self = false; let mut own_start = has_self as u32; let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| { - let generics = generics_of_def_id(ccx, def_id); + let generics = generics_of_def_id(tcx, def_id); assert_eq!(has_self, false); parent_has_self = generics.has_self; own_start = generics.count() as u32; @@ -1294,7 +1249,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); let regions = early_lifetimes.enumerate().map(|(i, l)| { - let issue_32330 = ccx.tcx.named_region_map.issue_32330 + let issue_32330 = tcx.named_region_map.issue_32330 .get(&l.lifetime.id) .cloned(); ty::RegionParameterDef { @@ -1372,24 +1327,24 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }) } -fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn type_of_def_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> { - let node_id = if let Some(id) = ccx.tcx.hir.as_local_node_id(def_id) { + let node_id = if let Some(id) = tcx.hir.as_local_node_id(def_id) { id } else { - return ccx.tcx.item_type(def_id); + return tcx.item_type(def_id); }; - ccx.tcx.maps.ty.memoize(def_id, || { + tcx.maps.ty.memoize(def_id, || { use rustc::hir::map::*; use rustc::hir::*; // Alway bring in generics, as computing the type needs them. - generics_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); - let icx = ccx.icx(def_id); + let icx = ItemCtxt::new(tcx, def_id); - match ccx.tcx.hir.get(node_id) { + match tcx.hir.get(node_id) { NodeItem(item) => { match item.node { ItemStatic(ref t, ..) | ItemConst(ref t, _) | @@ -1398,23 +1353,23 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } ItemFn(ref decl, unsafety, _, abi, _, _) => { let tofd = AstConv::ty_of_fn(&icx, unsafety, abi, &decl); - let substs = mk_item_substs(ccx, def_id); - ccx.tcx.mk_fn_def(def_id, substs, tofd) + let substs = mk_item_substs(tcx, def_id); + tcx.mk_fn_def(def_id, substs, tofd) } ItemEnum(ref ei, _) => { - let def = convert_enum_def(ccx, item, ei); - let substs = mk_item_substs(ccx, def_id); - ccx.tcx.mk_adt(def, substs) + let def = convert_enum_def(tcx, item, ei); + let substs = mk_item_substs(tcx, def_id); + tcx.mk_adt(def, substs) } ItemStruct(ref si, _) => { - let def = convert_struct_def(ccx, item, si); - let substs = mk_item_substs(ccx, def_id); - ccx.tcx.mk_adt(def, substs) + let def = convert_struct_def(tcx, item, si); + let substs = mk_item_substs(tcx, def_id); + tcx.mk_adt(def, substs) } ItemUnion(ref un, _) => { - let def = convert_union_def(ccx, item, un); - let substs = mk_item_substs(ccx, def_id); - ccx.tcx.mk_adt(def, substs) + let def = convert_union_def(tcx, item, un); + let substs = mk_item_substs(tcx, def_id); + tcx.mk_adt(def, substs) } ItemDefaultImpl(..) | ItemTrait(..) | @@ -1430,23 +1385,23 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } NodeForeignItem(foreign_item) => { - let abi = ccx.tcx.hir.get_foreign_abi(node_id); + let abi = tcx.hir.get_foreign_abi(node_id); match foreign_item.node { ForeignItemFn(ref fn_decl, _, _) => { - compute_type_of_foreign_fn_decl(ccx, def_id, fn_decl, abi) + compute_type_of_foreign_fn_decl(tcx, def_id, fn_decl, abi) } ForeignItemStatic(ref t, _) => icx.to_ty(t) } } NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => { - ccx.tcx.mk_closure(def_id, Substs::for_item( - ccx.tcx, def_id, + tcx.mk_closure(def_id, Substs::for_item( + tcx, def_id, |def, _| { let region = def.to_early_bound_region_data(); - ccx.tcx.mk_region(ty::ReEarlyBound(region)) + tcx.mk_region(ty::ReEarlyBound(region)) }, - |def, _| ccx.tcx.mk_param_from_def(def) + |def, _| tcx.mk_param_from_def(def) )) } NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => { @@ -1459,8 +1414,8 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }) } -fn predicates_of_item(ccx: &CrateCtxt, it: &hir::Item) { - let def_id = ccx.tcx.hir.local_def_id(it.id); +fn predicates_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::Item) { + let def_id = tcx.hir.local_def_id(it.id); let no_generics = hir::Generics::empty(); let generics = match it.node { @@ -1474,19 +1429,19 @@ fn predicates_of_item(ccx: &CrateCtxt, it: &hir::Item) { _ => &no_generics }; - ty_generic_predicates(ccx, def_id, generics); + ty_generic_predicates(tcx, def_id, generics); } -fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn convert_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { // For reasons I cannot fully articulate, I do so hate the AST // map, and I regard each time that I use it as a personal and // moral failing, but at the moment it seems like the only // convenient way to extract the ABI. - ndm - let def_id = ccx.tcx.hir.local_def_id(it.id); - generics_of_def_id(ccx, def_id); - type_of_def_id(ccx, def_id); + let def_id = tcx.hir.local_def_id(it.id); + generics_of_def_id(tcx, def_id); + type_of_def_id(tcx, def_id); let no_generics = hir::Generics::empty(); let generics = match it.node { @@ -1494,7 +1449,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, hir::ForeignItemStatic(..) => &no_generics }; - ty_generic_predicates(ccx, def_id, generics); + ty_generic_predicates(tcx, def_id, generics); } // Is it marked with ?Sized @@ -1557,10 +1512,11 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>( .filter(move |l| !tcx.named_region_map.late_bound.contains(&l.lifetime.id)) } -fn ty_generic_predicates(ccx: &CrateCtxt, def_id: DefId, ast_generics: &hir::Generics) { - let tcx = ccx.tcx; - let icx = ccx.icx(def_id); - let generics = generics_of_def_id(ccx, def_id); +fn ty_generic_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + ast_generics: &hir::Generics) { + let icx = ItemCtxt::new(tcx, def_id); + let generics = generics_of_def_id(tcx, def_id); let parent_count = generics.parent_count() as u32; let has_own_self = generics.has_self && parent_count == 0; @@ -1573,11 +1529,11 @@ fn ty_generic_predicates(ccx: &CrateCtxt, def_id: DefId, ast_generics: &hir::Gen hir::ItemTrait(.., ref items) => { (Some((ty::TraitRef { def_id: def_id, - substs: mk_item_substs(ccx, def_id) + substs: mk_item_substs(tcx, def_id) }, items)), None) } hir::ItemImpl(..) => { - let self_ty = type_of_def_id(ccx, def_id); + let self_ty = type_of_def_id(tcx, def_id); let trait_ref = tcx.impl_trait_ref(def_id); (None, Some((self_ty, trait_ref))) } @@ -1695,7 +1651,7 @@ fn ty_generic_predicates(ccx: &CrateCtxt, def_id: DefId, ast_generics: &hir::Gen let assoc_ty = tcx.mk_projection(self_trait_ref, trait_item.name); - let bounds = compute_bounds(&ccx.icx(def_id), + let bounds = compute_bounds(&ItemCtxt::new(tcx, def_id), assoc_ty, bounds, SizedByDefault::Yes, @@ -1809,24 +1765,24 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>, } fn compute_type_of_foreign_fn_decl<'a, 'tcx>( - ccx: &CrateCtxt<'a, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, decl: &hir::FnDecl, abi: abi::Abi) -> Ty<'tcx> { - let fty = AstConv::ty_of_fn(&ccx.icx(def_id), hir::Unsafety::Unsafe, abi, decl); + let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), hir::Unsafety::Unsafe, abi, decl); // feature gate SIMD types in FFI, since I (huonw) am not sure the // ABIs are handled at all correctly. if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic - && !ccx.tcx.sess.features.borrow().simd_ffi { + && !tcx.sess.features.borrow().simd_ffi { let check = |ast_ty: &hir::Ty, ty: ty::Ty| { if ty.is_simd() { - ccx.tcx.sess.struct_span_err(ast_ty.span, + tcx.sess.struct_span_err(ast_ty.span, &format!("use of SIMD type `{}` in FFI is highly experimental and \ may result in invalid code", - ccx.tcx.hir.node_to_pretty_string(ast_ty.id))) + tcx.hir.node_to_pretty_string(ast_ty.id))) .help("add #![feature(simd_ffi)] to the crate attributes to enable") .emit(); } @@ -1839,15 +1795,15 @@ fn compute_type_of_foreign_fn_decl<'a, 'tcx>( } } - let substs = mk_item_substs(ccx, def_id); - ccx.tcx.mk_fn_def(def_id, substs, fty) + let substs = mk_item_substs(tcx, def_id); + tcx.mk_fn_def(def_id, substs, fty) } -fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn mk_item_substs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Substs<'tcx> { // FIXME(eddyb) Do this request from Substs::for_item in librustc. - generics_of_def_id(ccx, def_id); + generics_of_def_id(tcx, def_id); - Substs::identity_for_item(ccx.tcx, def_id) + Substs::identity_for_item(tcx, def_id) } diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 3a19b3579d559..3df25825a71f6 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -23,14 +23,12 @@ use rustc::dep_graph::DepNode; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::def_id::DefId; -use rustc::ty; +use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use syntax_pos::Span; -use CrateCtxt; - /// Checks that all the type/lifetime parameters on an impl also /// appear in the trait ref or self-type (or are constrained by a /// where-clause). These rules are needed to ensure that, given a @@ -61,27 +59,27 @@ use CrateCtxt; /// impl<'a> Trait for Bar { type X = &'a i32; } /// ^ 'a is unused and appears in assoc type, error /// ``` -pub fn impl_wf_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>) { +pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. - ccx.tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut ImplWfCheck { ccx: ccx }); + tcx.visit_all_item_likes_in_krate(DepNode::WfCheck, &mut ImplWfCheck { tcx: tcx }); } struct ImplWfCheck<'a, 'tcx: 'a> { - ccx: &'a CrateCtxt<'a, 'tcx>, + tcx: TyCtxt<'a, 'tcx, 'tcx>, } impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { hir::ItemImpl(.., ref generics, _, _, ref impl_item_refs) => { - let impl_def_id = self.ccx.tcx.hir.local_def_id(item.id); - enforce_impl_params_are_constrained(self.ccx, + let impl_def_id = self.tcx.hir.local_def_id(item.id); + enforce_impl_params_are_constrained(self.tcx, generics, impl_def_id, impl_item_refs); - enforce_impl_items_are_distinct(self.ccx, impl_item_refs); + enforce_impl_items_are_distinct(self.tcx, impl_item_refs); } _ => { } } @@ -92,16 +90,16 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem) { } } -fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_hir_generics: &hir::Generics, impl_def_id: DefId, impl_item_refs: &[hir::ImplItemRef]) { // Every lifetime used in an associated type must be constrained. - let impl_self_ty = ccx.tcx.item_type(impl_def_id); - let impl_generics = ccx.tcx.item_generics(impl_def_id); - let impl_predicates = ccx.tcx.item_predicates(impl_def_id); - let impl_trait_ref = ccx.tcx.impl_trait_ref(impl_def_id); + let impl_self_ty = tcx.item_type(impl_def_id); + let impl_generics = tcx.item_generics(impl_def_id); + let impl_predicates = tcx.item_predicates(impl_def_id); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); let mut input_parameters = ctp::parameters_for_impl(impl_self_ty, impl_trait_ref); ctp::identify_constrained_type_params( @@ -111,19 +109,19 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, for (ty_param, param) in impl_generics.types.iter().zip(&impl_hir_generics.ty_params) { let param_ty = ty::ParamTy::for_def(ty_param); if !input_parameters.contains(&ctp::Parameter::from(param_ty)) { - report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string()); + report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string()); } } // Disallow unconstrained lifetimes, but only if they appear in assoc types. let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter() - .map(|item_ref| ccx.tcx.hir.local_def_id(item_ref.id.node_id)) + .map(|item_ref| tcx.hir.local_def_id(item_ref.id.node_id)) .filter(|&def_id| { - let item = ccx.tcx.associated_item(def_id); + let item = tcx.associated_item(def_id); item.kind == ty::AssociatedKind::Type && item.defaultness.has_value() }) .flat_map(|def_id| { - ctp::parameters_for(&ccx.tcx.item_type(def_id), true) + ctp::parameters_for(&tcx.item_type(def_id), true) }).collect(); for (ty_lifetime, lifetime) in impl_generics.regions.iter() .zip(&impl_hir_generics.lifetimes) @@ -134,7 +132,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, lifetimes_in_associated_types.contains(¶m) && // (*) !input_parameters.contains(¶m) { - report_unused_parameter(ccx, lifetime.lifetime.span, + report_unused_parameter(tcx, lifetime.lifetime.span, "lifetime", &lifetime.lifetime.name.to_string()); } } @@ -159,13 +157,13 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // used elsewhere are not projected back out. } -fn report_unused_parameter(ccx: &CrateCtxt, +fn report_unused_parameter(tcx: TyCtxt, span: Span, kind: &str, name: &str) { struct_span_err!( - ccx.tcx.sess, span, E0207, + tcx.sess, span, E0207, "the {} parameter `{}` is not constrained by the \ impl trait, self type, or predicates", kind, name) @@ -174,10 +172,9 @@ fn report_unused_parameter(ccx: &CrateCtxt, } /// Enforce that we do not have two items in an impl with the same name. -fn enforce_impl_items_are_distinct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn enforce_impl_items_are_distinct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_item_refs: &[hir::ImplItemRef]) { - let tcx = ccx.tcx; let mut seen_type_items = FxHashMap(); let mut seen_value_items = FxHashMap(); for impl_item_ref in impl_item_refs { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 03175782c38fd..ddd8d9259cc99 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -110,7 +110,7 @@ use hir::map as hir_map; use rustc::infer::InferOk; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; +use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal}; use session::config; use util::common::time; @@ -120,9 +120,6 @@ use syntax::symbol::keywords; use syntax_pos::Span; use std::iter; -use std::cell::RefCell; -use util::nodemap::NodeMap; - // NB: This module needs to be declared first so diagnostics are // registered before they are used. pub mod diagnostics; @@ -141,27 +138,6 @@ pub struct TypeAndSubsts<'tcx> { pub ty: Ty<'tcx>, } -pub struct CrateCtxt<'a, 'tcx: 'a> { - ast_ty_to_ty_cache: RefCell>>, - - /// A vector of every trait accessible in the whole crate - /// (i.e. including those from subcrates). This is used only for - /// error reporting, and so is lazily initialised and generally - /// shouldn't taint the common path (hence the RefCell). - pub all_traits: RefCell>, - - /// This stack is used to identify cycles in the user's source. - /// Note that these cycles can cross multiple items. - pub stack: RefCell>, - - pub tcx: TyCtxt<'a, 'tcx, 'tcx>, - - /// Obligations which will have to be checked at the end of - /// type-checking, after all functions have been inferred. - /// The key is the NodeId of the item the obligations were from. - pub deferred_obligations: RefCell>>>, -} - fn require_c_abi_if_variadic(tcx: TyCtxt, decl: &hir::FnDecl, abi: Abi, @@ -174,12 +150,12 @@ fn require_c_abi_if_variadic(tcx: TyCtxt, } } -fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, +fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>) -> bool { - ccx.tcx.infer_ctxt((), Reveal::NotSpecializable).enter(|infcx| { + tcx.infer_ctxt((), Reveal::NotSpecializable).enter(|infcx| { match infcx.eq_types(false, &cause, expected, actual) { Ok(InferOk { obligations, .. }) => { // FIXME(#32730) propagate obligations @@ -218,10 +194,9 @@ fn ty_param_name(tcx: TyCtxt, id: ast::NodeId) -> ast::Name { } } -fn check_main_fn_ty(ccx: &CrateCtxt, - main_id: ast::NodeId, - main_span: Span) { - let tcx = ccx.tcx; +fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + main_id: ast::NodeId, + main_span: Span) { let main_def_id = tcx.hir.local_def_id(main_id); let main_t = tcx.item_type(main_def_id); match main_t.sty { @@ -231,7 +206,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, match it.node { hir::ItemFn(.., ref generics, _) => { if generics.is_parameterized() { - struct_span_err!(ccx.tcx.sess, generics.span, E0131, + struct_span_err!(tcx.sess, generics.span, E0131, "main function is not allowed to have type parameters") .span_label(generics.span, &format!("main cannot have type parameters")) @@ -253,7 +228,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt, })); require_same_types( - ccx, + tcx, &ObligationCause::new(main_span, main_id, ObligationCauseCode::MainFunctionType), se_ty, main_t); @@ -266,11 +241,10 @@ fn check_main_fn_ty(ccx: &CrateCtxt, } } -fn check_start_fn_ty(ccx: &CrateCtxt, - start_id: ast::NodeId, - start_span: Span) { - let tcx = ccx.tcx; - let start_def_id = ccx.tcx.hir.local_def_id(start_id); +fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + start_id: ast::NodeId, + start_span: Span) { + let start_def_id = tcx.hir.local_def_id(start_id); let start_t = tcx.item_type(start_def_id); match start_t.sty { ty::TyFnDef(..) => { @@ -308,7 +282,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt, })); require_same_types( - ccx, + tcx, &ObligationCause::new(start_span, start_id, ObligationCauseCode::StartFunctionType), se_ty, start_t); @@ -321,13 +295,12 @@ fn check_start_fn_ty(ccx: &CrateCtxt, } } -fn check_for_entry_fn(ccx: &CrateCtxt) { - let tcx = ccx.tcx; +fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let _task = tcx.dep_graph.in_task(DepNode::CheckEntryFn); if let Some((id, sp)) = *tcx.sess.entry_fn.borrow() { match tcx.sess.entry_type.get() { - Some(config::EntryMain) => check_main_fn_ty(ccx, id, sp), - Some(config::EntryStart) => check_start_fn_ty(ccx, id, sp), + Some(config::EntryMain) => check_main_fn_ty(tcx, id, sp), + Some(config::EntryStart) => check_start_fn_ty(tcx, id, sp), Some(config::EntryNone) => {} None => bug!("entry function without a type") } @@ -335,21 +308,14 @@ fn check_for_entry_fn(ccx: &CrateCtxt) { } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> Result>, usize> { + -> Result<(), usize> { let time_passes = tcx.sess.time_passes(); - let ccx = CrateCtxt { - ast_ty_to_ty_cache: RefCell::new(NodeMap()), - all_traits: RefCell::new(None), - stack: RefCell::new(Vec::new()), - tcx: tcx, - deferred_obligations: RefCell::new(NodeMap()), - }; // this ensures that later parts of type checking can assume that items // have valid types and not error tcx.sess.track_errors(|| { time(time_passes, "type collecting", || - collect::collect_item_types(&ccx)); + collect::collect_item_types(tcx)); })?; @@ -358,28 +324,28 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) tcx.sess.track_errors(|| { time(time_passes, "impl wf inference", || - impl_wf_check::impl_wf_check(&ccx)); + impl_wf_check::impl_wf_check(tcx)); })?; tcx.sess.track_errors(|| { time(time_passes, "coherence checking", || - coherence::check_coherence(&ccx)); + coherence::check_coherence(tcx)); })?; - time(time_passes, "wf checking", || check::check_wf_new(&ccx))?; + time(time_passes, "wf checking", || check::check_wf_new(tcx))?; - time(time_passes, "item-types checking", || check::check_item_types(&ccx))?; + time(time_passes, "item-types checking", || check::check_item_types(tcx))?; - time(time_passes, "item-bodies checking", || check::check_item_bodies(&ccx))?; + time(time_passes, "item-bodies checking", || check::check_item_bodies(tcx))?; - time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx))?; + time(time_passes, "drop-impl checking", || check::check_drop_impls(tcx))?; check_unused::check_crate(tcx); - check_for_entry_fn(&ccx); + check_for_entry_fn(tcx); let err_count = tcx.sess.err_count(); if err_count == 0 { - Ok(ccx.ast_ty_to_ty_cache.into_inner()) + Ok(()) } else { Err(err_count) } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dc09fc2b8d3cc..cd94e3fd14a50 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1772,7 +1772,7 @@ impl Clean for hir::Ty { } TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => { let mut def = Def::Err; - if let Some(ty) = cx.hir_ty_to_ty.get(&self.id) { + if let Some(ty) = cx.tcx.ast_ty_to_ty_cache.borrow().get(&self.id) { if let ty::TyProjection(proj) = ty.sty { def = Def::Trait(proj.trait_ref.def_id); } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5393e395bbe43..0a9db2c26464c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -15,10 +15,10 @@ use rustc::session::{self, config}; use rustc::hir::def_id::DefId; use rustc::hir::def::{Def, ExportMap}; use rustc::middle::privacy::AccessLevels; -use rustc::ty::{self, TyCtxt, GlobalArenas, Ty}; +use rustc::ty::{self, TyCtxt, GlobalArenas}; use rustc::hir::map as hir_map; use rustc::lint; -use rustc::util::nodemap::{FxHashMap, NodeMap}; +use rustc::util::nodemap::FxHashMap; use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; @@ -65,9 +65,6 @@ pub struct DocContext<'a, 'tcx: 'a> { /// Table node id of lifetime parameter definition -> substituted lifetime pub lt_substs: RefCell>, pub export_map: ExportMap, - - /// Table from HIR Ty nodes to their resolved Ty. - pub hir_ty_to_ty: NodeMap>, } impl<'a, 'tcx> DocContext<'a, 'tcx> { @@ -183,7 +180,7 @@ pub fn run_core(search_paths: SearchPaths, sess.fatal("Compilation failed, aborting rustdoc"); } - let ty::CrateAnalysis { access_levels, export_map, hir_ty_to_ty, .. } = analysis; + let ty::CrateAnalysis { access_levels, export_map, .. } = analysis; // Convert from a NodeId set to a DefId set since we don't always have easy access // to the map from defid -> nodeid @@ -202,7 +199,6 @@ pub fn run_core(search_paths: SearchPaths, ty_substs: Default::default(), lt_substs: Default::default(), export_map: export_map, - hir_ty_to_ty: hir_ty_to_ty, }; debug!("crate: {:?}", tcx.hir.krate());