rustc_typeck: lift CrateCtxt to TyCtxt.
This commit is contained in:
parent
374ea14412
commit
4649f7387e
24 changed files with 653 additions and 759 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(..) => {}
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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", ¶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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue