rustc: store type parameter defaults outside of ty::Generics.

This commit is contained in:
Eduard-Mihai Burtescu 2017-01-25 22:01:11 +02:00
parent 1572bf104d
commit e8d01ea4c7
34 changed files with 394 additions and 385 deletions

View file

@ -42,7 +42,7 @@ use std::cell::RefCell;
use std::iter;
use syntax::{abi, ast};
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax::symbol::{Symbol, keywords};
use syntax::symbol::Symbol;
use syntax_pos::Span;
pub trait AstConv<'gcx, 'tcx> {
@ -53,7 +53,7 @@ pub trait AstConv<'gcx, 'tcx> {
/// Returns the generic type and lifetime parameters for an item.
fn get_generics(&self, span: Span, id: DefId)
-> Result<&'tcx ty::Generics<'tcx>, ErrorReported>;
-> Result<&'tcx ty::Generics, ErrorReported>;
/// Identify the type for an item, like a type alias, fn, or struct.
fn get_item_type(&self, span: Span, id: DefId) -> Result<Ty<'tcx>, ErrorReported>;
@ -89,7 +89,7 @@ pub trait AstConv<'gcx, 'tcx> {
/// Same as ty_infer, but with a known type parameter definition.
fn ty_infer_for_def(&self,
_def: &ty::TypeParameterDef<'tcx>,
_def: &ty::TypeParameterDef,
_substs: &[Kind<'tcx>],
span: Span) -> Ty<'tcx> {
self.ty_infer(span)
@ -277,9 +277,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
}
let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
let default_needs_object_self = |p: &ty::TypeParameterDef<'tcx>| {
if let Some(ref default) = p.default {
if is_object && default.has_self_ty() {
let default_needs_object_self = |p: &ty::TypeParameterDef| {
if is_object && p.has_default {
let default = self.get_item_type(span, p.def_id).ok();
if default.has_self_ty() {
// There is no suitable inference default for a type parameter
// that references self, in an object type.
return true;
@ -327,7 +328,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
self.ty_infer(span)
};
ty_var
} else if let Some(default) = def.default {
} else if def.has_default {
// No type parameter provided, but a default exists.
// If we are converting an object type, then the
@ -346,7 +347,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
tcx.types.err
} else {
// This is a default type parameter.
default.subst_spanned(tcx, substs, Some(span))
match self.get_item_type(span, def.def_id) {
Ok(ty) => ty.subst_spanned(tcx, substs, Some(span)),
Err(ErrorReported) => tcx.types.err
}
}
} else {
// We've already errored above about the mismatch.
@ -954,19 +958,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
Err(ErrorReported) => return (tcx.types.err, Def::Err),
}
}
(&ty::TyParam(_), Def::SelfTy(Some(trait_did), None)) => {
let trait_node_id = tcx.hir.as_local_node_id(trait_did).unwrap();
match self.find_bound_for_assoc_item(trait_node_id,
keywords::SelfType.name(),
assoc_name,
span) {
Ok(bound) => bound,
Err(ErrorReported) => return (tcx.types.err, Def::Err),
}
}
(&ty::TyParam(_), Def::SelfTy(Some(param_did), None)) |
(&ty::TyParam(_), Def::TyParam(param_did)) => {
let param_node_id = tcx.hir.as_local_node_id(param_did).unwrap();
let param_name = tcx.type_parameter_def(param_node_id).name;
let param_name = ::ty_param_name(tcx, param_node_id);
match self.find_bound_for_assoc_item(param_node_id,
param_name,
assoc_name,
@ -1063,21 +1058,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
tcx.prohibit_type_params(&path.segments);
let node_id = tcx.hir.as_local_node_id(did).unwrap();
let param = tcx.ty_param_defs.borrow().get(&node_id)
.map(ty::ParamTy::for_def);
if let Some(p) = param {
p.to_ty(tcx)
} else {
// Only while computing defaults of earlier type
// parameters can a type parameter be missing its def.
struct_span_err!(tcx.sess, span, E0128,
"type parameters with a default cannot use \
forward declared identifiers")
.span_label(span, &format!("defaulted type parameters \
cannot be forward declared"))
.emit();
tcx.types.err
}
let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id));
let index = match self.get_generics(span, item_def_id) {
Ok(generics) => {
generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index]
}
Err(ErrorReported) => return tcx.types.err
};
tcx.mk_param(index, ::ty_param_name(tcx, node_id))
}
Def::SelfTy(_, Some(def_id)) => {
// Self in impl (we know the concrete type).
@ -1510,7 +1498,7 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
ty_param_defs: &[ty::TypeParameterDef]) {
let accepted = ty_param_defs.len();
let required = ty_param_defs.iter().take_while(|x| x.default.is_none()) .count();
let required = ty_param_defs.iter().take_while(|x| !x.has_default).count();
if supplied < required {
let expected = if required < accepted {
"expected at least"

View file

@ -386,8 +386,8 @@ fn compare_predicate_entailment<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn check_region_bounds_on_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
span: Span,
impl_m: &ty::AssociatedItem,
trait_generics: &ty::Generics<'tcx>,
impl_generics: &ty::Generics<'tcx>,
trait_generics: &ty::Generics,
impl_generics: &ty::Generics,
trait_to_skol_substs: &Substs<'tcx>,
impl_to_skol_substs: &Substs<'tcx>)
-> Result<(), ErrorReported> {

View file

@ -1360,7 +1360,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
}
fn get_generics(&self, _: Span, id: DefId)
-> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
-> Result<&'tcx ty::Generics, ErrorReported>
{
Ok(self.tcx().item_generics(id))
}
@ -1390,14 +1390,17 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
node_id: ast::NodeId)
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
{
let def = self.tcx.type_parameter_def(node_id);
let tcx = self.tcx;
let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id));
let generics = tcx.item_generics(item_def_id);
let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index];
let r = self.parameter_environment
.caller_bounds
.iter()
.filter_map(|predicate| {
match *predicate {
ty::Predicate::Trait(ref data) => {
if data.0.self_ty().is_param(def.index) {
if data.0.self_ty().is_param(index) {
Some(data.to_poly_trait_ref())
} else {
None
@ -1426,7 +1429,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
}
fn ty_infer_for_def(&self,
ty_param_def: &ty::TypeParameterDef<'tcx>,
ty_param_def: &ty::TypeParameterDef,
substs: &[Kind<'tcx>],
span: Span) -> Ty<'tcx> {
self.type_var_for_def(span, ty_param_def, substs)
@ -4423,8 +4426,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let Some(ast_ty) = types.get(i) {
// A provided type parameter.
self.to_ty(ast_ty)
} else if let (false, Some(default)) = (infer_types, def.default) {
} else if !infer_types && def.has_default {
// No type parameter provided, but a default exists.
let default = self.tcx.item_type(def.def_id);
default.subst_spanned(self.tcx, substs, Some(span))
} else {
// No type parameters were provided, we can infer all.
@ -4537,9 +4541,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
&generics.types
}
});
let required_len = type_defs.iter()
.take_while(|d| d.default.is_none())
.count();
let required_len = type_defs.iter().take_while(|d| !d.has_default).count();
if types.len() > type_defs.len() {
let span = types[type_defs.len()].span;
let expected_text = count_type_params(type_defs.len());

View file

@ -62,6 +62,7 @@ use lint;
use constrained_type_params as ctp;
use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
use middle::resolve_lifetime as rl;
use rustc_const_eval::EvalHint::UncheckedExprHint;
use rustc_const_eval::{ConstContext, report_const_eval_err};
use rustc::ty::subst::Substs;
@ -76,6 +77,7 @@ use CrateCtxt;
use rustc_const_math::ConstInt;
use std::cell::RefCell;
use std::collections::BTreeMap;
use syntax::{abi, ast, attr};
use syntax::symbol::{Symbol, keywords};
@ -186,6 +188,16 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
intravisit::walk_item(self, item);
}
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
for param in &generics.ty_params {
if param.default.is_some() {
let def_id = self.ccx.tcx.hir.local_def_id(param.id);
type_of_def_id(self.ccx, def_id);
}
}
intravisit::walk_generics(self, generics);
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
if let hir::ExprClosure(..) = expr.node {
let def_id = self.ccx.tcx.hir.local_def_id(expr.id);
@ -277,11 +289,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
tcx.item_path_str(def_id)));
}
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
err.note(
&format!("the cycle begins when computing the bounds \
for type parameter `{}`...",
def.name));
::ty_param_name(tcx, id)));
}
}
@ -300,11 +311,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
tcx.item_path_str(def_id)));
}
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
err.note(
&format!("...which then requires computing the bounds \
for type parameter `{}`...",
def.name));
::ty_param_name(tcx, id)));
}
}
}
@ -324,11 +334,10 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
tcx.item_path_str(def_id)));
}
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
err.note(
&format!("...which then again requires computing the bounds \
for type parameter `{}`, completing the cycle.",
def.name));
::ty_param_name(tcx, id)));
}
}
err.emit();
@ -385,7 +394,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
}
fn get_generics(&self, span: Span, id: DefId)
-> Result<&'tcx ty::Generics<'tcx>, ErrorReported>
-> Result<&'tcx ty::Generics, ErrorReported>
{
self.ccx.cycle_check(span, AstConvRequest::GetGenerics(id), || {
Ok(generics_of_def_id(self.ccx, id))
@ -531,20 +540,23 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
node_id: ast::NodeId)
-> Vec<ty::Predicate<'tcx>>
{
let def = astconv.tcx().type_parameter_def(node_id);
let tcx = astconv.tcx();
let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id));
let generics = tcx.item_generics(item_def_id);
let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index];
let mut results = self.parent.map_or(vec![], |def_id| {
let parent = astconv.tcx().item_predicates(def_id);
let parent = tcx.item_predicates(def_id);
parent.get_type_parameter_bounds(astconv, span, node_id)
});
results.extend(self.predicates.iter().filter(|predicate| {
match **predicate {
ty::Predicate::Trait(ref data) => {
data.skip_binder().self_ty().is_param(def.index)
data.skip_binder().self_ty().is_param(index)
}
ty::Predicate::TypeOutlives(ref data) => {
data.skip_binder().0.is_param(def.index)
data.skip_binder().0.is_param(index)
}
ty::Predicate::Equate(..) |
ty::Predicate::RegionOutlives(..) |
@ -568,7 +580,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
fn get_type_parameter_bounds(&self,
astconv: &AstConv<'tcx, 'tcx>,
_: Span,
span: Span,
node_id: ast::NodeId)
-> Vec<ty::Predicate<'tcx>>
{
@ -576,8 +588,15 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
// written inline like `<T:Foo>` or in a where clause like
// `where T:Foo`.
let def = astconv.tcx().type_parameter_def(node_id);
let ty = astconv.tcx().mk_param_from_def(&def);
let tcx = astconv.tcx();
let item_def_id = tcx.hir.local_def_id(::ty_param_owner(tcx, node_id));
let index = match astconv.get_generics(span, item_def_id) {
Ok(generics) => {
generics.type_param_to_index[&tcx.hir.local_def_id(node_id).index]
}
Err(ErrorReported) => return vec![]
};
let ty = tcx.mk_param(index, ::ty_param_name(tcx, node_id));
let from_ty_params =
self.ty_params
@ -594,7 +613,7 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for hir::Generics {
hir::WherePredicate::BoundPredicate(ref bp) => Some(bp),
_ => None
})
.filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
.filter(|bp| is_param(tcx, &bp.bounded_ty, node_id))
.flat_map(|bp| bp.bounds.iter())
.flat_map(|b| predicates_from_bound(astconv, ty, b));
@ -625,7 +644,7 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
struct_generics: &'tcx ty::Generics<'tcx>,
struct_generics: &'tcx ty::Generics,
struct_predicates: &ty::GenericPredicates<'tcx>,
field: &hir::StructField,
ty_f: &'tcx ty::FieldDef)
@ -938,7 +957,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
fn convert_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
def: &'tcx ty::AdtDef,
ty: Ty<'tcx>,
generics: &'tcx ty::Generics<'tcx>,
generics: &'tcx ty::Generics,
predicates: ty::GenericPredicates<'tcx>,
variants: &[hir::Variant]) {
// fill the field types
@ -1325,7 +1344,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
def_id: DefId)
-> &'tcx ty::Generics<'tcx> {
-> &'tcx ty::Generics {
let tcx = ccx.tcx;
let node_id = if let Some(id) = tcx.hir.as_local_node_id(def_id) {
id
@ -1402,18 +1421,14 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// the node id for the Self type parameter.
let param_id = item.id;
let parent = ccx.tcx.hir.get_parent(param_id);
let def = ty::TypeParameterDef {
opt_self = Some(ty::TypeParameterDef {
index: 0,
name: keywords::SelfType.name(),
def_id: tcx.hir.local_def_id(param_id),
default_def_id: tcx.hir.local_def_id(parent),
default: None,
has_default: false,
object_lifetime_default: rl::Set1::Empty,
pure_wrt_drop: false,
};
tcx.ty_param_defs.borrow_mut().insert(param_id, def.clone());
opt_self = Some(def);
});
allow_defaults = true;
generics
@ -1459,11 +1474,36 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
}).collect::<Vec<_>>();
let object_lifetime_defaults =
tcx.named_region_map.object_lifetime_defaults.get(&node_id);
// Now create the real type parameters.
let type_start = own_start + regions.len() as u32;
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
let i = type_start + i as u32;
get_or_create_type_parameter_def(ccx, i, p, allow_defaults)
if p.name == keywords::SelfType.name() {
span_bug!(p.span, "`Self` should not be the name of a regular parameter");
}
if !allow_defaults && p.default.is_some() {
if !tcx.sess.features.borrow().default_type_parameter_fallback {
tcx.sess.add_lint(
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
p.id,
p.span,
format!("defaults for type parameters are only allowed in `struct`, \
`enum`, `type`, or `trait` definitions."));
}
}
ty::TypeParameterDef {
index: type_start + i as u32,
name: p.name,
def_id: tcx.hir.local_def_id(p.id),
has_default: p.default.is_some(),
object_lifetime_default:
object_lifetime_defaults.map_or(rl::Set1::Empty, |o| o[i]),
pure_wrt_drop: p.pure_wrt_drop,
}
});
let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
@ -1476,19 +1516,25 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
index: type_start + i as u32,
name: Symbol::intern("<upvar>"),
def_id: def_id,
default_def_id: parent_def_id.unwrap(),
default: None,
has_default: false,
object_lifetime_default: rl::Set1::Empty,
pure_wrt_drop: false,
}));
});
}
let mut type_param_to_index = BTreeMap::new();
for param in &types {
type_param_to_index.insert(param.def_id.index, param.index);
}
tcx.alloc_generics(ty::Generics {
parent: parent_def_id,
parent_regions: parent_regions,
parent_types: parent_types,
regions: regions,
types: types,
type_param_to_index: type_param_to_index,
has_self: has_self || parent_has_self
})
})
@ -1576,6 +1622,9 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|def, _| ccx.tcx.mk_param_from_def(def)
))
}
NodeTyParam(&hir::TyParam { default: Some(ref ty), .. }) => {
ccx.icx(&()).to_ty(ty)
}
x => {
bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
}
@ -1808,54 +1857,6 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
}
}
fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
index: u32,
param: &hir::TyParam,
allow_defaults: bool)
-> ty::TypeParameterDef<'tcx>
{
let tcx = ccx.tcx;
match tcx.ty_param_defs.borrow().get(&param.id) {
Some(d) => { return d.clone(); }
None => { }
}
let default =
param.default.as_ref().map(|def| ccx.icx(&()).to_ty(def));
let parent = tcx.hir.get_parent(param.id);
if !allow_defaults && default.is_some() {
if !tcx.sess.features.borrow().default_type_parameter_fallback {
tcx.sess.add_lint(
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
param.id,
param.span,
format!("defaults for type parameters are only allowed in `struct`, \
`enum`, `type`, or `trait` definitions."));
}
}
let def = ty::TypeParameterDef {
index: index,
name: param.name,
def_id: ccx.tcx.hir.local_def_id(param.id),
default_def_id: ccx.tcx.hir.local_def_id(parent),
default: default,
pure_wrt_drop: param.pure_wrt_drop,
};
if def.name == keywords::SelfType.name() {
span_bug!(param.span, "`Self` should not be the name of a regular parameter");
}
tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
debug!("get_or_create_type_parameter_def: def for type param: {:?}", def);
def
}
pub enum SizedByDefault { Yes, No, }
/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or

View file

@ -1701,33 +1701,6 @@ struct Foo {
```
"##,
E0128: r##"
Type parameter defaults can only use parameters that occur before them.
Erroneous code example:
```compile_fail,E0128
struct Foo<T=U, U=()> {
field1: T,
filed2: U,
}
// error: type parameters with a default cannot use forward declared
// identifiers
```
Since type parameters are evaluated in-order, you may be able to fix this issue
by doing:
```
struct Foo<U=(), T=U> {
field1: T,
filed2: U,
}
```
Please also verify that this wasn't because of a name-clash and rename the type
parameter if so.
"##,
E0131: r##"
It is not possible to define `main` with type parameters, or even with function
parameters. When `main` is present, it must take no arguments and return `()`.

View file

@ -116,6 +116,7 @@ use util::common::time;
use syntax::ast;
use syntax::abi::Abi;
use syntax::symbol::keywords;
use syntax_pos::Span;
use std::iter;
@ -193,6 +194,30 @@ fn require_same_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
})
}
fn ty_param_owner(tcx: TyCtxt, id: ast::NodeId) -> ast::NodeId {
match tcx.hir.get(id) {
hir::map::NodeItem(&hir::Item { node: hir::ItemTrait(..), .. }) => id,
hir::map::NodeTyParam(_) => tcx.hir.get_parent_node(id),
_ => {
bug!("ty_param_owner: {} not a type parameter",
tcx.hir.node_to_string(id))
}
}
}
fn ty_param_name(tcx: TyCtxt, id: ast::NodeId) -> ast::Name {
match tcx.hir.get(id) {
hir::map::NodeItem(&hir::Item { node: hir::ItemTrait(..), .. }) => {
keywords::SelfType.name()
}
hir::map::NodeTyParam(tp) => tp.name,
_ => {
bug!("ty_param_name: {} not a type parameter",
tcx.hir.node_to_string(id))
}
}
}
fn check_main_fn_ty(ccx: &CrateCtxt,
main_id: ast::NodeId,
main_span: Span) {

View file

@ -279,7 +279,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
fn add_constraints_from_trait_ref(&mut self,
generics: &ty::Generics<'tcx>,
generics: &ty::Generics,
trait_ref: ty::TraitRef<'tcx>,
variance: VarianceTermPtr<'a>) {
debug!("add_constraints_from_trait_ref: trait_ref={:?} variance={:?}",
@ -305,7 +305,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// in a context with the generics defined in `generics` and
/// ambient variance `variance`
fn add_constraints_from_ty(&mut self,
generics: &ty::Generics<'tcx>,
generics: &ty::Generics,
ty: Ty<'tcx>,
variance: VarianceTermPtr<'a>) {
debug!("add_constraints_from_ty(ty={:?}, variance={:?})",
@ -433,9 +433,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// Adds constraints appropriate for a nominal type (enum, struct,
/// object, etc) appearing in a context with ambient variance `variance`
fn add_constraints_from_substs(&mut self,
generics: &ty::Generics<'tcx>,
generics: &ty::Generics,
def_id: DefId,
type_param_defs: &[ty::TypeParameterDef<'tcx>],
type_param_defs: &[ty::TypeParameterDef],
region_param_defs: &[ty::RegionParameterDef],
substs: &Substs<'tcx>,
variance: VarianceTermPtr<'a>) {
@ -465,7 +465,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// Adds constraints appropriate for a function with signature
/// `sig` appearing in a context with ambient variance `variance`
fn add_constraints_from_sig(&mut self,
generics: &ty::Generics<'tcx>,
generics: &ty::Generics,
sig: &ty::PolyFnSig<'tcx>,
variance: VarianceTermPtr<'a>) {
let contra = self.contravariant(variance);
@ -478,7 +478,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// Adds constraints appropriate for a region appearing in a
/// context with ambient variance `variance`
fn add_constraints_from_region(&mut self,
generics: &ty::Generics<'tcx>,
generics: &ty::Generics,
region: &'tcx ty::Region,
variance: VarianceTermPtr<'a>) {
match *region {
@ -518,7 +518,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
/// Adds constraints appropriate for a mutability-type pair
/// appearing in a context with ambient variance `variance`
fn add_constraints_from_mt(&mut self,
generics: &ty::Generics<'tcx>,
generics: &ty::Generics,
mt: &ty::TypeAndMut<'tcx>,
variance: VarianceTermPtr<'a>) {
match mt.mutbl {