rustc_typeck: lift CrateCtxt to TyCtxt.

This commit is contained in:
Eduard Burtescu 2016-10-04 02:19:40 +03:00 committed by Eduard-Mihai Burtescu
parent 374ea14412
commit 4649f7387e
24 changed files with 653 additions and 759 deletions

View file

@ -525,6 +525,20 @@ pub struct GlobalCtxt<'tcx> {
stability_interner: RefCell<FxHashSet<&'tcx attr::Stability>>,
layout_interner: RefCell<FxHashSet<&'tcx Layout>>,
/// 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<Option<Vec<DefId>>>,
/// 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<NodeMap<Vec<traits::DeferredObligation<'tcx>>>>,
/// HIR Ty -> Ty lowering cache.
pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
}
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)
}
}

View file

@ -37,6 +37,7 @@ macro_rules! define_maps {
pub $name:ident: $node:ident($K:ty) -> $V:ty),*) => {
pub struct Maps<$tcx> {
providers: IndexVec<CrateNum, Providers<$tcx>>,
pub query_stack: RefCell<Vec<Query>>,
$($(#[$attr])* pub $name: RefCell<DepTrackingMap<queries::$name<$tcx>>>),*
}
@ -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>,

View file

@ -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<hir::GlobMap>,
pub hir_ty_to_ty: NodeMap<Ty<'tcx>>,
}
#[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<VariantDef>,

View file

@ -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<TyCtxt<'a, 'tcx, 'tcx>>,
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<PathBuf>,
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<F>(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<F>(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<R, usize>
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",

View file

@ -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,

View file

@ -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) {

View file

@ -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)
};

View file

@ -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();
}

View file

@ -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<Span>)
-> 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<Span>)
-> 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();

View file

@ -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<T>; impl<T:Clone> Drop for S<T> { ... }`).
///
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);

View file

@ -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<Ty<'tcx>>,
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)
}
}

View file

@ -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(..) => {}
}

View file

@ -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)?;
}

View file

@ -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<TraitInfo>;
pub type AllTraitsVec = Vec<DefId>;
#[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<DefId>,
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)
})
}
}

View file

@ -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<NodeMap<Ty<'tcx>>>,
fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
@ -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<F, R>(&'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<ConstInt> = 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"))

View file

@ -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);

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}

File diff suppressed because it is too large Load diff

View file

@ -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<Foo> 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", &param_ty.to_string());
report_unused_parameter(tcx, param.span, "type", &param_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(&param) && // (*)
!input_parameters.contains(&param)
{
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 {

View file

@ -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<NodeMap<Ty<'tcx>>>,
/// 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<Option<check::method::AllTraitsVec>>,
/// This stack is used to identify cycles in the user's source.
/// Note that these cycles can cross multiple items.
pub stack: RefCell<Vec<collect::AstConvRequest>>,
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<NodeMap<Vec<traits::DeferredObligation<'tcx>>>>,
}
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<NodeMap<Ty<'tcx>>, 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)
}

View file

@ -1772,7 +1772,7 @@ impl Clean<Type> 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);
}

View file

@ -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<FxHashMap<ast::NodeId, clean::Lifetime>>,
pub export_map: ExportMap,
/// Table from HIR Ty nodes to their resolved Ty.
pub hir_ty_to_ty: NodeMap<Ty<'tcx>>,
}
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());