Remove the AssocSpace

This commit is contained in:
Niko Matsakis 2014-12-29 16:32:12 -05:00
parent 42e645ca9a
commit de8e0ae22c
14 changed files with 41 additions and 96 deletions

View file

@ -707,9 +707,8 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
{ {
let types = self.read_to_vec(|this| Ok(f(this))).unwrap(); let types = self.read_to_vec(|this| Ok(f(this))).unwrap();
let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap(); let selfs = self.read_to_vec(|this| Ok(f(this))).unwrap();
let assocs = self.read_to_vec(|this| Ok(f(this))).unwrap();
let fns = self.read_to_vec(|this| Ok(f(this))).unwrap(); let fns = self.read_to_vec(|this| Ok(f(this))).unwrap();
VecPerParamSpace::new(types, selfs, assocs, fns) VecPerParamSpace::new(types, selfs, fns)
} }
fn read_vtable_res_with_key(&mut self, fn read_vtable_res_with_key(&mut self,

View file

@ -864,10 +864,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let region_param_defs = generics.regions.get_slice(subst::TypeSpace); let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
let regions = self.region_vars_for_defs(span, region_param_defs); let regions = self.region_vars_for_defs(span, region_param_defs);
let assoc_type_parameter_count = generics.types.len(subst::AssocSpace); subst::Substs::new_trait(type_parameters, regions, self_ty)
let assoc_type_parameters = self.next_ty_vars(assoc_type_parameter_count);
subst::Substs::new_trait(type_parameters, regions, assoc_type_parameters, self_ty)
} }
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region { pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex) -> ty::Region {

View file

@ -55,18 +55,17 @@ impl<'tcx> Substs<'tcx> {
r: Vec<ty::Region>) r: Vec<ty::Region>)
-> Substs<'tcx> -> Substs<'tcx>
{ {
Substs::new(VecPerParamSpace::new(t, Vec::new(), Vec::new(), Vec::new()), Substs::new(VecPerParamSpace::new(t, Vec::new(), Vec::new()),
VecPerParamSpace::new(r, Vec::new(), Vec::new(), Vec::new())) VecPerParamSpace::new(r, Vec::new(), Vec::new()))
} }
pub fn new_trait(t: Vec<Ty<'tcx>>, pub fn new_trait(t: Vec<Ty<'tcx>>,
r: Vec<ty::Region>, r: Vec<ty::Region>,
a: Vec<Ty<'tcx>>,
s: Ty<'tcx>) s: Ty<'tcx>)
-> Substs<'tcx> -> Substs<'tcx>
{ {
Substs::new(VecPerParamSpace::new(t, vec!(s), a, Vec::new()), Substs::new(VecPerParamSpace::new(t, vec!(s), Vec::new()),
VecPerParamSpace::new(r, Vec::new(), Vec::new(), Vec::new())) VecPerParamSpace::new(r, Vec::new(), Vec::new()))
} }
pub fn erased(t: VecPerParamSpace<Ty<'tcx>>) -> Substs<'tcx> pub fn erased(t: VecPerParamSpace<Ty<'tcx>>) -> Substs<'tcx>
@ -123,13 +122,6 @@ impl<'tcx> Substs<'tcx> {
s s
} }
pub fn with_assoc_tys(&self, assoc_tys: Vec<Ty<'tcx>>) -> Substs<'tcx> {
assert!(self.types.is_empty_in(AssocSpace));
let mut s = (*self).clone();
s.types.replace(AssocSpace, assoc_tys);
s
}
pub fn erase_regions(self) -> Substs<'tcx> { pub fn erase_regions(self) -> Substs<'tcx> {
let Substs { types, regions: _ } = self; let Substs { types, regions: _ } = self;
Substs { types: types, regions: ErasedRegions } Substs { types: types, regions: ErasedRegions }
@ -192,21 +184,19 @@ impl RegionSubsts {
pub enum ParamSpace { pub enum ParamSpace {
TypeSpace, // Type parameters attached to a type definition, trait, or impl TypeSpace, // Type parameters attached to a type definition, trait, or impl
SelfSpace, // Self parameter on a trait SelfSpace, // Self parameter on a trait
AssocSpace, // Assoc types defined in a trait/impl
FnSpace, // Type parameters attached to a method or fn FnSpace, // Type parameters attached to a method or fn
} }
impl ParamSpace { impl ParamSpace {
pub fn all() -> [ParamSpace, ..4] { pub fn all() -> [ParamSpace, ..3] {
[TypeSpace, SelfSpace, AssocSpace, FnSpace] [TypeSpace, SelfSpace, FnSpace]
} }
pub fn to_uint(self) -> uint { pub fn to_uint(self) -> uint {
match self { match self {
TypeSpace => 0, TypeSpace => 0,
SelfSpace => 1, SelfSpace => 1,
AssocSpace => 2, FnSpace => 2,
FnSpace => 3,
} }
} }
@ -214,8 +204,7 @@ impl ParamSpace {
match u { match u {
0 => TypeSpace, 0 => TypeSpace,
1 => SelfSpace, 1 => SelfSpace,
2 => AssocSpace, 2 => FnSpace,
3 => FnSpace,
_ => panic!("Invalid ParamSpace: {}", u) _ => panic!("Invalid ParamSpace: {}", u)
} }
} }
@ -235,11 +224,9 @@ pub struct VecPerParamSpace<T> {
// //
// AF(self) = (self.content[..self.type_limit], // AF(self) = (self.content[..self.type_limit],
// self.content[self.type_limit..self.self_limit], // self.content[self.type_limit..self.self_limit],
// self.content[self.self_limit..self.assoc_limit], // self.content[self.self_limit..])
// self.content[self.assoc_limit..])
type_limit: uint, type_limit: uint,
self_limit: uint, self_limit: uint,
assoc_limit: uint,
content: Vec<T>, content: Vec<T>,
} }
@ -248,7 +235,6 @@ pub struct VecPerParamSpace<T> {
pub struct SeparateVecsPerParamSpace<T> { pub struct SeparateVecsPerParamSpace<T> {
pub types: Vec<T>, pub types: Vec<T>,
pub selfs: Vec<T>, pub selfs: Vec<T>,
pub assocs: Vec<T>,
pub fns: Vec<T>, pub fns: Vec<T>,
} }
@ -268,8 +254,7 @@ impl<T> VecPerParamSpace<T> {
match space { match space {
TypeSpace => (0, self.type_limit), TypeSpace => (0, self.type_limit),
SelfSpace => (self.type_limit, self.self_limit), SelfSpace => (self.type_limit, self.self_limit),
AssocSpace => (self.self_limit, self.assoc_limit), FnSpace => (self.self_limit, self.content.len()),
FnSpace => (self.assoc_limit, self.content.len()),
} }
} }
@ -277,7 +262,6 @@ impl<T> VecPerParamSpace<T> {
VecPerParamSpace { VecPerParamSpace {
type_limit: 0, type_limit: 0,
self_limit: 0, self_limit: 0,
assoc_limit: 0,
content: Vec::new() content: Vec::new()
} }
} }
@ -290,31 +274,27 @@ impl<T> VecPerParamSpace<T> {
/// `s` is the self space. /// `s` is the self space.
/// `a` is the assoc space. /// `a` is the assoc space.
/// `f` is the fn space. /// `f` is the fn space.
pub fn new(t: Vec<T>, s: Vec<T>, a: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> { pub fn new(t: Vec<T>, s: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
let type_limit = t.len(); let type_limit = t.len();
let self_limit = type_limit + s.len(); let self_limit = type_limit + s.len();
let assoc_limit = self_limit + a.len();
let mut content = t; let mut content = t;
content.extend(s.into_iter()); content.extend(s.into_iter());
content.extend(a.into_iter());
content.extend(f.into_iter()); content.extend(f.into_iter());
VecPerParamSpace { VecPerParamSpace {
type_limit: type_limit, type_limit: type_limit,
self_limit: self_limit, self_limit: self_limit,
assoc_limit: assoc_limit,
content: content, content: content,
} }
} }
fn new_internal(content: Vec<T>, type_limit: uint, self_limit: uint, assoc_limit: uint) fn new_internal(content: Vec<T>, type_limit: uint, self_limit: uint)
-> VecPerParamSpace<T> -> VecPerParamSpace<T>
{ {
VecPerParamSpace { VecPerParamSpace {
type_limit: type_limit, type_limit: type_limit,
self_limit: self_limit, self_limit: self_limit,
assoc_limit: assoc_limit,
content: content, content: content,
} }
} }
@ -326,9 +306,8 @@ impl<T> VecPerParamSpace<T> {
pub fn push(&mut self, space: ParamSpace, value: T) { pub fn push(&mut self, space: ParamSpace, value: T) {
let (_, limit) = self.limits(space); let (_, limit) = self.limits(space);
match space { match space {
TypeSpace => { self.type_limit += 1; self.self_limit += 1; self.assoc_limit += 1; } TypeSpace => { self.type_limit += 1; self.self_limit += 1; }
SelfSpace => { self.self_limit += 1; self.assoc_limit += 1; } SelfSpace => { self.self_limit += 1; }
AssocSpace => { self.assoc_limit += 1; }
FnSpace => { } FnSpace => { }
} }
self.content.insert(limit, value); self.content.insert(limit, value);
@ -340,9 +319,8 @@ impl<T> VecPerParamSpace<T> {
None None
} else { } else {
match space { match space {
TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; self.assoc_limit -= 1; } TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; }
SelfSpace => { self.self_limit -= 1; self.assoc_limit -= 1; } SelfSpace => { self.self_limit -= 1; }
AssocSpace => { self.assoc_limit -= 1; }
FnSpace => {} FnSpace => {}
} }
self.content.remove(limit - 1) self.content.remove(limit - 1)
@ -439,8 +417,7 @@ impl<T> VecPerParamSpace<T> {
let result = self.iter().map(pred).collect(); let result = self.iter().map(pred).collect();
VecPerParamSpace::new_internal(result, VecPerParamSpace::new_internal(result,
self.type_limit, self.type_limit,
self.self_limit, self.self_limit)
self.assoc_limit)
} }
pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
@ -449,8 +426,7 @@ impl<T> VecPerParamSpace<T> {
let result = self.iter_enumerated().map(pred).collect(); let result = self.iter_enumerated().map(pred).collect();
VecPerParamSpace::new_internal(result, VecPerParamSpace::new_internal(result,
self.type_limit, self.type_limit,
self.self_limit, self.self_limit)
self.assoc_limit)
} }
pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> where pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U> where
@ -459,25 +435,22 @@ impl<T> VecPerParamSpace<T> {
let SeparateVecsPerParamSpace { let SeparateVecsPerParamSpace {
types: t, types: t,
selfs: s, selfs: s,
assocs: a,
fns: f fns: f
} = self.split(); } = self.split();
VecPerParamSpace::new(t.into_iter().map(|p| pred(p)).collect(), VecPerParamSpace::new(t.into_iter().map(|p| pred(p)).collect(),
s.into_iter().map(|p| pred(p)).collect(), s.into_iter().map(|p| pred(p)).collect(),
a.into_iter().map(|p| pred(p)).collect(),
f.into_iter().map(|p| pred(p)).collect()) f.into_iter().map(|p| pred(p)).collect())
} }
pub fn split(self) -> SeparateVecsPerParamSpace<T> { pub fn split(self) -> SeparateVecsPerParamSpace<T> {
let VecPerParamSpace { type_limit, self_limit, assoc_limit, content } = self; let VecPerParamSpace { type_limit, self_limit, content } = self;
let mut content_iter = content.into_iter(); let mut content_iter = content.into_iter();
SeparateVecsPerParamSpace { SeparateVecsPerParamSpace {
types: content_iter.by_ref().take(type_limit).collect(), types: content_iter.by_ref().take(type_limit).collect(),
selfs: content_iter.by_ref().take(self_limit - type_limit).collect(), selfs: content_iter.by_ref().take(self_limit - type_limit).collect(),
assocs: content_iter.by_ref().take(assoc_limit - self_limit).collect(),
fns: content_iter.collect() fns: content_iter.collect()
} }
} }

View file

@ -1674,8 +1674,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}); });
} }
let obligations = VecPerParamSpace::new(obligations, Vec::new(), let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
Vec::new(), Vec::new());
debug!("vtable_builtin_data: obligations={}", debug!("vtable_builtin_data: obligations={}",
obligations.repr(self.tcx())); obligations.repr(self.tcx()));
@ -1769,7 +1768,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Substs::new_trait( Substs::new_trait(
vec![arguments_tuple, output_type], vec![arguments_tuple, output_type],
vec![], vec![],
vec![],
self_ty); self_ty);
let trait_ref = ty::Binder(Rc::new(ty::TraitRef { let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
def_id: obligation.predicate.def_id(), def_id: obligation.predicate.def_id(),
@ -1810,7 +1808,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
vec![arguments_tuple.subst(self.tcx(), substs), vec![arguments_tuple.subst(self.tcx(), substs),
closure_sig.0.output.unwrap().subst(self.tcx(), substs)], closure_sig.0.output.unwrap().subst(self.tcx(), substs)],
vec![], vec![],
vec![],
obligation.self_ty()); obligation.self_ty());
let trait_ref = ty::Binder(Rc::new(ty::TraitRef { let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
def_id: obligation.predicate.def_id(), def_id: obligation.predicate.def_id(),

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::subst::{Subst, Substs, VecPerParamSpace}; use middle::subst::{Substs, VecPerParamSpace};
use middle::infer::InferCtxt; use middle::infer::InferCtxt;
use middle::ty::{mod, Ty, AsPredicate, ToPolyTraitRef}; use middle::ty::{mod, Ty, AsPredicate, ToPolyTraitRef};
use std::collections::HashSet; use std::collections::HashSet;
@ -229,18 +229,7 @@ pub fn fresh_substs_for_impl<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
{ {
let tcx = infcx.tcx; let tcx = infcx.tcx;
let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics; let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics;
let input_substs = infcx.fresh_substs_for_generics(span, &impl_generics); infcx.fresh_substs_for_generics(span, &impl_generics)
// Add substs for the associated types bound in the impl.
let ref items = tcx.impl_items.borrow()[impl_def_id];
let mut assoc_tys = Vec::new();
for item in items.iter() {
if let &ty::ImplOrTraitItemId::TypeTraitItemId(id) = item {
assoc_tys.push(tcx.tcache.borrow()[id].ty.subst(tcx, &input_substs));
}
}
input_substs.with_assoc_tys(assoc_tys)
} }
impl<'tcx, N> fmt::Show for VtableImplData<'tcx, N> { impl<'tcx, N> fmt::Show for VtableImplData<'tcx, N> {

View file

@ -701,10 +701,9 @@ impl<'tcx> Repr<'tcx> for subst::Substs<'tcx> {
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for subst::VecPerParamSpace<T> { impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for subst::VecPerParamSpace<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { fn repr(&self, tcx: &ctxt<'tcx>) -> String {
format!("[{};{};{};{}]", format!("[{};{};{}]",
self.get_slice(subst::TypeSpace).repr(tcx), self.get_slice(subst::TypeSpace).repr(tcx),
self.get_slice(subst::SelfSpace).repr(tcx), self.get_slice(subst::SelfSpace).repr(tcx),
self.get_slice(subst::AssocSpace).repr(tcx),
self.get_slice(subst::FnSpace).repr(tcx)) self.get_slice(subst::FnSpace).repr(tcx))
} }
} }

View file

@ -209,7 +209,6 @@ pub fn trans_static_method_callee(bcx: Block,
let subst::SeparateVecsPerParamSpace { let subst::SeparateVecsPerParamSpace {
types: rcvr_type, types: rcvr_type,
selfs: rcvr_self, selfs: rcvr_self,
assocs: rcvr_assoc,
fns: rcvr_method fns: rcvr_method
} = rcvr_substs.types.split(); } = rcvr_substs.types.split();
@ -238,7 +237,6 @@ pub fn trans_static_method_callee(bcx: Block,
let trait_substs = let trait_substs =
Substs::erased(VecPerParamSpace::new(rcvr_type, Substs::erased(VecPerParamSpace::new(rcvr_type,
rcvr_self, rcvr_self,
rcvr_assoc,
Vec::new())); Vec::new()));
let trait_substs = bcx.tcx().mk_substs(trait_substs); let trait_substs = bcx.tcx().mk_substs(trait_substs);
debug!("trait_substs={}", trait_substs.repr(bcx.tcx())); debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
@ -276,13 +274,11 @@ pub fn trans_static_method_callee(bcx: Block,
let subst::SeparateVecsPerParamSpace { let subst::SeparateVecsPerParamSpace {
types: impl_type, types: impl_type,
selfs: impl_self, selfs: impl_self,
assocs: impl_assoc,
fns: _ fns: _
} = impl_substs.types.split(); } = impl_substs.types.split();
let callee_substs = let callee_substs =
Substs::erased(VecPerParamSpace::new(impl_type, Substs::erased(VecPerParamSpace::new(impl_type,
impl_self, impl_self,
impl_assoc,
rcvr_method)); rcvr_method));
let mth_id = method_with_name(ccx, impl_did, mname); let mth_id = method_with_name(ccx, impl_did, mname);
@ -411,13 +407,12 @@ fn combine_impl_and_methods_tps<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let subst::SeparateVecsPerParamSpace { let subst::SeparateVecsPerParamSpace {
types: rcvr_type, types: rcvr_type,
selfs: rcvr_self, selfs: rcvr_self,
assocs: rcvr_assoc,
fns: rcvr_method fns: rcvr_method
} = rcvr_substs.types.clone().split(); } = rcvr_substs.types.clone().split();
assert!(rcvr_method.is_empty()); assert!(rcvr_method.is_empty());
subst::Substs { subst::Substs {
regions: subst::ErasedRegions, regions: subst::ErasedRegions,
types: subst::VecPerParamSpace::new(rcvr_type, rcvr_self, rcvr_assoc, node_method) types: subst::VecPerParamSpace::new(rcvr_type, rcvr_self, node_method)
} }
} }

View file

@ -155,14 +155,11 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
} }
}; };
let number_assoc_types = trait_def.generics.types.len(subst::AssocSpace);
let assoc_types = fcx.inh.infcx.next_ty_vars(number_assoc_types);
assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0); assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0);
assert!(trait_def.generics.regions.is_empty()); assert!(trait_def.generics.regions.is_empty());
// Construct a trait-reference `self_ty : Trait<input_tys>` // Construct a trait-reference `self_ty : Trait<input_tys>`
let substs = subst::Substs::new_trait(input_types, Vec::new(), assoc_types, self_ty); let substs = subst::Substs::new_trait(input_types, Vec::new(), self_ty);
let trait_ref = Rc::new(ty::TraitRef::new(trait_def_id, fcx.tcx().mk_substs(substs))); let trait_ref = Rc::new(ty::TraitRef::new(trait_def_id, fcx.tcx().mk_substs(substs)));
// Construct an obligation // Construct an obligation

View file

@ -5430,7 +5430,6 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
span_err!(fcx.tcx().sess, data.bindings[0].span, E0182, span_err!(fcx.tcx().sess, data.bindings[0].span, E0182,
"unexpected binding of associated item in expression path \ "unexpected binding of associated item in expression path \
(only allowed in type paths)"); (only allowed in type paths)");
substs.types.truncate(subst::ParamSpace::AssocSpace, 0);
} }
{ {

View file

@ -898,7 +898,7 @@ pub fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// ...and also create the `Self` parameter. // ...and also create the `Self` parameter.
let self_ty = ty::mk_self_type(ccx.tcx); let self_ty = ty::mk_self_type(ccx.tcx);
subst::Substs::new_trait(types, regions, Vec::new(), self_ty) subst::Substs::new_trait(types, regions, self_ty)
} }
} }

View file

@ -14,7 +14,7 @@
// Regions that just appear in normal spots are contravariant: // Regions that just appear in normal spots are contravariant:
#[rustc_variance] #[rustc_variance]
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[];[];[]] struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[];[]]
x: &'a int, x: &'a int,
y: &'b [int], y: &'b [int],
c: &'c str c: &'c str
@ -23,7 +23,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[];[];[]]
// Those same annotations in function arguments become covariant: // Those same annotations in function arguments become covariant:
#[rustc_variance] #[rustc_variance]
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[];[];[]] struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[];[]]
x: extern "Rust" fn(&'a int), x: extern "Rust" fn(&'a int),
y: extern "Rust" fn(&'b [int]), y: extern "Rust" fn(&'b [int]),
c: extern "Rust" fn(&'c str), c: extern "Rust" fn(&'c str),
@ -32,7 +32,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[];[];[]]
// Mutability induces invariance: // Mutability induces invariance:
#[rustc_variance] #[rustc_variance]
struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[];[];[]] struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[];[]]
x: &'a mut &'b int, x: &'a mut &'b int,
} }
@ -40,7 +40,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[];[];[]]
// contravariant context: // contravariant context:
#[rustc_variance] #[rustc_variance]
struct Test5<'a, 'b> { //~ ERROR regions=[[+, o];[];[];[]] struct Test5<'a, 'b> { //~ ERROR regions=[[+, o];[];[]]
x: extern "Rust" fn(&'a mut &'b int), x: extern "Rust" fn(&'a mut &'b int),
} }
@ -50,21 +50,21 @@ struct Test5<'a, 'b> { //~ ERROR regions=[[+, o];[];[];[]]
// argument list occurs in an invariant context. // argument list occurs in an invariant context.
#[rustc_variance] #[rustc_variance]
struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[];[]] struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]]
x: &'a mut extern "Rust" fn(&'b int), x: &'a mut extern "Rust" fn(&'b int),
} }
// No uses at all is bivariant: // No uses at all is bivariant:
#[rustc_variance] #[rustc_variance]
struct Test7<'a> { //~ ERROR regions=[[*];[];[];[]] struct Test7<'a> { //~ ERROR regions=[[*];[];[]]
x: int x: int
} }
// Try enums too. // Try enums too.
#[rustc_variance] #[rustc_variance]
enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[];[]] enum Test8<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[]]
Test8A(extern "Rust" fn(&'a int)), Test8A(extern "Rust" fn(&'a int)),
Test8B(&'b [int]), Test8B(&'b [int]),
Test8C(&'b mut &'c str), Test8C(&'b mut &'c str),

View file

@ -13,29 +13,29 @@
// Try enums too. // Try enums too.
#[rustc_variance] #[rustc_variance]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[];[]] enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
Test8A(extern "Rust" fn(&'a int)), Test8A(extern "Rust" fn(&'a int)),
Test8B(&'b [int]), Test8B(&'b [int]),
Test8C(&'b mut &'c str), Test8C(&'b mut &'c str),
} }
#[rustc_variance] #[rustc_variance]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[];[]] struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]]
f: Base<'z, 'y, 'x, 'w> f: Base<'z, 'y, 'x, 'w>
} }
#[rustc_variance] // Combine - and + to yield o #[rustc_variance] // Combine - and + to yield o
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[];[]] struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]]
f: Base<'a, 'a, 'b, 'c> f: Base<'a, 'a, 'b, 'c>
} }
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[];[]] struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]]
f: Base<'a, 'b, 'a, 'c> f: Base<'a, 'b, 'a, 'c>
} }
#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here) #[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here)
struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[];[]] struct Derived4<'a, 'b, 'c:'b> { //~ ERROR regions=[[+, -, o];[];[]]
f: Base<'a, 'b, 'c, 'a> f: Base<'a, 'b, 'c, 'a>
} }

View file

@ -19,7 +19,7 @@ use std::mem;
trait T { fn foo(); } trait T { fn foo(); }
#[rustc_variance] #[rustc_variance]
struct TOption<'a> { //~ ERROR regions=[[-];[];[];[]] struct TOption<'a> { //~ ERROR regions=[[-];[];[]]
v: Option<Box<T + 'a>>, v: Option<Box<T + 'a>>,
} }