typeck: Avoid passing &TyCtxt around where possible.
This commit is contained in:
parent
e387e6c7c8
commit
ef2f5f6d8e
16 changed files with 288 additions and 359 deletions
|
|
@ -33,7 +33,7 @@ use hir;
|
|||
|
||||
pub trait IntTypeExt {
|
||||
fn to_ty<'tcx>(&self, tcx: &TyCtxt<'tcx>) -> Ty<'tcx>;
|
||||
fn disr_incr(&self, val: Disr) -> Option<Disr>;
|
||||
fn disr_incr(&self, tcx: &TyCtxt, val: Option<Disr>) -> Option<Disr>;
|
||||
fn assert_ty_matches(&self, val: Disr);
|
||||
fn initial_discriminant(&self, tcx: &TyCtxt) -> Disr;
|
||||
}
|
||||
|
|
@ -93,9 +93,13 @@ impl IntTypeExt for attr::IntType {
|
|||
}
|
||||
}
|
||||
|
||||
fn disr_incr(&self, val: Disr) -> Option<Disr> {
|
||||
self.assert_ty_matches(val);
|
||||
(val + ConstInt::Infer(1)).ok()
|
||||
fn disr_incr(&self, tcx: &TyCtxt, val: Option<Disr>) -> Option<Disr> {
|
||||
if let Some(val) = val {
|
||||
self.assert_ty_matches(val);
|
||||
(val + ConstInt::Infer(1)).ok()
|
||||
} else {
|
||||
Some(self.initial_discriminant(tcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ pub fn ast_path_substs_for_ty<'tcx>(
|
|||
}
|
||||
};
|
||||
|
||||
prohibit_projections(this.tcx(), &assoc_bindings);
|
||||
assoc_bindings.first().map(|b| prohibit_projection(this.tcx(), b.span));
|
||||
|
||||
create_substs_for_ast_path(this,
|
||||
span,
|
||||
|
|
@ -580,10 +580,11 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
|
|||
/// Returns the appropriate lifetime to use for any output lifetimes
|
||||
/// (if one exists) and a vector of the (pattern, number of lifetimes)
|
||||
/// corresponding to each input type/pattern.
|
||||
fn find_implied_output_region<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
fn find_implied_output_region<'tcx>(this: &AstConv<'tcx>,
|
||||
input_tys: &[Ty<'tcx>],
|
||||
input_pats: Vec<String>) -> ElidedLifetime
|
||||
{
|
||||
let tcx = this.tcx();
|
||||
let mut lifetimes_for_params = Vec::new();
|
||||
let mut possible_implied_output_region = None;
|
||||
|
||||
|
|
@ -655,7 +656,7 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>,
|
|||
.collect::<Vec<Ty<'tcx>>>();
|
||||
|
||||
let input_params = vec![String::new(); inputs.len()];
|
||||
let implied_output_region = find_implied_output_region(this.tcx(), &inputs, input_params);
|
||||
let implied_output_region = find_implied_output_region(this, &inputs, input_params);
|
||||
|
||||
let input_ty = this.tcx().mk_tup(inputs);
|
||||
|
||||
|
|
@ -824,7 +825,7 @@ fn ast_path_to_mono_trait_ref<'a,'tcx>(this: &AstConv<'tcx>,
|
|||
trait_def_id,
|
||||
self_ty,
|
||||
trait_segment);
|
||||
prohibit_projections(this.tcx(), &assoc_bindings);
|
||||
assoc_bindings.first().map(|b| prohibit_projection(this.tcx(), b.span));
|
||||
ty::TraitRef::new(trait_def_id, substs)
|
||||
}
|
||||
|
||||
|
|
@ -960,7 +961,7 @@ fn ast_type_binding_to_poly_projection_predicate<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let candidate = one_bound_for_assoc_type(tcx,
|
||||
let candidate = one_bound_for_assoc_type(this,
|
||||
candidates,
|
||||
&trait_ref.to_string(),
|
||||
&binding.item_name.as_str(),
|
||||
|
|
@ -1219,7 +1220,7 @@ fn find_bound_for_assoc_item<'tcx>(this: &AstConv<'tcx>,
|
|||
.filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
|
||||
.collect();
|
||||
|
||||
one_bound_for_assoc_type(tcx,
|
||||
one_bound_for_assoc_type(this,
|
||||
suitable_bounds,
|
||||
&ty_param_name.as_str(),
|
||||
&assoc_name.as_str(),
|
||||
|
|
@ -1229,7 +1230,7 @@ fn find_bound_for_assoc_item<'tcx>(this: &AstConv<'tcx>,
|
|||
|
||||
// Checks that bounds contains exactly one element and reports appropriate
|
||||
// errors otherwise.
|
||||
fn one_bound_for_assoc_type<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
fn one_bound_for_assoc_type<'tcx>(this: &AstConv<'tcx>,
|
||||
bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
||||
ty_param_name: &str,
|
||||
assoc_name: &str,
|
||||
|
|
@ -1237,7 +1238,7 @@ fn one_bound_for_assoc_type<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
|
||||
{
|
||||
if bounds.is_empty() {
|
||||
span_err!(tcx.sess, span, E0220,
|
||||
span_err!(this.tcx().sess, span, E0220,
|
||||
"associated type `{}` not found for `{}`",
|
||||
assoc_name,
|
||||
ty_param_name);
|
||||
|
|
@ -1245,7 +1246,7 @@ fn one_bound_for_assoc_type<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
}
|
||||
|
||||
if bounds.len() > 1 {
|
||||
let mut err = struct_span_err!(tcx.sess, span, E0221,
|
||||
let mut err = struct_span_err!(this.tcx().sess, span, E0221,
|
||||
"ambiguous associated type `{}` in bounds of `{}`",
|
||||
assoc_name,
|
||||
ty_param_name);
|
||||
|
|
@ -1305,7 +1306,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
|
|||
assoc_name))
|
||||
.collect();
|
||||
|
||||
match one_bound_for_assoc_type(tcx,
|
||||
match one_bound_for_assoc_type(this,
|
||||
candidates,
|
||||
"Self",
|
||||
&assoc_name.as_str(),
|
||||
|
|
@ -1814,7 +1815,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
|
|||
// have that lifetime.
|
||||
let implied_output_region = match explicit_self_category {
|
||||
Some(ty::ExplicitSelfCategory::ByReference(region, _)) => Ok(region),
|
||||
_ => find_implied_output_region(this.tcx(), &arg_tys, arg_pats)
|
||||
_ => find_implied_output_region(this, &arg_tys, arg_pats)
|
||||
};
|
||||
|
||||
let output_ty = match decl.output {
|
||||
|
|
@ -2208,14 +2209,6 @@ pub fn partition_bounds<'a>(tcx: &TyCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
fn prohibit_projections<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
bindings: &[ConvertedBinding<'tcx>])
|
||||
{
|
||||
for binding in bindings.iter().take(1) {
|
||||
prohibit_projection(tcx, binding.span);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_type_argument_count(tcx: &TyCtxt, span: Span, supplied: usize,
|
||||
required: usize, accepted: usize) {
|
||||
if supplied < required {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
|
|||
|
||||
// Check that the types of the end-points can be unified.
|
||||
let types_unify = require_same_types(
|
||||
tcx, Some(fcx.infcx()), false, pat.span, rhs_ty, lhs_ty,
|
||||
fcx.ccx, Some(fcx.infcx()), pat.span, rhs_ty, lhs_ty,
|
||||
"mismatched types in range",
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
|||
// In that case, we check each argument against "error" in order to
|
||||
// set up all the node type bindings.
|
||||
error_fn_sig = ty::Binder(ty::FnSig {
|
||||
inputs: err_args(fcx.tcx(), arg_exprs.len()),
|
||||
inputs: err_args(fcx, arg_exprs.len()),
|
||||
output: ty::FnConverging(fcx.tcx().types.err),
|
||||
variadic: false
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,13 +10,14 @@
|
|||
|
||||
use middle::free_region::FreeRegionMap;
|
||||
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::ty;
|
||||
use rustc::traits::{self, ProjectionMode};
|
||||
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
use CrateCtxt;
|
||||
use super::assoc;
|
||||
|
||||
/// Checks that a method from an impl conforms to the signature of
|
||||
|
|
@ -30,18 +31,19 @@ use super::assoc;
|
|||
/// - trait_m: the method in the trait
|
||||
/// - impl_trait_ref: the TraitRef corresponding to the trait implementation
|
||||
|
||||
pub fn compare_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
impl_m: &ty::Method<'tcx>,
|
||||
impl_m_span: Span,
|
||||
impl_m_body_id: ast::NodeId,
|
||||
trait_m: &ty::Method<'tcx>,
|
||||
impl_trait_ref: &ty::TraitRef<'tcx>) {
|
||||
pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_m: &ty::Method<'tcx>,
|
||||
impl_m_span: Span,
|
||||
impl_m_body_id: ast::NodeId,
|
||||
trait_m: &ty::Method<'tcx>,
|
||||
impl_trait_ref: &ty::TraitRef<'tcx>) {
|
||||
debug!("compare_impl_method(impl_trait_ref={:?})",
|
||||
impl_trait_ref);
|
||||
|
||||
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
|
||||
impl_trait_ref);
|
||||
|
||||
let tcx = ccx.tcx;
|
||||
let mut infcx = InferCtxt::new(tcx, &tcx.tables, None, ProjectionMode::AnyFinal);
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
|
||||
|
|
@ -186,7 +188,7 @@ pub fn compare_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
|
||||
// Check region bounds. FIXME(@jroesch) refactor this away when removing
|
||||
// ParamBounds.
|
||||
if !check_region_bounds_on_impl_method(tcx,
|
||||
if !check_region_bounds_on_impl_method(ccx,
|
||||
impl_m_span,
|
||||
impl_m,
|
||||
&trait_m.generics,
|
||||
|
|
@ -364,14 +366,14 @@ pub fn compare_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
|
||||
infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
|
||||
|
||||
fn check_region_bounds_on_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
impl_m: &ty::Method<'tcx>,
|
||||
trait_generics: &ty::Generics<'tcx>,
|
||||
impl_generics: &ty::Generics<'tcx>,
|
||||
trait_to_skol_substs: &Substs<'tcx>,
|
||||
impl_to_skol_substs: &Substs<'tcx>)
|
||||
-> bool
|
||||
fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
impl_m: &ty::Method<'tcx>,
|
||||
trait_generics: &ty::Generics<'tcx>,
|
||||
impl_generics: &ty::Generics<'tcx>,
|
||||
trait_to_skol_substs: &Substs<'tcx>,
|
||||
impl_to_skol_substs: &Substs<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
|
||||
let trait_params = trait_generics.regions.get_slice(subst::FnSpace);
|
||||
|
|
@ -397,7 +399,7 @@ pub fn compare_impl_method<'tcx>(tcx: &TyCtxt<'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() {
|
||||
span_err!(tcx.sess, span, E0195,
|
||||
span_err!(ccx.tcx.sess, span, E0195,
|
||||
"lifetime parameters or bounds on method `{}` do \
|
||||
not match the trait declaration",
|
||||
impl_m.name);
|
||||
|
|
@ -408,14 +410,15 @@ pub fn compare_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn compare_const_impl<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
impl_c: &ty::AssociatedConst<'tcx>,
|
||||
impl_c_span: Span,
|
||||
trait_c: &ty::AssociatedConst<'tcx>,
|
||||
impl_trait_ref: &ty::TraitRef<'tcx>) {
|
||||
pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_c: &ty::AssociatedConst<'tcx>,
|
||||
impl_c_span: Span,
|
||||
trait_c: &ty::AssociatedConst<'tcx>,
|
||||
impl_trait_ref: &ty::TraitRef<'tcx>) {
|
||||
debug!("compare_const_impl(impl_trait_ref={:?})",
|
||||
impl_trait_ref);
|
||||
|
||||
let tcx = ccx.tcx;
|
||||
let infcx = InferCtxt::new(tcx, &tcx.tables, None, ProjectionMode::AnyFinal);
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use CrateCtxt;
|
||||
use check::regionck::{self, Rcx};
|
||||
|
||||
use hir::def_id::DefId;
|
||||
|
|
@ -15,7 +16,7 @@ use middle::free_region::FreeRegionMap;
|
|||
use rustc::infer::{self, InferCtxt};
|
||||
use middle::region;
|
||||
use rustc::ty::subst::{self, Subst};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::traits::{self, ProjectionMode};
|
||||
use util::nodemap::FnvHashSet;
|
||||
|
||||
|
|
@ -39,20 +40,20 @@ use syntax::codemap::{self, 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(tcx: &TyCtxt, drop_impl_did: DefId) -> Result<(), ()> {
|
||||
pub fn check_drop_impl(ccx: &CrateCtxt, drop_impl_did: DefId) -> Result<(), ()> {
|
||||
let ty::TypeScheme { generics: ref dtor_generics,
|
||||
ty: dtor_self_type } = tcx.lookup_item_type(drop_impl_did);
|
||||
let dtor_predicates = tcx.lookup_predicates(drop_impl_did);
|
||||
ty: dtor_self_type } = ccx.tcx.lookup_item_type(drop_impl_did);
|
||||
let dtor_predicates = ccx.tcx.lookup_predicates(drop_impl_did);
|
||||
match dtor_self_type.sty {
|
||||
ty::TyEnum(adt_def, self_to_impl_substs) |
|
||||
ty::TyStruct(adt_def, self_to_impl_substs) => {
|
||||
ensure_drop_params_and_item_params_correspond(tcx,
|
||||
ensure_drop_params_and_item_params_correspond(ccx,
|
||||
drop_impl_did,
|
||||
dtor_generics,
|
||||
&dtor_self_type,
|
||||
adt_def.did)?;
|
||||
|
||||
ensure_drop_predicates_are_implied_by_item_defn(tcx,
|
||||
ensure_drop_predicates_are_implied_by_item_defn(ccx,
|
||||
drop_impl_did,
|
||||
&dtor_predicates,
|
||||
adt_def.did,
|
||||
|
|
@ -61,7 +62,7 @@ pub fn check_drop_impl(tcx: &TyCtxt, drop_impl_did: DefId) -> Result<(), ()> {
|
|||
_ => {
|
||||
// Destructors only work on nominal types. This was
|
||||
// already checked by coherence, so we can panic here.
|
||||
let span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
|
||||
let span = ccx.tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
|
||||
span_bug!(span,
|
||||
"should have been rejected by coherence check: {}",
|
||||
dtor_self_type);
|
||||
|
|
@ -69,13 +70,14 @@ pub fn check_drop_impl(tcx: &TyCtxt, drop_impl_did: DefId) -> Result<(), ()> {
|
|||
}
|
||||
}
|
||||
|
||||
fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
||||
ccx: &CrateCtxt<'a, 'tcx>,
|
||||
drop_impl_did: DefId,
|
||||
drop_impl_generics: &ty::Generics<'tcx>,
|
||||
drop_impl_ty: &ty::Ty<'tcx>,
|
||||
self_type_did: DefId) -> Result<(), ()>
|
||||
{
|
||||
let tcx = ccx.tcx;
|
||||
let drop_impl_node_id = tcx.map.as_local_node_id(drop_impl_did).unwrap();
|
||||
let self_type_node_id = tcx.map.as_local_node_id(self_type_did).unwrap();
|
||||
|
||||
|
|
@ -124,8 +126,8 @@ fn ensure_drop_params_and_item_params_correspond<'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<'tcx>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
|
||||
ccx: &CrateCtxt<'a, 'tcx>,
|
||||
drop_impl_did: DefId,
|
||||
dtor_predicates: &ty::GenericPredicates<'tcx>,
|
||||
self_type_did: DefId,
|
||||
|
|
@ -166,6 +168,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'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.map.as_local_node_id(self_type_did).unwrap();
|
||||
|
||||
let drop_impl_span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
|
||||
|
|
@ -407,7 +411,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
|
|||
// unbounded type parameter `T`, we must resume the recursive
|
||||
// analysis on `T` (since it would be ignored by
|
||||
// type_must_outlive).
|
||||
if has_dtor_of_interest(tcx, ty) {
|
||||
if has_dtor_of_interest(cx, ty) {
|
||||
debug!("iterate_over_potentially_unsafe_regions_in_type \
|
||||
{}ty: {} - is a dtorck type!",
|
||||
(0..depth).map(|_| ' ').collect::<String>(),
|
||||
|
|
@ -499,11 +503,11 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn has_dtor_of_interest<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
ty: ty::Ty<'tcx>) -> bool {
|
||||
fn has_dtor_of_interest<'a, 'b, 'tcx>(cx: &DropckContext<'a, 'b, 'tcx>,
|
||||
ty: ty::Ty<'tcx>) -> bool {
|
||||
match ty.sty {
|
||||
ty::TyEnum(def, _) | ty::TyStruct(def, _) => {
|
||||
def.is_dtorck(tcx)
|
||||
def.is_dtorck(cx.rcx.tcx())
|
||||
}
|
||||
ty::TyTrait(..) | ty::TyProjection(..) => {
|
||||
debug!("ty: {:?} isn't known, and therefore is a dropck type", ty);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
use intrinsics;
|
||||
use rustc::ty::subst::{self, Substs};
|
||||
use rustc::ty::FnSig;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Ty};
|
||||
use {CrateCtxt, require_same_types};
|
||||
|
||||
use std::collections::{HashMap};
|
||||
|
|
@ -25,11 +25,13 @@ use syntax::parse::token;
|
|||
|
||||
use rustc::hir;
|
||||
|
||||
fn equate_intrinsic_type<'a, 'tcx>(tcx: &TyCtxt<'tcx>, it: &hir::ForeignItem,
|
||||
fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
it: &hir::ForeignItem,
|
||||
n_tps: usize,
|
||||
abi: Abi,
|
||||
inputs: Vec<ty::Ty<'tcx>>,
|
||||
output: ty::FnOutput<'tcx>) {
|
||||
let tcx = ccx.tcx;
|
||||
let def_id = tcx.map.local_def_id(it.id);
|
||||
let i_ty = tcx.lookup_item_type(def_id);
|
||||
|
||||
|
|
@ -52,9 +54,8 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: &TyCtxt<'tcx>, it: &hir::ForeignItem,
|
|||
parameters: found {}, expected {}",
|
||||
i_n_tps, n_tps);
|
||||
} else {
|
||||
require_same_types(tcx,
|
||||
require_same_types(ccx,
|
||||
None,
|
||||
false,
|
||||
it.span,
|
||||
i_ty.ty,
|
||||
fty,
|
||||
|
|
@ -304,14 +305,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
|
|||
};
|
||||
(n_tps, inputs, ty::FnConverging(output))
|
||||
};
|
||||
equate_intrinsic_type(
|
||||
tcx,
|
||||
it,
|
||||
n_tps,
|
||||
Abi::RustIntrinsic,
|
||||
inputs,
|
||||
output
|
||||
)
|
||||
equate_intrinsic_type(ccx, it, n_tps, Abi::RustIntrinsic, inputs, output)
|
||||
}
|
||||
|
||||
/// Type-check `extern "platform-intrinsic" { ... }` functions.
|
||||
|
|
@ -377,10 +371,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(tcx, &format!("argument {}", i + 1), it.span,
|
||||
match_intrinsic_type_to_type(ccx, &format!("argument {}", i + 1), it.span,
|
||||
&mut structural_to_nomimal, expected_arg, arg);
|
||||
}
|
||||
match_intrinsic_type_to_type(tcx, "return value", it.span,
|
||||
match_intrinsic_type_to_type(ccx, "return value", it.span,
|
||||
&mut structural_to_nomimal,
|
||||
&intr.output, sig.output.unwrap());
|
||||
return
|
||||
|
|
@ -394,21 +388,15 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
|
|||
}
|
||||
};
|
||||
|
||||
equate_intrinsic_type(
|
||||
tcx,
|
||||
it,
|
||||
n_tps,
|
||||
Abi::PlatformIntrinsic,
|
||||
inputs,
|
||||
ty::FnConverging(output)
|
||||
)
|
||||
equate_intrinsic_type(ccx, it, n_tps, Abi::PlatformIntrinsic,
|
||||
inputs, ty::FnConverging(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>(
|
||||
tcx: &TyCtxt<'tcx>,
|
||||
ccx: &CrateCtxt<'a, 'tcx>,
|
||||
position: &str,
|
||||
span: Span,
|
||||
structural_to_nominal: &mut HashMap<&'a intrinsics::Type, ty::Ty<'tcx>>,
|
||||
|
|
@ -417,7 +405,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
|
|||
use intrinsics::Type::*;
|
||||
|
||||
let simple_error = |real: &str, expected: &str| {
|
||||
span_err!(tcx.sess, span, E0442,
|
||||
span_err!(ccx.tcx.sess, span, E0442,
|
||||
"intrinsic {} has wrong type: found {}, expected {}",
|
||||
position, real, expected)
|
||||
};
|
||||
|
|
@ -455,7 +443,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(tcx, position, span, structural_to_nominal,
|
||||
match_intrinsic_type_to_type(ccx, position, span, structural_to_nominal,
|
||||
inner_expected, ty)
|
||||
}
|
||||
_ => simple_error(&format!("`{}`", t), "raw pointer"),
|
||||
|
|
@ -466,19 +454,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(tcx);
|
||||
let t_len = t.simd_size(ccx.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(tcx);
|
||||
let t_ty = t.simd_type(ccx.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!(tcx.sess, span, E0443,
|
||||
span_err!(ccx.tcx.sess, span, E0443,
|
||||
"intrinsic {} has wrong type: found `{}`, expected `{}` which \
|
||||
was used for this vector type previously in this signature",
|
||||
position,
|
||||
|
|
@ -487,7 +475,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
|
|||
return;
|
||||
}
|
||||
}
|
||||
match_intrinsic_type_to_type(tcx,
|
||||
match_intrinsic_type_to_type(ccx,
|
||||
position,
|
||||
span,
|
||||
structural_to_nominal,
|
||||
|
|
@ -503,7 +491,7 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
|
|||
return
|
||||
}
|
||||
for (e, c) in expected_contents.iter().zip(contents) {
|
||||
match_intrinsic_type_to_type(tcx, position, span, structural_to_nominal,
|
||||
match_intrinsic_type_to_type(ccx, position, span, structural_to_nominal,
|
||||
e, c)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use hir::def::Def;
|
|||
use hir::def_id::DefId;
|
||||
use rustc::ty::subst;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, TyCtxt, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
|
||||
use rustc::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
|
||||
use rustc::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr};
|
||||
use rustc::infer;
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
// Trait must have a method named `m_name` and it should not have
|
||||
// type parameters or early-bound regions.
|
||||
let tcx = fcx.tcx();
|
||||
let method_item = trait_item(tcx, trait_def_id, m_name).unwrap();
|
||||
let method_item = trait_item(fcx, trait_def_id, m_name).unwrap();
|
||||
let method_ty = method_item.as_opt_method().unwrap();
|
||||
assert_eq!(method_ty.generics.types.len(subst::FnSpace), 0);
|
||||
assert_eq!(method_ty.generics.regions.len(subst::FnSpace), 0);
|
||||
|
|
@ -361,26 +361,26 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
|
||||
/// Find item with name `item_name` defined in `trait_def_id`
|
||||
/// and return it, or `None`, if no such item.
|
||||
fn trait_item<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
item_name: ast::Name)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
pub fn trait_item<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
trait_def_id: DefId,
|
||||
item_name: ast::Name)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
{
|
||||
let trait_items = tcx.trait_items(trait_def_id);
|
||||
let trait_items = fcx.tcx().trait_items(trait_def_id);
|
||||
trait_items.iter()
|
||||
.find(|item| item.name() == item_name)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn impl_item<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
item_name: ast::Name)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
pub fn impl_item<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
impl_def_id: DefId,
|
||||
item_name: ast::Name)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
{
|
||||
let impl_items = tcx.impl_items.borrow();
|
||||
let impl_items = fcx.tcx().impl_items.borrow();
|
||||
let impl_items = impl_items.get(&impl_def_id).unwrap();
|
||||
impl_items
|
||||
.iter()
|
||||
.map(|&did| tcx.impl_or_trait_item(did.def_id()))
|
||||
.map(|&did| fcx.tcx().impl_or_trait_item(did.def_id()))
|
||||
.find(|m| m.name() == item_name)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
|
||||
debug!("assemble_inherent_impl_probe {:?}", impl_def_id);
|
||||
|
||||
let item = match impl_item(self.tcx(), impl_def_id, self.item_name) {
|
||||
let item = match self.impl_item(impl_def_id) {
|
||||
Some(m) => m,
|
||||
None => { return; } // No method with correct name on this impl
|
||||
};
|
||||
|
|
@ -563,9 +563,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
|
||||
let tcx = self.tcx();
|
||||
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
|
||||
let item = match trait_item(tcx,
|
||||
bound_trait_ref.def_id(),
|
||||
self.item_name) {
|
||||
let item = match self.trait_item(bound_trait_ref.def_id()) {
|
||||
Some(v) => v,
|
||||
None => { continue; }
|
||||
};
|
||||
|
|
@ -1311,33 +1309,20 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||
{
|
||||
self.tcx().erase_late_bound_regions(value)
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_item<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
impl_def_id: DefId,
|
||||
item_name: ast::Name)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
{
|
||||
let impl_items = tcx.impl_items.borrow();
|
||||
let impl_items = impl_items.get(&impl_def_id).unwrap();
|
||||
impl_items
|
||||
.iter()
|
||||
.map(|&did| tcx.impl_or_trait_item(did.def_id()))
|
||||
.find(|item| item.name() == item_name)
|
||||
}
|
||||
fn impl_item(&self, impl_def_id: DefId)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
{
|
||||
super::impl_item(self.fcx, impl_def_id, self.item_name)
|
||||
}
|
||||
|
||||
/// Find item with name `item_name` defined in `trait_def_id`
|
||||
/// and return it, or `None`, if no such item.
|
||||
fn trait_item<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
item_name: ast::Name)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
{
|
||||
let trait_items = tcx.trait_items(trait_def_id);
|
||||
debug!("trait_method; items: {:?}", trait_items);
|
||||
trait_items.iter()
|
||||
.find(|item| item.name() == item_name)
|
||||
.cloned()
|
||||
/// Find item with name `item_name` defined in `trait_def_id`
|
||||
/// and return it, or `None`, if no such item.
|
||||
fn trait_item(&self, trait_def_id: DefId)
|
||||
-> Option<ty::ImplOrTraitItem<'tcx>>
|
||||
{
|
||||
super::trait_item(self.fcx, trait_def_id, self.item_name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Candidate<'tcx> {
|
||||
|
|
|
|||
|
|
@ -233,10 +233,10 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
CandidateSource::ImplSource(impl_did) => {
|
||||
// Provide the best span we can. Use the item, if local to crate, else
|
||||
// the impl, if local to crate (item may be defaulted), else nothing.
|
||||
let item = impl_item(fcx.tcx(), impl_did, item_name)
|
||||
let item = impl_item(fcx, impl_did, item_name)
|
||||
.or_else(|| {
|
||||
trait_item(
|
||||
fcx.tcx(),
|
||||
fcx,
|
||||
fcx.tcx().impl_trait_ref(impl_did).unwrap().def_id,
|
||||
item_name
|
||||
)
|
||||
|
|
@ -268,7 +268,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
CandidateSource::TraitSource(trait_did) => {
|
||||
let item = trait_item(fcx.tcx(), trait_did, item_name).unwrap();
|
||||
let item = trait_item(fcx, trait_did, item_name).unwrap();
|
||||
let item_span = fcx.tcx().map.def_id_span(item.def_id(), span);
|
||||
span_note!(err, item_span,
|
||||
"candidate #{} is defined in the trait `{}`",
|
||||
|
|
@ -291,8 +291,6 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
rcvr_expr: Option<&hir::Expr>,
|
||||
valid_out_of_scope_traits: Vec<DefId>)
|
||||
{
|
||||
let tcx = fcx.tcx();
|
||||
|
||||
if !valid_out_of_scope_traits.is_empty() {
|
||||
let mut candidates = valid_out_of_scope_traits;
|
||||
candidates.sort();
|
||||
|
|
@ -328,7 +326,7 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
// implementing a trait would be legal but is rejected
|
||||
// here).
|
||||
(type_is_local || info.def_id.is_local())
|
||||
&& trait_item(tcx, info.def_id, item_name).is_some()
|
||||
&& trait_item(fcx, info.def_id, item_name).is_some()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
|
|||
drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| {
|
||||
let _task = ccx.tcx.dep_graph.in_task(DepNode::DropckImpl(drop_impl_did));
|
||||
if drop_impl_did.is_local() {
|
||||
match dropck::check_drop_impl(ccx.tcx, drop_impl_did) {
|
||||
match dropck::check_drop_impl(ccx, drop_impl_did) {
|
||||
Ok(()) => {}
|
||||
Err(()) => {
|
||||
assert!(ccx.tcx.sess.has_errors());
|
||||
|
|
@ -947,7 +947,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
|
||||
// Find associated const definition.
|
||||
if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
|
||||
compare_const_impl(ccx.tcx,
|
||||
compare_const_impl(ccx,
|
||||
&impl_const,
|
||||
impl_item.span,
|
||||
trait_const,
|
||||
|
|
@ -969,7 +969,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
};
|
||||
|
||||
if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
|
||||
compare_impl_method(ccx.tcx,
|
||||
compare_impl_method(ccx,
|
||||
&impl_method,
|
||||
impl_item.span,
|
||||
body.id,
|
||||
|
|
@ -2116,7 +2116,7 @@ pub fn autoderef<'a, 'b, 'tcx, E, I, T, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
let method_call = MethodCall::autoderef(expr.id, autoderefs as u32);
|
||||
fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
|
||||
}
|
||||
make_overloaded_lvalue_return_type(fcx.tcx(), method)
|
||||
make_overloaded_lvalue_return_type(fcx, method)
|
||||
} else {
|
||||
return (resolved_t, autoderefs, None);
|
||||
};
|
||||
|
|
@ -2167,14 +2167,14 @@ fn try_overloaded_deref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
/// For the overloaded lvalue expressions (`*x`, `x[3]`), the trait returns a type of `&T`, but the
|
||||
/// actual type we assign to the *expression* is `T`. So this function just peels off the return
|
||||
/// type by one layer to yield `T`.
|
||||
fn make_overloaded_lvalue_return_type<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
method: MethodCallee<'tcx>)
|
||||
-> ty::TypeAndMut<'tcx>
|
||||
fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
method: MethodCallee<'tcx>)
|
||||
-> ty::TypeAndMut<'tcx>
|
||||
{
|
||||
// extract method return type, which will be &T;
|
||||
// all LB regions should have been instantiated during method lookup
|
||||
let ret_ty = method.ty.fn_ret();
|
||||
let ret_ty = tcx.no_late_bound_regions(&ret_ty).unwrap().unwrap();
|
||||
let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
|
||||
|
||||
// method returns &T, but the type as visible to user is T, so deref
|
||||
ret_ty.builtin_deref(true, NoPreference).unwrap()
|
||||
|
|
@ -2295,7 +2295,7 @@ fn try_index_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
method.map(|method| {
|
||||
debug!("try_index_step: success, using overloaded indexing");
|
||||
fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
|
||||
(input_ty, make_overloaded_lvalue_return_type(fcx.tcx(), method).ty)
|
||||
(input_ty, make_overloaded_lvalue_return_type(fcx, method).ty)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -2308,7 +2308,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
expected: Expectation<'tcx>)
|
||||
-> ty::FnOutput<'tcx> {
|
||||
if method_fn_ty.references_error() {
|
||||
let err_inputs = err_args(fcx.tcx(), args_no_rcvr.len());
|
||||
let err_inputs = err_args(fcx, args_no_rcvr.len());
|
||||
|
||||
let err_inputs = match tuple_arguments {
|
||||
DontTupleArguments => err_inputs,
|
||||
|
|
@ -2387,7 +2387,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
args.len(),
|
||||
if args.len() == 1 {" was"} else {"s were"});
|
||||
expected_arg_tys = &[];
|
||||
err_args(fcx.tcx(), args.len())
|
||||
err_args(fcx, args.len())
|
||||
} else {
|
||||
expected_arg_tys = match expected_arg_tys.get(0) {
|
||||
Some(&ty) => match ty.sty {
|
||||
|
|
@ -2404,7 +2404,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
"cannot use call notation; the first type parameter \
|
||||
for the function trait is neither a tuple nor unit");
|
||||
expected_arg_tys = &[];
|
||||
err_args(fcx.tcx(), args.len())
|
||||
err_args(fcx, args.len())
|
||||
}
|
||||
}
|
||||
} else if expected_arg_count == supplied_arg_count {
|
||||
|
|
@ -2421,7 +2421,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
expected_arg_tys = &[];
|
||||
err_args(fcx.tcx(), supplied_arg_count)
|
||||
err_args(fcx, supplied_arg_count)
|
||||
}
|
||||
} else {
|
||||
span_err!(tcx.sess, sp, E0061,
|
||||
|
|
@ -2431,7 +2431,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
supplied_arg_count,
|
||||
if supplied_arg_count == 1 {" was"} else {"s were"});
|
||||
expected_arg_tys = &[];
|
||||
err_args(fcx.tcx(), supplied_arg_count)
|
||||
err_args(fcx, supplied_arg_count)
|
||||
};
|
||||
|
||||
debug!("check_argument_types: formal_tys={:?}",
|
||||
|
|
@ -2490,7 +2490,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
// The special-cased logic below has three functions:
|
||||
// 1. Provide as good of an expected type as possible.
|
||||
let expected = expected_arg_tys.get(i).map(|&ty| {
|
||||
Expectation::rvalue_hint(fcx.tcx(), ty)
|
||||
Expectation::rvalue_hint(fcx, ty)
|
||||
});
|
||||
|
||||
check_expr_with_expectation(fcx, &arg,
|
||||
|
|
@ -2571,9 +2571,8 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
|
||||
fn err_args<'tcx>(tcx: &TyCtxt<'tcx>, len: usize) -> Vec<Ty<'tcx>> {
|
||||
(0..len).map(|_| tcx.types.err).collect()
|
||||
fn err_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, len: usize) -> Vec<Ty<'tcx>> {
|
||||
(0..len).map(|_| fcx.tcx().types.err).collect()
|
||||
}
|
||||
|
||||
fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
|
|
@ -3241,7 +3240,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
hir::ExprBox(ref subexpr) => {
|
||||
let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
|
||||
match ty.sty {
|
||||
ty::TyBox(ty) => Expectation::rvalue_hint(tcx, ty),
|
||||
ty::TyBox(ty) => Expectation::rvalue_hint(fcx, ty),
|
||||
_ => NoExpectation
|
||||
}
|
||||
});
|
||||
|
|
@ -3286,7 +3285,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
oprnd_t = mt.ty;
|
||||
} else if let Some(method) = try_overloaded_deref(
|
||||
fcx, expr.span, Some(&oprnd), oprnd_t, lvalue_pref) {
|
||||
oprnd_t = make_overloaded_lvalue_return_type(tcx, method).ty;
|
||||
oprnd_t = make_overloaded_lvalue_return_type(fcx, method).ty;
|
||||
fcx.inh.tables.borrow_mut().method_map.insert(MethodCall::expr(expr.id),
|
||||
method);
|
||||
} else {
|
||||
|
|
@ -3329,7 +3328,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
// the last field of a struct can be unsized.
|
||||
ExpectHasType(mt.ty)
|
||||
} else {
|
||||
Expectation::rvalue_hint(tcx, mt.ty)
|
||||
Expectation::rvalue_hint(fcx, mt.ty)
|
||||
}
|
||||
}
|
||||
_ => NoExpectation
|
||||
|
|
@ -3810,8 +3809,8 @@ impl<'tcx> Expectation<'tcx> {
|
|||
/// which still is useful, because it informs integer literals and the like.
|
||||
/// See the test case `test/run-pass/coerce-expect-unsized.rs` and #20169
|
||||
/// for examples of where this comes up,.
|
||||
fn rvalue_hint(tcx: &TyCtxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
|
||||
match tcx.struct_tail(ty).sty {
|
||||
fn rvalue_hint<'a>(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
|
||||
match fcx.tcx().struct_tail(ty).sty {
|
||||
ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
|
||||
ExpectRvalueLikeUnsized(ty)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||
debug!("check_method_receiver: receiver ty = {:?}", rcvr_ty);
|
||||
|
||||
let _ = ::require_same_types(
|
||||
fcx.tcx(), Some(fcx.infcx()), false, span,
|
||||
fcx.ccx, Some(fcx.infcx()), span,
|
||||
sig.inputs[0], rcvr_ty,
|
||||
"mismatched method receiver");
|
||||
}
|
||||
|
|
@ -435,8 +435,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||
.map(|p| Parameter::Type(p))
|
||||
.collect();
|
||||
|
||||
identify_constrained_type_params(self.tcx(),
|
||||
ty_predicates.predicates.as_slice(),
|
||||
identify_constrained_type_params(ty_predicates.predicates.as_slice(),
|
||||
None,
|
||||
&mut constrained_parameters);
|
||||
|
||||
|
|
@ -494,7 +493,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||
span: Span,
|
||||
param_name: ast::Name)
|
||||
{
|
||||
let mut err = error_392(self.tcx(), span, param_name);
|
||||
let mut err = error_392(self.ccx, span, param_name);
|
||||
|
||||
let suggested_marker_id = self.tcx().lang_items.phantom_data();
|
||||
match suggested_marker_id {
|
||||
|
|
@ -512,9 +511,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn reject_shadowing_type_parameters<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
generics: &ty::Generics<'tcx>) {
|
||||
fn reject_shadowing_type_parameters(tcx: &TyCtxt, span: Span, generics: &ty::Generics) {
|
||||
let impl_params = generics.types.get_slice(subst::TypeSpace).iter()
|
||||
.map(|tp| tp.name).collect::<HashSet<_>>();
|
||||
|
||||
|
|
@ -607,25 +604,25 @@ fn impl_implied_bounds<'fcx,'tcx>(fcx: &FnCtxt<'fcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn error_192<'ccx,'tcx>(ccx: &'ccx CrateCtxt<'ccx, 'tcx>, span: Span) {
|
||||
fn error_192(ccx: &CrateCtxt, span: Span) {
|
||||
span_err!(ccx.tcx.sess, span, E0192,
|
||||
"negative impls are only allowed for traits with \
|
||||
default impls (e.g., `Send` and `Sync`)")
|
||||
}
|
||||
|
||||
pub fn error_380<'ccx,'tcx>(ccx: &'ccx CrateCtxt<'ccx, 'tcx>, span: Span) {
|
||||
fn error_380(ccx: &CrateCtxt, span: Span) {
|
||||
span_err!(ccx.tcx.sess, span, E0380,
|
||||
"traits with default impls (`e.g. unsafe impl \
|
||||
Trait for ..`) must have no methods or associated items")
|
||||
}
|
||||
|
||||
pub fn error_392<'tcx>(tcx: &TyCtxt<'tcx>, span: Span, param_name: ast::Name)
|
||||
fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name)
|
||||
-> DiagnosticBuilder<'tcx> {
|
||||
struct_span_err!(tcx.sess, span, E0392,
|
||||
struct_span_err!(ccx.tcx.sess, span, E0392,
|
||||
"parameter `{}` is never used", param_name)
|
||||
}
|
||||
|
||||
pub fn error_194<'tcx>(tcx: &TyCtxt<'tcx>, span: Span, name: ast::Name) {
|
||||
fn error_194(tcx: &TyCtxt, span: Span, name: ast::Name) {
|
||||
span_err!(tcx.sess, span, E0194,
|
||||
"type parameter `{}` shadows another type parameter of the same name",
|
||||
name);
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
|
|||
|
||||
let var_ty = self.fcx.local_ty(l.span, l.id);
|
||||
let var_ty = self.resolve(&var_ty, ResolvingLocal(l.span));
|
||||
write_ty_to_tcx(self.tcx(), l.id, var_ty);
|
||||
write_ty_to_tcx(self.fcx.ccx, l.id, var_ty);
|
||||
intravisit::walk_local(self, l);
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
|
|||
match t.node {
|
||||
hir::TyFixedLengthVec(ref ty, ref count_expr) => {
|
||||
self.visit_ty(&ty);
|
||||
write_ty_to_tcx(self.tcx(), count_expr.id, self.tcx().types.usize);
|
||||
write_ty_to_tcx(self.fcx.ccx, count_expr.id, self.tcx().types.usize);
|
||||
}
|
||||
hir::TyBareFn(ref function_declaration) => {
|
||||
intravisit::walk_fn_decl_nopat(self, &function_declaration.decl);
|
||||
|
|
@ -263,12 +263,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
// Resolve the type of the node with id `id`
|
||||
let n_ty = self.fcx.node_ty(id);
|
||||
let n_ty = self.resolve(&n_ty, reason);
|
||||
write_ty_to_tcx(self.tcx(), id, n_ty);
|
||||
write_ty_to_tcx(self.fcx.ccx, id, n_ty);
|
||||
debug!("Node {} has type {:?}", id, n_ty);
|
||||
|
||||
// Resolve any substitutions
|
||||
self.fcx.opt_node_ty_substs(id, |item_substs| {
|
||||
write_substs_to_tcx(self.tcx(), id,
|
||||
write_substs_to_tcx(self.fcx.ccx, id,
|
||||
self.resolve(item_substs, reason));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,9 +87,7 @@ use std::collections::HashSet;
|
|||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use std::rc::Rc;
|
||||
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::{abi, ast, attr};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax::ptr::P;
|
||||
|
|
@ -565,7 +563,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
});
|
||||
ccx.tcx.predicates.borrow_mut().insert(def_id, ty_method.predicates.clone());
|
||||
|
||||
write_ty_to_tcx(ccx.tcx, id, fty);
|
||||
write_ty_to_tcx(ccx, id, fty);
|
||||
|
||||
debug!("writing method type: def_id={:?} mty={:?}",
|
||||
def_id, ty_method);
|
||||
|
|
@ -582,7 +580,7 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
{
|
||||
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &field.ty);
|
||||
ty_f.fulfill_ty(tt);
|
||||
write_ty_to_tcx(ccx.tcx, field.id, tt);
|
||||
write_ty_to_tcx(ccx, field.id, tt);
|
||||
|
||||
/* add the field to the tcache */
|
||||
ccx.tcx.register_item_type(ccx.tcx.map.local_def_id(field.id),
|
||||
|
|
@ -606,7 +604,7 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
|
||||
ty::GenericPredicates::empty());
|
||||
|
||||
write_ty_to_tcx(ccx.tcx, id, ty);
|
||||
write_ty_to_tcx(ccx, id, ty);
|
||||
|
||||
let associated_const = Rc::new(ty::AssociatedConst {
|
||||
name: name,
|
||||
|
|
@ -684,7 +682,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
}
|
||||
hir::ItemEnum(ref enum_definition, _) => {
|
||||
let (scheme, predicates) = convert_typed_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, scheme.ty);
|
||||
write_ty_to_tcx(ccx, it.id, scheme.ty);
|
||||
convert_enum_variant_types(ccx,
|
||||
tcx.lookup_adt_def_master(ccx.tcx.map.local_def_id(it.id)),
|
||||
scheme,
|
||||
|
|
@ -717,7 +715,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
debug!("convert: impl_bounds={:?}", ty_predicates);
|
||||
|
||||
let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &selfty);
|
||||
write_ty_to_tcx(tcx, it.id, selfty);
|
||||
write_ty_to_tcx(ccx, it.id, selfty);
|
||||
|
||||
tcx.register_item_type(def_id,
|
||||
TypeScheme { generics: ty_generics.clone(),
|
||||
|
|
@ -730,7 +728,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
});
|
||||
tcx.impl_trait_refs.borrow_mut().insert(def_id, trait_ref);
|
||||
|
||||
enforce_impl_params_are_constrained(tcx, generics, &mut ty_predicates, def_id);
|
||||
enforce_impl_params_are_constrained(ccx, generics, &mut ty_predicates, def_id);
|
||||
tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
|
||||
|
||||
|
||||
|
|
@ -807,7 +805,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
}
|
||||
}
|
||||
|
||||
enforce_impl_lifetimes_are_constrained(tcx, generics, def_id, impl_items);
|
||||
enforce_impl_lifetimes_are_constrained(ccx, generics, def_id, impl_items);
|
||||
},
|
||||
hir::ItemTrait(_, _, _, ref trait_items) => {
|
||||
let trait_def = trait_def_of_item(ccx, it);
|
||||
|
|
@ -891,7 +889,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
},
|
||||
hir::ItemStruct(ref struct_def, _) => {
|
||||
let (scheme, predicates) = convert_typed_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, scheme.ty);
|
||||
write_ty_to_tcx(ccx, it.id, scheme.ty);
|
||||
|
||||
let it_def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
let variant = tcx.lookup_adt_def_master(it_def_id).struct_variant();
|
||||
|
|
@ -907,14 +905,14 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||
hir::ItemTy(_, ref generics) => {
|
||||
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
|
||||
let (scheme, _) = convert_typed_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, scheme.ty);
|
||||
write_ty_to_tcx(ccx, it.id, scheme.ty);
|
||||
},
|
||||
_ => {
|
||||
// This call populates the type cache with the converted type
|
||||
// of the item in passing. All we have to do here is to write
|
||||
// it into the node type table.
|
||||
let (scheme, _) = convert_typed_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, scheme.ty);
|
||||
write_ty_to_tcx(ccx, it.id, scheme.ty);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -946,7 +944,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
})
|
||||
}
|
||||
};
|
||||
write_ty_to_tcx(tcx, ctor_id, ctor_ty);
|
||||
write_ty_to_tcx(ccx, ctor_id, ctor_ty);
|
||||
tcx.predicates.borrow_mut().insert(tcx.map.local_def_id(ctor_id), predicates);
|
||||
tcx.register_item_type(tcx.map.local_def_id(ctor_id),
|
||||
TypeScheme {
|
||||
|
|
@ -978,18 +976,19 @@ fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_struct_variant<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
did: DefId,
|
||||
name: ast::Name,
|
||||
disr_val: ty::Disr,
|
||||
def: &hir::VariantData) -> ty::VariantDefData<'tcx, 'tcx> {
|
||||
fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
did: DefId,
|
||||
name: ast::Name,
|
||||
disr_val: ty::Disr,
|
||||
def: &hir::VariantData)
|
||||
-> ty::VariantDefData<'tcx, 'tcx> {
|
||||
let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap();
|
||||
let node_id = tcx.map.as_local_node_id(did).unwrap();
|
||||
let node_id = ccx.tcx.map.as_local_node_id(did).unwrap();
|
||||
let fields = def.fields().iter().map(|f| {
|
||||
let fid = tcx.map.local_def_id(f.id);
|
||||
let fid = ccx.tcx.map.local_def_id(f.id);
|
||||
let dup_span = seen_fields.get(&f.name).cloned();
|
||||
if let Some(prev_span) = dup_span {
|
||||
let mut err = struct_span_err!(tcx.sess, f.span, E0124,
|
||||
let mut err = struct_span_err!(ccx.tcx.sess, f.span, E0124,
|
||||
"field `{}` is already declared",
|
||||
f.name);
|
||||
span_note!(&mut err, prev_span, "previously declared here");
|
||||
|
|
@ -998,7 +997,8 @@ fn convert_struct_variant<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
seen_fields.insert(f.name, f.span);
|
||||
}
|
||||
|
||||
ty::FieldDefData::new(fid, f.name, ty::Visibility::from_hir(&f.vis, node_id, tcx))
|
||||
ty::FieldDefData::new(fid, f.name,
|
||||
ty::Visibility::from_hir(&f.vis, node_id, ccx.tcx))
|
||||
}).collect();
|
||||
ty::VariantDefData {
|
||||
did: did,
|
||||
|
|
@ -1009,71 +1009,63 @@ fn convert_struct_variant<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_struct_def<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
it: &hir::Item,
|
||||
def: &hir::VariantData)
|
||||
-> ty::AdtDefMaster<'tcx>
|
||||
fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
it: &hir::Item,
|
||||
def: &hir::VariantData)
|
||||
-> ty::AdtDefMaster<'tcx>
|
||||
{
|
||||
|
||||
let did = tcx.map.local_def_id(it.id);
|
||||
let did = ccx.tcx.map.local_def_id(it.id);
|
||||
let ctor_id = if !def.is_struct() {
|
||||
tcx.map.local_def_id(def.id())
|
||||
ccx.tcx.map.local_def_id(def.id())
|
||||
} else {
|
||||
did
|
||||
};
|
||||
tcx.intern_adt_def(
|
||||
did,
|
||||
ty::AdtKind::Struct,
|
||||
vec![convert_struct_variant(tcx, ctor_id, it.name, ConstInt::Infer(0), def)]
|
||||
)
|
||||
ccx.tcx.intern_adt_def(did, ty::AdtKind::Struct,
|
||||
vec![convert_struct_variant(ccx, ctor_id, it.name, ConstInt::Infer(0), def)])
|
||||
}
|
||||
|
||||
fn convert_enum_def<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
it: &hir::Item,
|
||||
def: &hir::EnumDef)
|
||||
-> ty::AdtDefMaster<'tcx>
|
||||
{
|
||||
fn print_err(tcx: &TyCtxt, span: Span, ty: ty::Ty, cv: ConstVal) {
|
||||
struct_span_err!(tcx.sess, span, E0079, "mismatched types")
|
||||
.note_expected_found(&"type", &ty, &format!("{}", cv.description()))
|
||||
.emit();
|
||||
}
|
||||
fn evaluate_disr_expr<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
repr_ty: attr::IntType,
|
||||
e: &hir::Expr) -> Option<ty::Disr> {
|
||||
fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
|
||||
-> Option<ty::Disr> {
|
||||
debug!("disr expr, checking {}", pprust::expr_to_string(e));
|
||||
|
||||
let ty_hint = repr_ty.to_ty(tcx);
|
||||
let ty_hint = repr_ty.to_ty(ccx.tcx);
|
||||
let print_err = |cv: ConstVal| {
|
||||
struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types")
|
||||
.note_expected_found(&"type", &ty_hint, &format!("{}", cv.description()))
|
||||
.emit();
|
||||
};
|
||||
|
||||
let hint = UncheckedExprHint(ty_hint);
|
||||
match eval_const_expr_partial(tcx, e, hint, None) {
|
||||
match eval_const_expr_partial(ccx.tcx, e, hint, None) {
|
||||
Ok(ConstVal::Integral(i)) => {
|
||||
// FIXME: eval_const_expr_partial should return an error if the hint is wrong
|
||||
match (repr_ty, i) {
|
||||
(attr::SignedInt(ast::IntTy::I8), ConstInt::I8(_)) => Some(i),
|
||||
(attr::SignedInt(ast::IntTy::I16), ConstInt::I16(_)) => Some(i),
|
||||
(attr::SignedInt(ast::IntTy::I32), ConstInt::I32(_)) => Some(i),
|
||||
(attr::SignedInt(ast::IntTy::I64), ConstInt::I64(_)) => Some(i),
|
||||
(attr::SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) => Some(i),
|
||||
(attr::UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) => Some(i),
|
||||
(attr::UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) => Some(i),
|
||||
(attr::UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) => Some(i),
|
||||
(attr::UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) => Some(i),
|
||||
(attr::SignedInt(ast::IntTy::I8), ConstInt::I8(_)) |
|
||||
(attr::SignedInt(ast::IntTy::I16), ConstInt::I16(_)) |
|
||||
(attr::SignedInt(ast::IntTy::I32), ConstInt::I32(_)) |
|
||||
(attr::SignedInt(ast::IntTy::I64), ConstInt::I64(_)) |
|
||||
(attr::SignedInt(ast::IntTy::Is), ConstInt::Isize(_)) |
|
||||
(attr::UnsignedInt(ast::UintTy::U8), ConstInt::U8(_)) |
|
||||
(attr::UnsignedInt(ast::UintTy::U16), ConstInt::U16(_)) |
|
||||
(attr::UnsignedInt(ast::UintTy::U32), ConstInt::U32(_)) |
|
||||
(attr::UnsignedInt(ast::UintTy::U64), ConstInt::U64(_)) |
|
||||
(attr::UnsignedInt(ast::UintTy::Us), ConstInt::Usize(_)) => Some(i),
|
||||
(_, i) => {
|
||||
print_err(tcx, e.span, ty_hint, ConstVal::Integral(i));
|
||||
print_err(ConstVal::Integral(i));
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
Ok(cv) => {
|
||||
print_err(tcx, e.span, ty_hint, cv);
|
||||
print_err(cv);
|
||||
None
|
||||
},
|
||||
// enum variant evaluation happens before the global constant check
|
||||
// so we need to report the real error
|
||||
Err(ConstEvalErr { kind: ErroneousReferencedConstant(box err), ..}) |
|
||||
Err(err) => {
|
||||
let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
|
||||
let mut diag = struct_span_err!(ccx.tcx.sess, err.span, E0080,
|
||||
"constant evaluation error: {}",
|
||||
err.description());
|
||||
if !e.span.contains(err.span) {
|
||||
|
|
@ -1085,54 +1077,34 @@ fn convert_enum_def<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn report_discrim_overflow(tcx: &TyCtxt,
|
||||
variant_span: Span,
|
||||
variant_name: &str,
|
||||
prev_val: ty::Disr) {
|
||||
span_err!(tcx.sess, variant_span, E0370,
|
||||
"enum discriminant overflowed on value after {}; \
|
||||
set explicitly via {} = {} if that is desired outcome",
|
||||
prev_val, variant_name, prev_val.wrap_incr());
|
||||
}
|
||||
|
||||
fn next_disr(tcx: &TyCtxt,
|
||||
v: &hir::Variant,
|
||||
repr_type: attr::IntType,
|
||||
prev_disr_val: Option<ty::Disr>) -> Option<ty::Disr> {
|
||||
if let Some(prev_disr_val) = prev_disr_val {
|
||||
let result = repr_type.disr_incr(prev_disr_val);
|
||||
if let None = result {
|
||||
report_discrim_overflow(tcx, v.span, &v.node.name.as_str(), prev_disr_val);
|
||||
}
|
||||
result
|
||||
} else {
|
||||
Some(repr_type.initial_discriminant(tcx))
|
||||
}
|
||||
}
|
||||
fn convert_enum_variant<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
v: &hir::Variant,
|
||||
disr: ty::Disr)
|
||||
-> ty::VariantDefData<'tcx, 'tcx>
|
||||
{
|
||||
let did = tcx.map.local_def_id(v.node.data.id());
|
||||
let name = v.node.name;
|
||||
convert_struct_variant(tcx, did, name, disr, &v.node.data)
|
||||
}
|
||||
fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
it: &hir::Item,
|
||||
def: &hir::EnumDef)
|
||||
-> ty::AdtDefMaster<'tcx>
|
||||
{
|
||||
let tcx = ccx.tcx;
|
||||
let did = tcx.map.local_def_id(it.id);
|
||||
let repr_hints = tcx.lookup_repr_hints(did);
|
||||
let repr_type = tcx.enum_repr_type(repr_hints.get(0));
|
||||
let mut prev_disr = None;
|
||||
let initial = repr_type.initial_discriminant(tcx);
|
||||
let mut prev_disr = None::<ty::Disr>;
|
||||
let variants = def.variants.iter().map(|v| {
|
||||
let disr = match v.node.disr_expr {
|
||||
Some(ref e) => evaluate_disr_expr(tcx, repr_type, e),
|
||||
None => next_disr(tcx, v, repr_type, prev_disr)
|
||||
}.unwrap_or_else(|| {
|
||||
prev_disr.map(ty::Disr::wrap_incr)
|
||||
.unwrap_or(repr_type.initial_discriminant(tcx))
|
||||
});
|
||||
|
||||
let wrapped_disr = prev_disr.map_or(initial, |d| d.wrap_incr());
|
||||
let disr = if let Some(ref e) = v.node.disr_expr {
|
||||
evaluate_disr_expr(ccx, repr_type, e)
|
||||
} else if let Some(disr) = repr_type.disr_incr(tcx, prev_disr) {
|
||||
Some(disr)
|
||||
} else {
|
||||
span_err!(tcx.sess, v.span, E0370,
|
||||
"enum discriminant overflowed on value after {}; \
|
||||
set explicitly via {} = {} if that is desired outcome",
|
||||
prev_disr.unwrap(), v.node.name, wrapped_disr);
|
||||
None
|
||||
}.unwrap_or(wrapped_disr);
|
||||
prev_disr = Some(disr);
|
||||
convert_enum_variant(tcx, v, disr)
|
||||
|
||||
let did = tcx.map.local_def_id(v.node.data.id());
|
||||
convert_struct_variant(ccx, did, v.node.name, disr, &v.node.data)
|
||||
}).collect();
|
||||
tcx.intern_adt_def(tcx.map.local_def_id(it.id), ty::AdtKind::Enum, variants)
|
||||
}
|
||||
|
|
@ -1471,16 +1443,16 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||
ty::TypeScheme { ty: ty, generics: ty_generics }
|
||||
}
|
||||
hir::ItemEnum(ref ei, ref generics) => {
|
||||
let def = convert_enum_def(ccx, it, ei);
|
||||
let ty_generics = ty_generics_for_type(ccx, generics);
|
||||
let substs = mk_item_substs(ccx, &ty_generics);
|
||||
let def = convert_enum_def(tcx, it, ei);
|
||||
let t = tcx.mk_enum(def, tcx.mk_substs(substs));
|
||||
ty::TypeScheme { ty: t, generics: ty_generics }
|
||||
}
|
||||
hir::ItemStruct(ref si, ref generics) => {
|
||||
let def = convert_struct_def(ccx, it, si);
|
||||
let ty_generics = ty_generics_for_type(ccx, generics);
|
||||
let substs = mk_item_substs(ccx, &ty_generics);
|
||||
let def = convert_struct_def(tcx, it, si);
|
||||
let t = tcx.mk_struct(def, tcx.mk_substs(substs));
|
||||
ty::TypeScheme { ty: t, generics: ty_generics }
|
||||
}
|
||||
|
|
@ -1606,7 +1578,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
let abi = tcx.map.get_foreign_abi(it.id);
|
||||
|
||||
let scheme = type_scheme_of_foreign_item(ccx, it, abi);
|
||||
write_ty_to_tcx(ccx.tcx, it.id, scheme.ty);
|
||||
write_ty_to_tcx(ccx, it.id, scheme.ty);
|
||||
|
||||
let predicates = match it.node {
|
||||
hir::ForeignItemFn(_, ref generics) => {
|
||||
|
|
@ -2229,13 +2201,13 @@ fn mk_item_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||
}
|
||||
|
||||
/// Checks that all the type parameters on an impl
|
||||
fn enforce_impl_params_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
ast_generics: &hir::Generics,
|
||||
impl_predicates: &mut ty::GenericPredicates<'tcx>,
|
||||
impl_def_id: DefId)
|
||||
fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
ast_generics: &hir::Generics,
|
||||
impl_predicates: &mut ty::GenericPredicates<'tcx>,
|
||||
impl_def_id: DefId)
|
||||
{
|
||||
let impl_scheme = tcx.lookup_item_type(impl_def_id);
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||
let impl_scheme = ccx.tcx.lookup_item_type(impl_def_id);
|
||||
let impl_trait_ref = ccx.tcx.impl_trait_ref(impl_def_id);
|
||||
|
||||
assert!(impl_predicates.predicates.is_empty_in(FnSpace));
|
||||
assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
|
||||
|
|
@ -2249,8 +2221,7 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
|
||||
}
|
||||
|
||||
ctp::setup_constraining_predicates(tcx,
|
||||
impl_predicates.predicates.get_mut_slice(TypeSpace),
|
||||
ctp::setup_constraining_predicates(impl_predicates.predicates.get_mut_slice(TypeSpace),
|
||||
impl_trait_ref,
|
||||
&mut input_parameters);
|
||||
|
||||
|
|
@ -2259,42 +2230,41 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
idx: index as u32,
|
||||
name: ty_param.name };
|
||||
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
|
||||
report_unused_parameter(tcx, ty_param.span, "type", ¶m_ty.to_string());
|
||||
report_unused_parameter(ccx, ty_param.span, "type", ¶m_ty.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
ast_generics: &hir::Generics,
|
||||
impl_def_id: DefId,
|
||||
impl_items: &[hir::ImplItem])
|
||||
fn enforce_impl_lifetimes_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
ast_generics: &hir::Generics,
|
||||
impl_def_id: DefId,
|
||||
impl_items: &[hir::ImplItem])
|
||||
{
|
||||
// Every lifetime used in an associated type must be constrained.
|
||||
let impl_scheme = tcx.lookup_item_type(impl_def_id);
|
||||
let impl_predicates = tcx.lookup_predicates(impl_def_id);
|
||||
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
|
||||
let impl_scheme = ccx.tcx.lookup_item_type(impl_def_id);
|
||||
let impl_predicates = ccx.tcx.lookup_predicates(impl_def_id);
|
||||
let impl_trait_ref = ccx.tcx.impl_trait_ref(impl_def_id);
|
||||
|
||||
let mut input_parameters: HashSet<_> =
|
||||
ctp::parameters_for_type(impl_scheme.ty, false).into_iter().collect();
|
||||
if let Some(ref trait_ref) = impl_trait_ref {
|
||||
input_parameters.extend(ctp::parameters_for_trait_ref(trait_ref, false));
|
||||
}
|
||||
ctp::identify_constrained_type_params(tcx,
|
||||
ctp::identify_constrained_type_params(
|
||||
&impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters);
|
||||
|
||||
let lifetimes_in_associated_types: HashSet<_> =
|
||||
impl_items.iter()
|
||||
.map(|item| tcx.impl_or_trait_item(tcx.map.local_def_id(item.id)))
|
||||
.filter_map(|item| match item {
|
||||
ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
|
||||
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
|
||||
})
|
||||
.flat_map(|ty| ctp::parameters_for_type(ty, true))
|
||||
.filter_map(|p| match p {
|
||||
ctp::Parameter::Type(_) => None,
|
||||
ctp::Parameter::Region(r) => Some(r),
|
||||
})
|
||||
.collect();
|
||||
let lifetimes_in_associated_types: HashSet<_> = impl_items.iter()
|
||||
.map(|item| ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(item.id)))
|
||||
.filter_map(|item| match item {
|
||||
ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
|
||||
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
|
||||
})
|
||||
.flat_map(|ty| ctp::parameters_for_type(ty, true))
|
||||
.filter_map(|p| match p {
|
||||
ctp::Parameter::Type(_) => None,
|
||||
ctp::Parameter::Region(r) => Some(r),
|
||||
})
|
||||
.collect();
|
||||
|
||||
for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
|
||||
let region = ty::EarlyBoundRegion { space: TypeSpace,
|
||||
|
|
@ -2304,7 +2274,7 @@ fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
lifetimes_in_associated_types.contains(®ion) && // (*)
|
||||
!input_parameters.contains(&ctp::Parameter::Region(region))
|
||||
{
|
||||
report_unused_parameter(tcx, lifetime_def.lifetime.span,
|
||||
report_unused_parameter(ccx, lifetime_def.lifetime.span,
|
||||
"lifetime", ®ion.name.to_string());
|
||||
}
|
||||
}
|
||||
|
|
@ -2329,12 +2299,12 @@ fn enforce_impl_lifetimes_are_constrained<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
// used elsewhere are not projected back out.
|
||||
}
|
||||
|
||||
fn report_unused_parameter(tcx: &TyCtxt,
|
||||
fn report_unused_parameter(ccx: &CrateCtxt,
|
||||
span: Span,
|
||||
kind: &str,
|
||||
name: &str)
|
||||
{
|
||||
span_err!(tcx.sess, span, E0207,
|
||||
span_err!(ccx.tcx.sess, span, E0207,
|
||||
"the {} parameter `{}` is not constrained by the \
|
||||
impl trait, self type, or predicates",
|
||||
kind, name);
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::ty::subst;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, subst, Ty};
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
|
|
@ -94,13 +93,12 @@ fn parameters_for_region(region: &ty::Region) -> Option<Parameter> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn identify_constrained_type_params<'tcx>(_tcx: &TyCtxt<'tcx>,
|
||||
predicates: &[ty::Predicate<'tcx>],
|
||||
pub fn identify_constrained_type_params<'tcx>(predicates: &[ty::Predicate<'tcx>],
|
||||
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
input_parameters: &mut HashSet<Parameter>)
|
||||
{
|
||||
let mut predicates = predicates.to_owned();
|
||||
setup_constraining_predicates(_tcx, &mut predicates, impl_trait_ref, input_parameters);
|
||||
setup_constraining_predicates(&mut predicates, impl_trait_ref, input_parameters);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -144,8 +142,7 @@ pub fn identify_constrained_type_params<'tcx>(_tcx: &TyCtxt<'tcx>,
|
|||
/// which is determined by 1, which requires `U`, that is determined
|
||||
/// by 0. I should probably pick a less tangled example, but I can't
|
||||
/// think of any.
|
||||
pub fn setup_constraining_predicates<'tcx>(_tcx: &TyCtxt<'tcx>,
|
||||
predicates: &mut [ty::Predicate<'tcx>],
|
||||
pub fn setup_constraining_predicates<'tcx>(predicates: &mut [ty::Predicate<'tcx>],
|
||||
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
input_parameters: &mut HashSet<Parameter>)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -153,13 +153,13 @@ pub struct CrateCtxt<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
// Functions that write types into the node type table
|
||||
fn write_ty_to_tcx<'tcx>(tcx: &TyCtxt<'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
|
||||
fn write_ty_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, node_id: ast::NodeId, ty: Ty<'tcx>) {
|
||||
debug!("write_ty_to_tcx({}, {:?})", node_id, ty);
|
||||
assert!(!ty.needs_infer());
|
||||
tcx.node_type_insert(node_id, ty);
|
||||
ccx.tcx.node_type_insert(node_id, ty);
|
||||
}
|
||||
|
||||
fn write_substs_to_tcx<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
item_substs: ty::ItemSubsts<'tcx>) {
|
||||
if !item_substs.is_noop() {
|
||||
|
|
@ -169,7 +169,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||
|
||||
assert!(!item_substs.substs.types.needs_infer());
|
||||
|
||||
tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
|
||||
ccx.tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,44 +192,35 @@ fn require_c_abi_if_variadic(tcx: &TyCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
fn require_same_types<'a, 'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
|
||||
t1_is_expected: bool,
|
||||
span: Span,
|
||||
t1: Ty<'tcx>,
|
||||
t2: Ty<'tcx>,
|
||||
msg: &str)
|
||||
-> bool
|
||||
{
|
||||
let result = match maybe_infcx {
|
||||
None => {
|
||||
let infcx = InferCtxt::new(tcx, &tcx.tables, None, ProjectionMode::AnyFinal);
|
||||
infer::mk_eqty(&infcx, t1_is_expected, TypeOrigin::Misc(span), t1, t2)
|
||||
}
|
||||
Some(infcx) => {
|
||||
infer::mk_eqty(infcx, t1_is_expected, TypeOrigin::Misc(span), t1, t2)
|
||||
}
|
||||
let err = if let Some(infcx) = maybe_infcx {
|
||||
infer::mk_eqty(infcx, false, TypeOrigin::Misc(span), t1, t2).err()
|
||||
} else {
|
||||
let infcx = InferCtxt::new(ccx.tcx, &ccx.tcx.tables, None, ProjectionMode::AnyFinal);
|
||||
infer::mk_eqty(&infcx, false, TypeOrigin::Misc(span), t1, t2).err()
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(_) => true,
|
||||
Err(ref terr) => {
|
||||
let mut err = struct_span_err!(tcx.sess, span, E0211, "{}", msg);
|
||||
err = err.span_label(span, &terr);
|
||||
let (mut expected_ty, mut found_ty) =
|
||||
if t1_is_expected {(t1, t2)} else {(t2, t1)};
|
||||
if let Some(infcx) = maybe_infcx {
|
||||
expected_ty = infcx.resolve_type_vars_if_possible(&expected_ty);
|
||||
found_ty = infcx.resolve_type_vars_if_possible(&found_ty);
|
||||
}
|
||||
err = err.note_expected_found(&"type",
|
||||
&expected_ty,
|
||||
&found_ty);
|
||||
tcx.note_and_explain_type_err(&mut err, terr, span);
|
||||
err.emit();
|
||||
false
|
||||
if let Some(ref terr) = err {
|
||||
let mut err = struct_span_err!(ccx.tcx.sess, span, E0211, "{}", msg);
|
||||
err = err.span_label(span, &terr);
|
||||
let (mut expected_ty, mut found_ty) = (t2, t1);
|
||||
if let Some(infcx) = maybe_infcx {
|
||||
expected_ty = infcx.resolve_type_vars_if_possible(&expected_ty);
|
||||
found_ty = infcx.resolve_type_vars_if_possible(&found_ty);
|
||||
}
|
||||
err = err.note_expected_found(&"type", &expected_ty, &found_ty);
|
||||
ccx.tcx.note_and_explain_type_err(&mut err, terr, span);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
err.is_none()
|
||||
}
|
||||
|
||||
fn check_main_fn_ty(ccx: &CrateCtxt,
|
||||
|
|
@ -265,7 +256,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
|
|||
})
|
||||
});
|
||||
|
||||
require_same_types(tcx, None, false, main_span, main_t, se_ty,
|
||||
require_same_types(ccx, None, main_span, main_t, se_ty,
|
||||
"main function has wrong type");
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -313,7 +304,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
|||
}),
|
||||
});
|
||||
|
||||
require_same_types(tcx, None, false, start_span, start_t, se_ty,
|
||||
require_same_types(ccx, None, start_span, start_t, se_ty,
|
||||
"start function has wrong type");
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue