Add a 4th space for associated types defined in a trait (currently unused)
This commit is contained in:
parent
94d142b596
commit
d2f8074eac
8 changed files with 85 additions and 69 deletions
|
|
@ -717,8 +717,9 @@ impl<'a> vtable_decoder_helpers 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, fns)
|
VecPerParamSpace::new(types, selfs, assocs, fns)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_vtable_res_with_key(&mut self,
|
fn read_vtable_res_with_key(&mut self,
|
||||||
|
|
|
||||||
|
|
@ -112,8 +112,8 @@ impl Substs {
|
||||||
r: Vec<ty::Region>)
|
r: Vec<ty::Region>)
|
||||||
-> Substs
|
-> Substs
|
||||||
{
|
{
|
||||||
Substs::new(VecPerParamSpace::new(t, Vec::new(), Vec::new()),
|
Substs::new(VecPerParamSpace::new(t, Vec::new(), Vec::new(), Vec::new()),
|
||||||
VecPerParamSpace::new(r, Vec::new(), Vec::new()))
|
VecPerParamSpace::new(r, Vec::new(), Vec::new(), Vec::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_trait(t: Vec<ty::t>,
|
pub fn new_trait(t: Vec<ty::t>,
|
||||||
|
|
@ -121,8 +121,8 @@ impl Substs {
|
||||||
s: ty::t)
|
s: ty::t)
|
||||||
-> Substs
|
-> Substs
|
||||||
{
|
{
|
||||||
Substs::new(VecPerParamSpace::new(t, vec!(s), Vec::new()),
|
Substs::new(VecPerParamSpace::new(t, vec!(s), Vec::new(), Vec::new()),
|
||||||
VecPerParamSpace::new(r, Vec::new(), Vec::new()))
|
VecPerParamSpace::new(r, Vec::new(), Vec::new(), Vec::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn erased(t: VecPerParamSpace<ty::t>) -> Substs
|
pub fn erased(t: VecPerParamSpace<ty::t>) -> Substs
|
||||||
|
|
@ -226,21 +226,23 @@ impl RegionSubsts {
|
||||||
#[deriving(PartialOrd, Ord, PartialEq, Eq,
|
#[deriving(PartialOrd, Ord, PartialEq, Eq,
|
||||||
Clone, Hash, Encodable, Decodable, Show)]
|
Clone, Hash, Encodable, Decodable, Show)]
|
||||||
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
|
||||||
FnSpace, // Type parameters attached to a method or fn
|
AssocSpace, // Assoc types defined in a trait/impl
|
||||||
|
FnSpace, // Type parameters attached to a method or fn
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParamSpace {
|
impl ParamSpace {
|
||||||
pub fn all() -> [ParamSpace, ..3] {
|
pub fn all() -> [ParamSpace, ..4] {
|
||||||
[TypeSpace, SelfSpace, FnSpace]
|
[TypeSpace, SelfSpace, AssocSpace, 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,
|
||||||
FnSpace => 2,
|
AssocSpace => 2,
|
||||||
|
FnSpace => 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,7 +250,8 @@ impl ParamSpace {
|
||||||
match u {
|
match u {
|
||||||
0 => TypeSpace,
|
0 => TypeSpace,
|
||||||
1 => SelfSpace,
|
1 => SelfSpace,
|
||||||
2 => FnSpace,
|
2 => AssocSpace,
|
||||||
|
3 => FnSpace,
|
||||||
_ => panic!("Invalid ParamSpace: {}", u)
|
_ => panic!("Invalid ParamSpace: {}", u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,11 +271,13 @@ pub struct VecPerParamSpace<T> {
|
||||||
// Here is how the representation corresponds to the abstraction
|
// Here is how the representation corresponds to the abstraction
|
||||||
// i.e. the "abstraction function" AF:
|
// i.e. the "abstraction function" AF:
|
||||||
//
|
//
|
||||||
// AF(self) = (self.content.slice_to(self.type_limit),
|
// AF(self) = (self.content[..self.type_limit],
|
||||||
// self.content.slice(self.type_limit, self.self_limit),
|
// self.content[self.type_limit..self.self_limit],
|
||||||
// self.content.slice_from(self.self_limit))
|
// self.content[self.self_limit..self.assoc_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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,7 +297,8 @@ 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),
|
||||||
FnSpace => (self.self_limit, self.content.len()),
|
AssocSpace => (self.self_limit, self.assoc_limit),
|
||||||
|
FnSpace => (self.assoc_limit, self.content.len()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -300,6 +306,7 @@ 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -310,26 +317,33 @@ impl<T> VecPerParamSpace<T> {
|
||||||
|
|
||||||
/// `t` is the type space.
|
/// `t` is the type space.
|
||||||
/// `s` is the self space.
|
/// `s` is the self 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>, f: Vec<T>) -> VecPerParamSpace<T> {
|
pub fn new(t: Vec<T>, s: Vec<T>, a: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
|
||||||
let type_limit = t.len();
|
let type_limit = t.len();
|
||||||
let self_limit = t.len() + 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)
|
fn new_internal(content: Vec<T>, type_limit: uint, self_limit: uint, assoc_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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -341,9 +355,10 @@ 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; }
|
TypeSpace => { self.type_limit += 1; self.self_limit += 1; self.assoc_limit += 1; }
|
||||||
SelfSpace => { self.self_limit += 1; }
|
SelfSpace => { self.self_limit += 1; self.assoc_limit += 1; }
|
||||||
FnSpace => {}
|
AssocSpace => { self.assoc_limit += 1; }
|
||||||
|
FnSpace => { }
|
||||||
}
|
}
|
||||||
self.content.insert(limit, value);
|
self.content.insert(limit, value);
|
||||||
}
|
}
|
||||||
|
|
@ -354,9 +369,10 @@ impl<T> VecPerParamSpace<T> {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
match space {
|
match space {
|
||||||
TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; }
|
TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; self.assoc_limit -= 1; }
|
||||||
SelfSpace => { self.self_limit -= 1; }
|
SelfSpace => { self.self_limit -= 1; self.assoc_limit -= 1; }
|
||||||
FnSpace => {}
|
AssocSpace => { self.assoc_limit -= 1; }
|
||||||
|
FnSpace => {}
|
||||||
}
|
}
|
||||||
self.content.remove(limit - 1)
|
self.content.remove(limit - 1)
|
||||||
}
|
}
|
||||||
|
|
@ -442,35 +458,29 @@ 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_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> {
|
pub fn map_move<U>(self, pred: |T| -> U) -> VecPerParamSpace<U> {
|
||||||
let (t, s, f) = self.split();
|
let (t, s, a, f) = 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) -> (Vec<T>, Vec<T>, Vec<T>) {
|
pub fn split(self) -> (Vec<T>, Vec<T>, Vec<T>, Vec<T>) {
|
||||||
// FIXME (#15418): this does two traversals when in principle
|
let VecPerParamSpace { type_limit, self_limit, assoc_limit, content } = self;
|
||||||
// one would suffice. i.e. change to use `move_iter`.
|
|
||||||
let VecPerParamSpace { type_limit, self_limit, content } = self;
|
|
||||||
let mut i = 0;
|
|
||||||
let (prefix, fn_vec) = content.partition(|_| {
|
|
||||||
let on_left = i < self_limit;
|
|
||||||
i += 1;
|
|
||||||
on_left
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut i = 0;
|
let mut content_iter = content.into_iter();
|
||||||
let (type_vec, self_vec) = prefix.partition(|_| {
|
|
||||||
let on_left = i < type_limit;
|
|
||||||
i += 1;
|
|
||||||
on_left
|
|
||||||
});
|
|
||||||
|
|
||||||
(type_vec, self_vec, fn_vec)
|
let types = content_iter.by_ref().take(type_limit).collect();
|
||||||
|
let selfs = content_iter.by_ref().take(self_limit - type_limit).collect();
|
||||||
|
let assocs = content_iter.by_ref().take(assoc_limit - self_limit).collect();
|
||||||
|
let fns = content_iter.collect();
|
||||||
|
|
||||||
|
(types, selfs, assocs, fns)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_vec(mut self, space: ParamSpace, vec: Vec<T>)
|
pub fn with_vec(mut self, space: ParamSpace, vec: Vec<T>)
|
||||||
|
|
@ -616,12 +626,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||||
this.tcx().sess.span_bug(
|
this.tcx().sess.span_bug(
|
||||||
span,
|
span,
|
||||||
format!("Type parameter `{}` ({}/{}/{}) out of range \
|
format!("Type parameter `{}` ({}/{}/{}) out of range \
|
||||||
when substituting (root type={})",
|
when substituting (root type={}) substs={}",
|
||||||
p.repr(this.tcx()),
|
p.repr(this.tcx()),
|
||||||
source_ty.repr(this.tcx()),
|
source_ty.repr(this.tcx()),
|
||||||
space,
|
space,
|
||||||
index,
|
index,
|
||||||
this.root_ty.repr(this.tcx())).as_slice());
|
this.root_ty.repr(this.tcx()),
|
||||||
|
this.substs.repr(this.tcx())).as_slice());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1607,7 +1607,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err(ErrorReported) => Vec::new()
|
Err(ErrorReported) => Vec::new()
|
||||||
};
|
};
|
||||||
let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new());
|
let obligations = VecPerParamSpace::new(obligations, Vec::new(),
|
||||||
|
Vec::new(), Vec::new());
|
||||||
VtableBuiltinData { nested: obligations }
|
VtableBuiltinData { nested: obligations }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ pub fn trans_static_method_callee(bcx: Block,
|
||||||
// type parameters that belong to the trait but also some that
|
// type parameters that belong to the trait but also some that
|
||||||
// belong to the method:
|
// belong to the method:
|
||||||
let rcvr_substs = node_id_substs(bcx, ExprId(expr_id));
|
let rcvr_substs = node_id_substs(bcx, ExprId(expr_id));
|
||||||
let (rcvr_type, rcvr_self, rcvr_method) = rcvr_substs.types.split();
|
let (rcvr_type, rcvr_self, rcvr_assoc, rcvr_method) = rcvr_substs.types.split();
|
||||||
|
|
||||||
// Lookup the precise impl being called. To do that, we need to
|
// Lookup the precise impl being called. To do that, we need to
|
||||||
// create a trait reference identifying the self type and other
|
// create a trait reference identifying the self type and other
|
||||||
|
|
@ -232,6 +232,7 @@ 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()));
|
||||||
debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
|
debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
|
||||||
let trait_ref = Rc::new(ty::TraitRef { def_id: trait_id,
|
let trait_ref = Rc::new(ty::TraitRef { def_id: trait_id,
|
||||||
|
|
@ -265,10 +266,11 @@ pub fn trans_static_method_callee(bcx: Block,
|
||||||
// that with the `rcvr_method` from before, which tells us
|
// that with the `rcvr_method` from before, which tells us
|
||||||
// the type parameters from the *method*, to yield
|
// the type parameters from the *method*, to yield
|
||||||
// `callee_substs=[[T=int],[],[U=String]]`.
|
// `callee_substs=[[T=int],[],[U=String]]`.
|
||||||
let (impl_type, impl_self, _) = impl_substs.types.split();
|
let (impl_type, impl_self, impl_assoc, _) = 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);
|
||||||
|
|
@ -397,12 +399,12 @@ fn combine_impl_and_methods_tps(bcx: Block,
|
||||||
|
|
||||||
// Break apart the type parameters from the node and type
|
// Break apart the type parameters from the node and type
|
||||||
// parameters from the receiver.
|
// parameters from the receiver.
|
||||||
let (_, _, node_method) = node_substs.types.split();
|
let (_, _, _, node_method) = node_substs.types.split();
|
||||||
let (rcvr_type, rcvr_self, rcvr_method) = rcvr_substs.types.clone().split();
|
let (rcvr_type, rcvr_self, rcvr_assoc, rcvr_method) = 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, node_method)
|
types: subst::VecPerParamSpace::new(rcvr_type, rcvr_self, rcvr_assoc, node_method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -666,10 +666,11 @@ impl Repr for subst::Substs {
|
||||||
|
|
||||||
impl<T:Repr> Repr for subst::VecPerParamSpace<T> {
|
impl<T:Repr> Repr for subst::VecPerParamSpace<T> {
|
||||||
fn repr(&self, tcx: &ctxt) -> String {
|
fn repr(&self, tcx: &ctxt) -> 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::FnSpace).repr(tcx))
|
self.get_slice(subst::AssocSpace).repr(tcx),
|
||||||
|
self.get_slice(subst::FnSpace).repr(tcx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue