diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 75a31d156514..a18fdebbaa91 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -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; + fn disr_incr(&self, tcx: &TyCtxt, val: Option) -> Option; 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 { - self.assert_ty_matches(val); - (val + ConstInt::Infer(1)).ok() + fn disr_incr(&self, tcx: &TyCtxt, val: Option) -> Option { + if let Some(val) = val { + self.assert_ty_matches(val); + (val + ConstInt::Infer(1)).ok() + } else { + Some(self.initial_discriminant(tcx)) + } } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5e07011d5baf..b756df05faa5 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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) -> 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::>>(); 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_param_name: &str, assoc_name: &str, @@ -1237,7 +1238,7 @@ fn one_bound_for_assoc_type<'tcx>(tcx: &TyCtxt<'tcx>, -> Result, 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 { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 544fb117f361..b07437d299b2 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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", ); diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index a96b739ebcf9..5d37d5123e44 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -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 }); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 36944733dc8d..28d8206a145e 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -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(); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 2e2b3686f851..0ddf616bb54f 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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; impl Drop for S { ... }`). /// -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::(), @@ -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); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 29a9ae9e5162..79aa647d239d 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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>, 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) } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 26d1f50f8c54..467956b6497a 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -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> +pub fn trait_item<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, + trait_def_id: DefId, + item_name: ast::Name) + -> Option> { - 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> +pub fn impl_item<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, + impl_def_id: DefId, + item_name: ast::Name) + -> Option> { - 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) } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 0e064fbc45ba..96cedc76d050 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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> -{ - 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> + { + 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> -{ - 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> + { + super::trait_item(self.fcx, trait_def_id, self.item_name) + } } impl<'tcx> Candidate<'tcx> { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 6b90dcd54bf0..9b81c4e2e923 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -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) { - 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::>(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 2ad64e448704..d9807cc7baed 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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> { - (0..len).map(|_| tcx.types.err).collect() +fn err_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, len: usize) -> Vec> { + (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) } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index ffdae2339705..17856dc4255c 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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::>(); @@ -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); diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 4341ae5dac1c..a7039dcd91c3 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -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)); }); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 787324897a31..9393dd1bce7a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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 = 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 { + fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr) + -> Option { 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) -> Option { - 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::; 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); diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 7e8b08c58539..08c1b5fcc82c 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -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 { } } -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>, input_parameters: &mut HashSet) { 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>, input_parameters: &mut HashSet) { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index c65b12b1829b..e5e4fda10efc 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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"); } _ => {