rustc: move defaulting's use of &mut Substs from InferCtxt to typeck.

This commit is contained in:
Eduard Burtescu 2016-08-17 03:56:18 +03:00
parent c87063f07e
commit 5ef6af09e3
12 changed files with 212 additions and 231 deletions

View File

@ -1172,15 +1172,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.tcx.mk_var(self.next_ty_var_id(false))
}
pub fn next_ty_var_with_default(&self,
default: Option<type_variable::Default<'tcx>>) -> Ty<'tcx> {
let ty_var_id = self.type_variables
.borrow_mut()
.new_var(false, default);
self.tcx.mk_var(ty_var_id)
}
pub fn next_diverging_ty_var(&self) -> Ty<'tcx> {
self.tcx.mk_var(self.next_ty_var_id(true))
}
@ -1205,35 +1196,49 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ty::ReVar(self.region_vars.new_region_var(origin))
}
/// Create a region inference variable for the given
/// region parameter definition.
pub fn region_var_for_def(&self,
span: Span,
def: &ty::RegionParameterDef)
-> ty::Region {
self.next_region_var(EarlyBoundRegion(span, def.name))
}
/// Create a type inference variable for the given
/// type parameter definition. The substitutions are
/// for actual parameters that may be referred to by
/// the default of this type parameter, if it exists.
/// E.g. `struct Foo<A, B, C = (A, B)>(...);` when
/// used in a path such as `Foo::<T, U>::new()` will
/// use an inference variable for `C` with `[T, U]`
/// as the substitutions for the default, `(T, U)`.
pub fn type_var_for_def(&self,
span: Span,
def: &ty::TypeParameterDef<'tcx>,
substs: &Substs<'tcx>)
-> Ty<'tcx> {
let default = def.default.map(|default| {
type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
def_id: def.default_def_id
}
});
let ty_var_id = self.type_variables
.borrow_mut()
.new_var(false, default);
self.tcx.mk_var(ty_var_id)
}
pub fn region_vars_for_defs(&self,
span: Span,
defs: &[ty::RegionParameterDef])
-> Vec<ty::Region> {
defs.iter()
.map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
.collect()
}
// We have to take `&mut Substs` in order to provide the correct substitutions for defaults
// along the way, for this reason we don't return them.
pub fn type_vars_for_defs(&self,
span: Span,
space: subst::ParamSpace,
substs: &mut Substs<'tcx>,
defs: &[ty::TypeParameterDef<'tcx>]) {
for def in defs.iter() {
let default = def.default.map(|default| {
type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
def_id: def.default_def_id
}
});
let ty_var = self.next_ty_var_with_default(default);
substs.types.push(space, ty_var);
}
defs.iter().map(|def| self.region_var_for_def(span, def)).collect()
}
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
@ -1243,21 +1248,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
generics: &ty::Generics<'tcx>)
-> &'tcx subst::Substs<'tcx>
{
let type_params = subst::VecPerParamSpace::empty();
let region_params =
generics.regions.map(
|d| self.next_region_var(EarlyBoundRegion(span, d.name)));
let mut substs = subst::Substs::new(type_params, region_params);
for space in subst::ParamSpace::all().iter() {
self.type_vars_for_defs(
span,
*space,
&mut substs,
generics.types.get_slice(*space));
}
let type_defs = generics.types.as_full_slice();
let region_defs = generics.regions.as_full_slice();
let substs = Substs::from_param_defs(region_defs, type_defs, |def| {
self.region_var_for_def(span, def)
}, |def, substs| {
self.type_var_for_def(span, def, substs)
});
self.tcx.mk_substs(substs)
}
@ -1269,25 +1266,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span: Span,
generics: &ty::Generics<'tcx>,
self_ty: Ty<'tcx>)
-> subst::Substs<'tcx>
-> &'tcx subst::Substs<'tcx>
{
assert!(generics.types.len(subst::SelfSpace) == 1);
assert!(generics.types.len(subst::FnSpace) == 0);
assert!(generics.regions.len(subst::SelfSpace) == 0);
assert!(generics.regions.len(subst::FnSpace) == 0);
let type_params = Vec::new();
let type_defs = generics.types.as_full_slice();
let region_defs = generics.regions.as_full_slice();
let substs = Substs::from_param_defs(region_defs, type_defs, |def| {
self.region_var_for_def(span, def)
}, |def, substs| {
if def.space == subst::SelfSpace {
self_ty
} else {
self.type_var_for_def(span, def, substs)
}
});
let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
let regions = self.region_vars_for_defs(span, region_param_defs);
let mut substs = subst::Substs::new_trait(type_params, regions, self_ty);
let type_parameter_defs = generics.types.get_slice(subst::TypeSpace);
self.type_vars_for_defs(span, subst::TypeSpace, &mut substs, type_parameter_defs);
return substs;
self.tcx.mk_substs(substs)
}
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {

View File

@ -31,7 +31,7 @@ use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use ty::error::ExpectedFound;
use ty::fast_reject;
use ty::fold::TypeFolder;
use ty::subst::{self, Subst, TypeSpace};
use ty::subst::{Subst, TypeSpace};
use util::nodemap::{FnvHashMap, FnvHashSet};
use std::cmp;
@ -167,27 +167,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
});
}
fn impl_substs(&self,
did: DefId,
obligation: PredicateObligation<'tcx>)
-> subst::Substs<'tcx> {
let tcx = self.tcx;
let ity = tcx.lookup_item_type(did);
let (tps, rps, _) =
(ity.generics.types.get_slice(TypeSpace),
ity.generics.regions.get_slice(TypeSpace),
ity.ty);
let rps = self.region_vars_for_defs(obligation.cause.span, rps);
let mut substs = subst::Substs::new_type(vec![], rps);
self.type_vars_for_defs(obligation.cause.span,
TypeSpace,
&mut substs,
tps);
substs
}
fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
/// returns the fuzzy category of a given type, or None
/// if the type can be equated to any type.
@ -242,10 +221,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.tcx.lookup_trait_def(trait_ref.def_id)
.for_each_relevant_impl(self.tcx, trait_self_ty, |def_id| {
let ity = tcx.lookup_item_type(def_id);
let impl_substs = self.fresh_substs_for_generics(obligation.cause.span,
&ity.generics);
let impl_trait_ref = tcx
.impl_trait_ref(def_id)
.unwrap()
.subst(tcx, &self.impl_substs(def_id, obligation.clone()));
.subst(tcx, impl_substs);
let impl_self_ty = impl_trait_ref.self_ty();

View File

@ -358,8 +358,7 @@ pub fn fresh_type_vars_for_impl<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx
impl_def_id: DefId)
-> &'tcx Substs<'tcx>
{
let tcx = infcx.tcx;
let impl_generics = tcx.lookup_item_type(impl_def_id).generics;
let impl_generics = infcx.tcx.lookup_item_type(impl_def_id).generics;
infcx.fresh_substs_for_generics(span, &impl_generics)
}

View File

@ -73,6 +73,33 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
}
/// Creates a Substs for generic parameter definitions,
/// by calling closures to obtain each region and type.
/// The closures get to observe the Substs as they're
/// being built, which can be used to correctly
/// substitute defaults of type parameters.
pub fn from_generics<FR, FT>(generics: &ty::Generics<'tcx>,
mut mk_region: FR,
mut mk_type: FT)
-> Substs<'tcx>
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
let mut substs = Substs::empty();
for &space in &ParamSpace::all() {
for def in generics.regions.get_slice(space) {
let region = mk_region(def, &substs);
assert_eq!(substs.regions.len(def.space), def.index as usize);
substs.regions.push(def.space, region);
}
for def in generics.types.get_slice(space) {
let ty = mk_type(def, &substs);
assert_eq!(substs.types.len(def.space), def.index as usize);
substs.types.push(def.space, ty);
}
}
substs
}
pub fn is_noop(&self) -> bool {
self.regions.is_empty() && self.types.is_empty()
}
@ -81,6 +108,10 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
*self.types.get(ty_param_def.space, ty_param_def.index as usize)
}
pub fn region_for_def(&self, def: &ty::RegionParameterDef) -> ty::Region {
*self.regions.get(def.space, def.index as usize)
}
pub fn self_ty(&self) -> Option<Ty<'tcx>> {
self.types.get_self().cloned()
}

View File

@ -55,7 +55,7 @@ use hir::def_id::DefId;
use hir::print as pprust;
use middle::resolve_lifetime as rl;
use rustc::lint;
use rustc::ty::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace};
use rustc::ty::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs};
use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::wf::object_region_bounds;
@ -115,11 +115,15 @@ pub trait AstConv<'gcx, 'tcx> {
fn get_free_substs(&self) -> Option<&Substs<'tcx>>;
/// What type should we use when a type is omitted?
fn ty_infer(&self,
param_and_substs: Option<ty::TypeParameterDef<'tcx>>,
substs: Option<&mut Substs<'tcx>>,
space: Option<ParamSpace>,
span: Span) -> Ty<'tcx>;
fn ty_infer(&self, span: Span) -> Ty<'tcx>;
/// Same as ty_infer, but with a known type parameter definition.
fn ty_infer_for_def(&self,
_def: &ty::TypeParameterDef<'tcx>,
_substs: &Substs<'tcx>,
span: Span) -> Ty<'tcx> {
self.ty_infer(span)
}
/// Projecting an associated type from a (potentially)
/// higher-ranked trait reference is more complicated, because of
@ -535,26 +539,28 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
self_ty: Option<Ty<'tcx>>)
-> Vec<Ty<'tcx>>
{
fn default_type_parameter<'tcx>(p: &ty::TypeParameterDef<'tcx>, self_ty: Option<Ty<'tcx>>)
-> Option<ty::TypeParameterDef<'tcx>>
{
let use_default = |p: &ty::TypeParameterDef<'tcx>| {
if let Some(ref default) = p.default {
if self_ty.is_none() && default.has_self_ty() {
// There is no suitable inference default for a type parameter
// that references self with no self-type provided.
return None;
return false;
}
}
Some(p.clone())
}
true
};
if param_mode == PathParamMode::Optional && types_provided.is_empty() {
ty_param_defs
.iter()
.map(|p| self.ty_infer(default_type_parameter(p, self_ty), Some(&mut substs),
Some(TypeSpace), span))
.collect()
ty_param_defs.iter().map(|def| {
let ty_var = if use_default(def) {
self.ty_infer_for_def(def, &substs, span)
} else {
self.ty_infer(span)
};
substs.types.push(def.space, ty_var);
ty_var
}).collect()
} else {
types_provided
}
@ -1828,7 +1834,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// values in a ExprClosure, or as
// the type of local variables. Both of these cases are
// handled specially and will not descend into this routine.
self.ty_infer(None, None, None, ast_ty.span)
self.ty_infer(ast_ty.span)
}
};
@ -1845,7 +1851,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
{
match a.ty.node {
hir::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
hir::TyInfer => self.ty_infer(None, None, None, a.ty.span),
hir::TyInfer => self.ty_infer(a.ty.span),
_ => self.ast_ty_to_ty(rscope, &a.ty),
}
}
@ -2067,8 +2073,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
let output_ty = match decl.output {
_ if is_infer && expected_ret_ty.is_some() =>
expected_ret_ty.unwrap(),
_ if is_infer =>
self.ty_infer(None, None, None, decl.output.span()),
_ if is_infer => self.ty_infer(decl.output.span()),
hir::Return(ref output) =>
self.ast_ty_to_ty(&rb, &output),
hir::DefaultReturn(..) => bug!(),

View File

@ -198,7 +198,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
fn fresh_receiver_substs(&mut self,
self_ty: Ty<'tcx>,
pick: &probe::Pick<'tcx>)
-> subst::Substs<'tcx>
-> &'tcx subst::Substs<'tcx>
{
match pick.kind {
probe::InherentImplPick => {
@ -231,7 +231,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
original_poly_trait_ref,
upcast_trait_ref,
trait_def_id);
upcast_trait_ref.substs.clone()
upcast_trait_ref.substs
})
}
@ -249,9 +249,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
let impl_trait_ref =
self.instantiate_type_scheme(
self.span,
&impl_polytype.substs,
impl_polytype.substs,
&self.tcx.impl_trait_ref(impl_def_id).unwrap());
impl_trait_ref.substs.clone()
impl_trait_ref.substs
}
probe::TraitPick => {
@ -271,7 +271,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
probe::WhereClausePick(ref poly_trait_ref) => {
// Where clauses can have bound regions in them. We need to instantiate
// those to convert from a poly-trait-ref to a trait-ref.
self.replace_late_bound_regions_with_fresh_var(&poly_trait_ref).substs.clone()
self.replace_late_bound_regions_with_fresh_var(&poly_trait_ref).substs
}
}
}
@ -303,8 +303,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
fn instantiate_method_substs(&mut self,
pick: &probe::Pick<'tcx>,
supplied_method_types: Vec<Ty<'tcx>>,
substs: subst::Substs<'tcx>)
mut supplied_method_types: Vec<Ty<'tcx>>,
substs: &subst::Substs<'tcx>)
-> subst::Substs<'tcx>
{
// Determine the values for the generic parameters of the method.
@ -312,50 +312,42 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// variables.
let num_supplied_types = supplied_method_types.len();
let method = pick.item.as_opt_method().unwrap();
let method_types = method.generics.types.get_slice(subst::FnSpace);
let num_method_types = method_types.len();
let num_method_types = method.generics.types.len(subst::FnSpace);
if num_supplied_types > 0 && num_supplied_types != num_method_types {
if num_method_types == 0 {
span_err!(self.tcx.sess, self.span, E0035,
"does not take type parameters");
} else {
span_err!(self.tcx.sess, self.span, E0036,
"incorrect number of type parameters given for this method: \
expected {}, found {}",
num_method_types, num_supplied_types);
}
supplied_method_types = vec![self.tcx.types.err; num_method_types];
}
// Create subst for early-bound lifetime parameters, combining
// parameters from the type and those from the method.
//
// FIXME -- permit users to manually specify lifetimes
let method_regions =
self.region_vars_for_defs(
self.span,
pick.item.as_opt_method().unwrap()
.generics.regions.get_slice(subst::FnSpace));
let subst::Substs { types, regions } = substs;
let regions = regions.with_slice(subst::FnSpace, &method_regions);
let mut final_substs = subst::Substs { types: types, regions: regions };
if num_supplied_types == 0 {
self.type_vars_for_defs(
self.span,
subst::FnSpace,
&mut final_substs,
method_types);
} else if num_method_types == 0 {
span_err!(self.tcx.sess, self.span, E0035,
"does not take type parameters");
self.type_vars_for_defs(
self.span,
subst::FnSpace,
&mut final_substs,
method_types);
} else if num_supplied_types != num_method_types {
span_err!(self.tcx.sess, self.span, E0036,
"incorrect number of type parameters given for this method: expected {}, found {}",
num_method_types, num_supplied_types);
final_substs.types.replace(
subst::FnSpace,
vec![self.tcx.types.err; num_method_types]);
} else {
final_substs.types.replace(subst::FnSpace, supplied_method_types);
}
return final_substs;
let type_defs = method.generics.types.as_full_slice();
let region_defs = method.generics.regions.as_full_slice();
subst::Substs::from_param_defs(region_defs, type_defs, |def| {
if def.space != subst::FnSpace {
substs.region_for_def(def)
} else {
self.region_var_for_def(self.span, def)
}
}, |def, cur_substs| {
if def.space != subst::FnSpace {
substs.type_for_def(def)
} else if supplied_method_types.is_empty() {
self.type_var_for_def(self.span, def, cur_substs)
} else {
supplied_method_types[def.index as usize]
}
})
}
fn unify_receivers(&mut self,

View File

@ -182,29 +182,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
let type_parameter_defs = trait_def.generics.types.get_slice(subst::TypeSpace);
let expected_number_of_input_types = type_parameter_defs.len();
if let Some(ref input_types) = opt_input_types {
assert_eq!(trait_def.generics.types.len(subst::TypeSpace), input_types.len());
}
assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0);
assert!(trait_def.generics.regions.is_empty());
// Construct a trait-reference `self_ty : Trait<input_tys>`
let mut substs = subst::Substs::new_trait(Vec::new(), Vec::new(), self_ty);
match opt_input_types {
Some(input_types) => {
assert_eq!(expected_number_of_input_types, input_types.len());
substs.types.replace(subst::ParamSpace::TypeSpace, input_types);
let type_defs = trait_def.generics.types.as_full_slice();
let region_defs = trait_def.generics.regions.as_full_slice();
let substs = subst::Substs::from_param_defs(region_defs, type_defs, |def| {
self.region_var_for_def(span, def)
}, |def, substs| {
if def.space == subst::SelfSpace {
self_ty
} else if let Some(ref input_types) = opt_input_types {
input_types[def.index as usize]
} else {
self.type_var_for_def(span, def, substs)
}
None => {
self.type_vars_for_defs(
span,
subst::ParamSpace::TypeSpace,
&mut substs,
type_parameter_defs);
}
}
});
let trait_ref = ty::TraitRef::new(trait_def_id, self.tcx.mk_substs(substs));

View File

@ -1227,28 +1227,29 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
return impl_ty;
}
let mut placeholder;
let placeholder;
let mut substs = substs;
if
!method.generics.types.is_empty_in(subst::FnSpace) ||
!method.generics.regions.is_empty_in(subst::FnSpace)
{
// In general, during probe we erase regions. See
// `impl_self_ty()` for an explanation.
let method_regions =
method.generics.regions.get_slice(subst::FnSpace)
.iter()
.map(|_| ty::ReErased)
.collect();
placeholder = (*substs).clone().with_method(Vec::new(), method_regions);
self.type_vars_for_defs(
self.span,
subst::FnSpace,
&mut placeholder,
method.generics.types.get_slice(subst::FnSpace));
let type_defs = method.generics.types.as_full_slice();
let region_defs = method.generics.regions.as_full_slice();
placeholder = subst::Substs::from_param_defs(region_defs, type_defs, |def| {
if def.space != subst::FnSpace {
substs.region_for_def(def)
} else {
// In general, during probe we erase regions. See
// `impl_self_ty()` for an explanation.
ty::ReErased
}
}, |def, cur_substs| {
if def.space != subst::FnSpace {
substs.type_for_def(def)
} else {
self.type_var_for_def(self.span, def, cur_substs)
}
});
substs = &placeholder;
}

View File

@ -1358,27 +1358,15 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
trait_def.associated_type_names.contains(&assoc_name)
}
fn ty_infer(&self,
ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
substs: Option<&mut subst::Substs<'tcx>>,
space: Option<subst::ParamSpace>,
span: Span) -> Ty<'tcx> {
// Grab the default doing subsitution
let default = ty_param_def.and_then(|def| {
def.default.map(|ty| type_variable::Default {
ty: ty.subst_spanned(self.tcx(), substs.as_ref().unwrap(), Some(span)),
origin_span: span,
def_id: def.default_def_id
})
});
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
self.next_ty_var()
}
let ty_var = self.next_ty_var_with_default(default);
// Finally we add the type variable to the substs
match substs {
None => ty_var,
Some(substs) => { substs.types.push(space.unwrap(), ty_var); ty_var }
}
fn ty_infer_for_def(&self,
ty_param_def: &ty::TypeParameterDef<'tcx>,
substs: &subst::Substs<'tcx>,
span: Span) -> Ty<'tcx> {
self.type_var_for_def(span, ty_param_def, substs)
}
fn projected_ty_from_poly_trait_ref(&self,
@ -2785,20 +2773,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
span: Span, // (potential) receiver for this impl
did: DefId)
-> TypeAndSubsts<'tcx> {
let tcx = self.tcx;
let ity = self.tcx.lookup_item_type(did);
debug!("impl_self_ty: ity={:?}", ity);
let ity = tcx.lookup_item_type(did);
let (tps, rps, raw_ty) =
(ity.generics.types.get_slice(subst::TypeSpace),
ity.generics.regions.get_slice(subst::TypeSpace),
ity.ty);
debug!("impl_self_ty: tps={:?} rps={:?} raw_ty={:?}", tps, rps, raw_ty);
let rps = self.region_vars_for_defs(span, rps);
let mut substs = subst::Substs::new_type(vec![], rps);
self.type_vars_for_defs(span, ParamSpace::TypeSpace, &mut substs, tps);
let substd_ty = self.instantiate_type_scheme(span, &substs, &raw_ty);
let substs = self.fresh_substs_for_generics(span, &ity.generics);
let substd_ty = self.instantiate_type_scheme(span, &substs, &ity.ty);
TypeAndSubsts { substs: substs, ty: substd_ty }
}
@ -4532,7 +4511,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// everything.
if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
substs.types.replace(space, Vec::new());
self.type_vars_for_defs(span, space, substs, &desired[..]);
for def in desired {
let ty_var = self.type_var_for_def(span, def, substs);
substs.types.push(def.space, ty_var);
}
return;
}

View File

@ -362,11 +362,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
None
}
fn ty_infer(&self,
_ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
_substs: Option<&mut Substs<'tcx>>,
_space: Option<ParamSpace>,
span: Span) -> Ty<'tcx> {
fn ty_infer(&self, span: Span) -> Ty<'tcx> {
struct_span_err!(
self.tcx().sess,
span,

View File

@ -132,7 +132,7 @@ pub mod coherence;
pub mod variance;
pub struct TypeAndSubsts<'tcx> {
pub substs: Substs<'tcx>,
pub substs: &'tcx Substs<'tcx>,
pub ty: Ty<'tcx>,
}

View File

@ -464,7 +464,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.declared_variance(p.def_id, def_id, TypeParam,
p.space, p.index as usize);
let variance_i = self.xform(variance, variance_decl);
let substs_ty = *substs.types.get(p.space, p.index as usize);
let substs_ty = substs.type_for_def(p);
debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
variance_decl, variance_i);
self.add_constraints_from_ty(generics, substs_ty, variance_i);
@ -475,7 +475,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.declared_variance(p.def_id, def_id,
RegionParam, p.space, p.index as usize);
let variance_i = self.xform(variance, variance_decl);
let substs_r = *substs.regions.get(p.space, p.index as usize);
let substs_r = substs.region_for_def(p);
self.add_constraints_from_region(generics, substs_r, variance_i);
}
}