mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 18:43:38 +00:00
rustc: remove SelfSpace from ParamSpace.
This commit is contained in:
parent
4158673ad7
commit
c1cfd58cbd
@ -9,7 +9,6 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use ty::subst::ParamSpace;
|
|
||||||
use util::nodemap::NodeMap;
|
use util::nodemap::NodeMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use hir;
|
use hir;
|
||||||
@ -31,7 +30,7 @@ pub enum Def {
|
|||||||
AssociatedTy(DefId /* trait */, DefId),
|
AssociatedTy(DefId /* trait */, DefId),
|
||||||
Trait(DefId),
|
Trait(DefId),
|
||||||
PrimTy(hir::PrimTy),
|
PrimTy(hir::PrimTy),
|
||||||
TyParam(ParamSpace, u32, DefId, ast::Name),
|
TyParam(DefId),
|
||||||
Upvar(DefId, // def id of closed over local
|
Upvar(DefId, // def id of closed over local
|
||||||
ast::NodeId, // node id of closed over local
|
ast::NodeId, // node id of closed over local
|
||||||
usize, // index in the freevars list of the closure
|
usize, // index in the freevars list of the closure
|
||||||
@ -122,7 +121,7 @@ impl Def {
|
|||||||
match *self {
|
match *self {
|
||||||
Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) |
|
Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) |
|
||||||
Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) |
|
Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) |
|
||||||
Def::TyParam(_, _, id, _) | Def::Struct(id) | Def::Trait(id) |
|
Def::TyParam(id) | Def::Struct(id) | Def::Trait(id) |
|
||||||
Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) |
|
Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) |
|
||||||
Def::Local(id, _) | Def::Upvar(id, _, _, _) => {
|
Def::Local(id, _) | Def::Upvar(id, _, _, _) => {
|
||||||
id
|
id
|
||||||
|
@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
|||||||
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
|
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
|
||||||
if self.tcx.trait_of_item(def.def_id()).is_some() => {
|
if self.tcx.trait_of_item(def.def_id()).is_some() => {
|
||||||
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
|
if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
|
||||||
match substs.substs.types.get(subst::SelfSpace, 0).sty {
|
match substs.substs.types.get(subst::TypeSpace, 0).sty {
|
||||||
TyEnum(tyid, _) | TyStruct(tyid, _) => {
|
TyEnum(tyid, _) | TyStruct(tyid, _) => {
|
||||||
self.check_def_id(tyid.did)
|
self.check_def_id(tyid.did)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ use super::{SelectionContext, Obligation, ObligationCause};
|
|||||||
|
|
||||||
use middle::cstore::LOCAL_CRATE;
|
use middle::cstore::LOCAL_CRATE;
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use ty::subst::TypeSpace;
|
|
||||||
use ty::{self, Ty, TyCtxt};
|
use ty::{self, Ty, TyCtxt};
|
||||||
use infer::{InferCtxt, TypeOrigin};
|
use infer::{InferCtxt, TypeOrigin};
|
||||||
use syntax_pos::DUMMY_SP;
|
use syntax_pos::DUMMY_SP;
|
||||||
@ -160,12 +159,9 @@ fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt,
|
|||||||
|
|
||||||
// First, create an ordered iterator over all the type parameters to the trait, with the self
|
// First, create an ordered iterator over all the type parameters to the trait, with the self
|
||||||
// type appearing first.
|
// type appearing first.
|
||||||
let input_tys = Some(trait_ref.self_ty());
|
|
||||||
let input_tys = input_tys.iter().chain(trait_ref.substs.types.get_slice(TypeSpace));
|
|
||||||
|
|
||||||
// Find the first input type that either references a type parameter OR
|
// Find the first input type that either references a type parameter OR
|
||||||
// some local type.
|
// some local type.
|
||||||
for input_ty in input_tys {
|
for input_ty in trait_ref.input_types() {
|
||||||
if ty_is_local(tcx, input_ty, infer_is_local) {
|
if ty_is_local(tcx, input_ty, infer_is_local) {
|
||||||
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
|
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
|
||||||
|
|
||||||
|
@ -232,8 +232,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) {
|
if let Ok(..) = self.can_equate(&trait_self_ty, &impl_self_ty) {
|
||||||
self_match_impls.push(def_id);
|
self_match_impls.push(def_id);
|
||||||
|
|
||||||
if trait_ref.substs.types.get_slice(TypeSpace).iter()
|
if trait_ref.substs.types.get_slice(TypeSpace)[1..].iter()
|
||||||
.zip(impl_trait_ref.substs.types.get_slice(TypeSpace))
|
.zip(&impl_trait_ref.substs.types.get_slice(TypeSpace)[1..])
|
||||||
.all(|(u,v)| self.fuzzy_match_tys(u, v))
|
.all(|(u,v)| self.fuzzy_match_tys(u, v))
|
||||||
{
|
{
|
||||||
fuzzy_match_impls.push(def_id);
|
fuzzy_match_impls.push(def_id);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
use super::elaborate_predicates;
|
use super::elaborate_predicates;
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use ty::subst::{self, SelfSpace, TypeSpace};
|
use ty::subst;
|
||||||
use traits;
|
use traits;
|
||||||
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -146,10 +146,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
match predicate {
|
match predicate {
|
||||||
ty::Predicate::Trait(ref data) => {
|
ty::Predicate::Trait(ref data) => {
|
||||||
// In the case of a trait predicate, we can skip the "self" type.
|
// In the case of a trait predicate, we can skip the "self" type.
|
||||||
data.0.trait_ref.substs.types.get_slice(TypeSpace)
|
data.0.trait_ref.input_types()[1..].iter().any(|t| t.has_self_ty())
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.any(|t| t.has_self_ty())
|
|
||||||
}
|
}
|
||||||
ty::Predicate::Projection(..) |
|
ty::Predicate::Projection(..) |
|
||||||
ty::Predicate::WellFormed(..) |
|
ty::Predicate::WellFormed(..) |
|
||||||
@ -325,7 +322,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
ty.maybe_walk(|ty| {
|
ty.maybe_walk(|ty| {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyParam(ref param_ty) => {
|
ty::TyParam(ref param_ty) => {
|
||||||
if param_ty.space == SelfSpace {
|
if param_ty.is_self() {
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1353,7 +1353,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_self_type(self) -> Ty<'tcx> {
|
pub fn mk_self_type(self) -> Ty<'tcx> {
|
||||||
self.mk_param(subst::SelfSpace, 0, keywords::SelfType.name())
|
self.mk_param(subst::TypeSpace, 0, keywords::SelfType.name())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
|
pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> {
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use ty::subst;
|
|
||||||
use infer::type_variable;
|
use infer::type_variable;
|
||||||
use ty::{self, BoundRegion, Region, Ty, TyCtxt};
|
use ty::{self, BoundRegion, Region, Ty, TyCtxt};
|
||||||
|
|
||||||
@ -258,7 +257,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
|
|||||||
ty::TyInfer(ty::FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
|
ty::TyInfer(ty::FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
|
||||||
ty::TyProjection(_) => "associated type".to_string(),
|
ty::TyProjection(_) => "associated type".to_string(),
|
||||||
ty::TyParam(ref p) => {
|
ty::TyParam(ref p) => {
|
||||||
if p.space == subst::SelfSpace {
|
if p.is_self() {
|
||||||
"Self".to_string()
|
"Self".to_string()
|
||||||
} else {
|
} else {
|
||||||
"type parameter".to_string()
|
"type parameter".to_string()
|
||||||
|
@ -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 ty::subst::{self, Substs};
|
use ty::subst::Substs;
|
||||||
use ty::{self, Ty, TypeFlags, TypeFoldable};
|
use ty::{self, Ty, TypeFlags, TypeFoldable};
|
||||||
|
|
||||||
pub struct FlagComputation {
|
pub struct FlagComputation {
|
||||||
@ -77,7 +77,7 @@ impl FlagComputation {
|
|||||||
|
|
||||||
&ty::TyParam(ref p) => {
|
&ty::TyParam(ref p) => {
|
||||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||||
if p.space == subst::SelfSpace {
|
if p.is_self() {
|
||||||
self.add_flags(TypeFlags::HAS_SELF);
|
self.add_flags(TypeFlags::HAS_SELF);
|
||||||
} else {
|
} else {
|
||||||
self.add_flags(TypeFlags::HAS_PARAMS);
|
self.add_flags(TypeFlags::HAS_PARAMS);
|
||||||
|
@ -1225,7 +1225,7 @@ impl<'tcx> TraitRef<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||||
*self.substs.types.get(subst::SelfSpace, 0)
|
*self.substs.types.get(subst::TypeSpace, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_types(&self) -> &[Ty<'tcx>] {
|
pub fn input_types(&self) -> &[Ty<'tcx>] {
|
||||||
|
@ -305,7 +305,7 @@ pub struct TraitObject<'tcx> {
|
|||||||
///
|
///
|
||||||
/// This would be represented by a trait-reference where the def-id is the
|
/// This would be represented by a trait-reference where the def-id is the
|
||||||
/// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
|
/// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
|
||||||
/// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
|
/// `TypeSpace` and `U` as parameter 1 in the `TypeSpace`.
|
||||||
///
|
///
|
||||||
/// Trait references also appear in object types like `Foo<U>`, but in
|
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||||
/// that case the `Self` parameter is absent from the substitutions.
|
/// that case the `Self` parameter is absent from the substitutions.
|
||||||
@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> ParamTy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_self() -> ParamTy {
|
pub fn for_self() -> ParamTy {
|
||||||
ParamTy::new(subst::SelfSpace, 0, keywords::SelfType.name())
|
ParamTy::new(subst::TypeSpace, 0, keywords::SelfType.name())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy {
|
pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy {
|
||||||
@ -524,7 +524,13 @@ impl<'a, 'gcx, 'tcx> ParamTy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_self(&self) -> bool {
|
pub fn is_self(&self) -> bool {
|
||||||
self.space == subst::SelfSpace && self.idx == 0
|
if self.name == keywords::SelfType.name() {
|
||||||
|
assert_eq!(self.space, subst::TypeSpace);
|
||||||
|
assert_eq!(self.idx, 0);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,7 +960,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||||||
|
|
||||||
pub fn is_self(&self) -> bool {
|
pub fn is_self(&self) -> bool {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
TyParam(ref p) => p.space == subst::SelfSpace,
|
TyParam(ref p) => p.is_self(),
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
r: Vec<ty::Region>)
|
r: Vec<ty::Region>)
|
||||||
-> &'tcx Substs<'tcx>
|
-> &'tcx Substs<'tcx>
|
||||||
{
|
{
|
||||||
Substs::new(tcx, VecPerParamSpace::new(vec![], vec![], t),
|
Substs::new(tcx, VecPerParamSpace::new(vec![], t),
|
||||||
VecPerParamSpace::new(vec![], vec![], r))
|
VecPerParamSpace::new(vec![], r))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_type(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub fn new_type(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
@ -56,18 +56,19 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
r: Vec<ty::Region>)
|
r: Vec<ty::Region>)
|
||||||
-> &'tcx Substs<'tcx>
|
-> &'tcx Substs<'tcx>
|
||||||
{
|
{
|
||||||
Substs::new(tcx, VecPerParamSpace::new(vec![], t, vec![]),
|
Substs::new(tcx, VecPerParamSpace::new(t, vec![]),
|
||||||
VecPerParamSpace::new(vec![], r, vec![]))
|
VecPerParamSpace::new(r, vec![]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
t: Vec<Ty<'tcx>>,
|
mut t: Vec<Ty<'tcx>>,
|
||||||
r: Vec<ty::Region>,
|
r: Vec<ty::Region>,
|
||||||
s: Ty<'tcx>)
|
s: Ty<'tcx>)
|
||||||
-> &'tcx Substs<'tcx>
|
-> &'tcx Substs<'tcx>
|
||||||
{
|
{
|
||||||
Substs::new(tcx, VecPerParamSpace::new(vec![s], t, vec![]),
|
t.insert(0, s);
|
||||||
VecPerParamSpace::new(vec![], r, vec![]))
|
Substs::new(tcx, VecPerParamSpace::new(t, vec![]),
|
||||||
|
VecPerParamSpace::new(r, vec![]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
|
pub fn empty(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx Substs<'tcx> {
|
||||||
@ -90,12 +91,10 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
let defs = tcx.lookup_generics(def_id);
|
let defs = tcx.lookup_generics(def_id);
|
||||||
let mut substs = Substs {
|
let mut substs = Substs {
|
||||||
types: VecPerParamSpace {
|
types: VecPerParamSpace {
|
||||||
self_limit: 0,
|
|
||||||
type_limit: 0,
|
type_limit: 0,
|
||||||
content: Vec::with_capacity(defs.types.content.len())
|
content: Vec::with_capacity(defs.types.content.len())
|
||||||
},
|
},
|
||||||
regions: VecPerParamSpace {
|
regions: VecPerParamSpace {
|
||||||
self_limit: 0,
|
|
||||||
type_limit: 0,
|
type_limit: 0,
|
||||||
content: Vec::with_capacity(defs.regions.content.len())
|
content: Vec::with_capacity(defs.regions.content.len())
|
||||||
}
|
}
|
||||||
@ -104,7 +103,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
for &space in &ParamSpace::all() {
|
for &space in &ParamSpace::all() {
|
||||||
for def in defs.regions.get_slice(space) {
|
for def in defs.regions.get_slice(space) {
|
||||||
assert_eq!(def.space, space);
|
assert_eq!(def.space, space);
|
||||||
assert!(space != SelfSpace);
|
|
||||||
|
|
||||||
let region = mk_region(def, &substs);
|
let region = mk_region(def, &substs);
|
||||||
substs.regions.content.push(region);
|
substs.regions.content.push(region);
|
||||||
@ -120,11 +118,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
let ty = mk_type(def, &substs);
|
let ty = mk_type(def, &substs);
|
||||||
substs.types.content.push(ty);
|
substs.types.content.push(ty);
|
||||||
|
|
||||||
if space == SelfSpace {
|
if space == TypeSpace {
|
||||||
substs.types.self_limit += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if space <= TypeSpace {
|
|
||||||
substs.types.type_limit += 1;
|
substs.types.type_limit += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +149,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
target_substs: &Substs<'tcx>)
|
target_substs: &Substs<'tcx>)
|
||||||
-> &'tcx Substs<'tcx> {
|
-> &'tcx Substs<'tcx> {
|
||||||
let defs = tcx.lookup_generics(source_ancestor);
|
let defs = tcx.lookup_generics(source_ancestor);
|
||||||
assert_eq!(self.types.len(SelfSpace), defs.types.len(SelfSpace));
|
|
||||||
assert_eq!(self.types.len(TypeSpace), defs.types.len(TypeSpace));
|
assert_eq!(self.types.len(TypeSpace), defs.types.len(TypeSpace));
|
||||||
assert_eq!(target_substs.types.len(FnSpace), 0);
|
assert_eq!(target_substs.types.len(FnSpace), 0);
|
||||||
assert_eq!(defs.types.len(FnSpace), 0);
|
assert_eq!(defs.types.len(FnSpace), 0);
|
||||||
@ -195,29 +188,26 @@ impl<'tcx> Decodable for &'tcx Substs<'tcx> {
|
|||||||
#[derive(PartialOrd, Ord, PartialEq, Eq, Copy,
|
#[derive(PartialOrd, Ord, PartialEq, Eq, Copy,
|
||||||
Clone, Hash, RustcEncodable, RustcDecodable, Debug)]
|
Clone, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub enum ParamSpace {
|
pub enum ParamSpace {
|
||||||
SelfSpace, // Self parameter on a trait
|
|
||||||
TypeSpace, // Type parameters attached to a type definition, trait, or impl
|
TypeSpace, // Type parameters attached to a type definition, trait, or 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; 3] {
|
pub fn all() -> [ParamSpace; 2] {
|
||||||
[SelfSpace, TypeSpace, FnSpace]
|
[TypeSpace, FnSpace]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_uint(self) -> usize {
|
pub fn to_uint(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
SelfSpace => 0,
|
TypeSpace => 0,
|
||||||
TypeSpace => 1,
|
FnSpace => 1,
|
||||||
FnSpace => 2,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_uint(u: usize) -> ParamSpace {
|
pub fn from_uint(u: usize) -> ParamSpace {
|
||||||
match u {
|
match u {
|
||||||
0 => SelfSpace,
|
0 => TypeSpace,
|
||||||
1 => TypeSpace,
|
1 => FnSpace,
|
||||||
2 => FnSpace,
|
|
||||||
_ => bug!("Invalid ParamSpace: {}", u)
|
_ => bug!("Invalid ParamSpace: {}", u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -235,18 +225,15 @@ 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[..self.self_limit],
|
// AF(self) = (self.content[..self.type_limit],
|
||||||
// self.content[self.self_limit..self.type_limit],
|
|
||||||
// self.content[self.type_limit..])
|
// self.content[self.type_limit..])
|
||||||
self_limit: usize,
|
|
||||||
type_limit: usize,
|
type_limit: usize,
|
||||||
content: Vec<T>,
|
content: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
|
impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "[{:?};{:?};{:?}]",
|
write!(f, "[{:?};{:?}]",
|
||||||
self.get_slice(SelfSpace),
|
|
||||||
self.get_slice(TypeSpace),
|
self.get_slice(TypeSpace),
|
||||||
self.get_slice(FnSpace))
|
self.get_slice(FnSpace))
|
||||||
}
|
}
|
||||||
@ -255,43 +242,34 @@ impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
|
|||||||
impl<T> VecPerParamSpace<T> {
|
impl<T> VecPerParamSpace<T> {
|
||||||
fn limits(&self, space: ParamSpace) -> (usize, usize) {
|
fn limits(&self, space: ParamSpace) -> (usize, usize) {
|
||||||
match space {
|
match space {
|
||||||
SelfSpace => (0, self.self_limit),
|
TypeSpace => (0, self.type_limit),
|
||||||
TypeSpace => (self.self_limit, self.type_limit),
|
|
||||||
FnSpace => (self.type_limit, self.content.len()),
|
FnSpace => (self.type_limit, self.content.len()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty() -> VecPerParamSpace<T> {
|
pub fn empty() -> VecPerParamSpace<T> {
|
||||||
VecPerParamSpace {
|
VecPerParamSpace {
|
||||||
self_limit: 0,
|
|
||||||
type_limit: 0,
|
type_limit: 0,
|
||||||
content: Vec::new()
|
content: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `s` is the self space.
|
|
||||||
/// `t` is the type space.
|
/// `t` is the type space.
|
||||||
/// `f` is the fn space.
|
/// `f` is the fn space.
|
||||||
pub fn new(s: Vec<T>, t: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
|
pub fn new(t: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
|
||||||
let self_limit = s.len();
|
let type_limit = t.len();
|
||||||
let type_limit = self_limit + t.len();
|
|
||||||
|
|
||||||
let mut content = s;
|
let mut content = t;
|
||||||
content.extend(t);
|
|
||||||
content.extend(f);
|
content.extend(f);
|
||||||
|
|
||||||
VecPerParamSpace {
|
VecPerParamSpace {
|
||||||
self_limit: self_limit,
|
|
||||||
type_limit: type_limit,
|
type_limit: type_limit,
|
||||||
content: content,
|
content: content,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_internal(content: Vec<T>, self_limit: usize, type_limit: usize)
|
fn new_internal(content: Vec<T>, type_limit: usize) -> VecPerParamSpace<T> {
|
||||||
-> VecPerParamSpace<T>
|
|
||||||
{
|
|
||||||
VecPerParamSpace {
|
VecPerParamSpace {
|
||||||
self_limit: self_limit,
|
|
||||||
type_limit: type_limit,
|
type_limit: type_limit,
|
||||||
content: content,
|
content: content,
|
||||||
}
|
}
|
||||||
@ -336,18 +314,14 @@ impl<T> VecPerParamSpace<T> {
|
|||||||
|
|
||||||
pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U {
|
pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where P: FnMut(&T) -> U {
|
||||||
let result = self.as_full_slice().iter().map(pred).collect();
|
let result = self.as_full_slice().iter().map(pred).collect();
|
||||||
VecPerParamSpace::new_internal(result,
|
VecPerParamSpace::new_internal(result, self.type_limit)
|
||||||
self.self_limit,
|
|
||||||
self.type_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
|
||||||
P: FnMut((ParamSpace, usize, &T)) -> U,
|
P: FnMut((ParamSpace, usize, &T)) -> U,
|
||||||
{
|
{
|
||||||
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.self_limit,
|
|
||||||
self.type_limit)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,8 +613,6 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
|
|||||||
-> ty::ExistentialTraitRef<'tcx> {
|
-> ty::ExistentialTraitRef<'tcx> {
|
||||||
let Substs { mut types, regions } = trait_ref.substs.clone();
|
let Substs { mut types, regions } = trait_ref.substs.clone();
|
||||||
|
|
||||||
assert_eq!(types.self_limit, 1);
|
|
||||||
types.self_limit = 0;
|
|
||||||
types.type_limit -= 1;
|
types.type_limit -= 1;
|
||||||
types.content.remove(0);
|
types.content.remove(0);
|
||||||
|
|
||||||
@ -665,8 +637,6 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
|
|||||||
self.map_bound(|trait_ref| {
|
self.map_bound(|trait_ref| {
|
||||||
let Substs { mut types, regions } = trait_ref.substs.clone();
|
let Substs { mut types, regions } = trait_ref.substs.clone();
|
||||||
|
|
||||||
assert_eq!(types.self_limit, 0);
|
|
||||||
types.self_limit = 1;
|
|
||||||
types.type_limit += 1;
|
types.type_limit += 1;
|
||||||
types.content.insert(0, self_ty);
|
types.content.insert(0, self_ty);
|
||||||
|
|
||||||
|
@ -62,35 +62,36 @@ pub enum Ns {
|
|||||||
Value
|
Value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|
||||||
substs: &subst::Substs,
|
|
||||||
space: subst::ParamSpace,
|
|
||||||
generics: &ty::Generics<'tcx>)
|
|
||||||
-> usize
|
|
||||||
{
|
|
||||||
let ty_params = generics.types.get_slice(space);
|
|
||||||
let tps = substs.types.get_slice(space);
|
|
||||||
if ty_params.last().map_or(false, |def| def.default.is_some()) {
|
|
||||||
let substs = tcx.lift(&substs);
|
|
||||||
ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
|
|
||||||
substs.and_then(|substs| def.default.subst(tcx, substs))
|
|
||||||
== Some(actual)
|
|
||||||
}).count()
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parameterized(f: &mut fmt::Formatter,
|
pub fn parameterized(f: &mut fmt::Formatter,
|
||||||
substs: &subst::Substs,
|
substs: &subst::Substs,
|
||||||
did: DefId,
|
did: DefId,
|
||||||
ns: Ns,
|
ns: Ns,
|
||||||
projections: &[ty::ProjectionPredicate])
|
projections: &[ty::ProjectionPredicate])
|
||||||
-> fmt::Result {
|
-> fmt::Result {
|
||||||
let (fn_trait_kind, verbose, item_name, is_in_trait) = ty::tls::with(|tcx| {
|
let mut verbose = false;
|
||||||
let is_in_trait = ns == Ns::Value && tcx.trait_of_item(did).is_some();
|
let mut num_supplied_defaults = 0;
|
||||||
if is_in_trait {
|
let mut has_self = false;
|
||||||
write!(f, "<{} as ", substs.types.get(subst::SelfSpace, 0))?;
|
let (fn_trait_kind, item_name) = ty::tls::with(|tcx| {
|
||||||
|
verbose = tcx.sess.verbose();
|
||||||
|
let generics = tcx.lookup_generics(did);
|
||||||
|
if !verbose {
|
||||||
|
let ty_params = generics.types.get_slice(subst::TypeSpace);
|
||||||
|
if ty_params.last().map_or(false, |def| def.default.is_some()) {
|
||||||
|
if let Some(substs) = tcx.lift(&substs) {
|
||||||
|
let tps = substs.types.get_slice(subst::TypeSpace);
|
||||||
|
for (def, actual) in ty_params.iter().zip(tps).rev() {
|
||||||
|
if def.default.subst(tcx, substs) != Some(actual) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num_supplied_defaults += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
has_self = generics.has_self;
|
||||||
|
if ns == Ns::Value && has_self {
|
||||||
|
write!(f, "<{} as ", substs.types.get(subst::TypeSpace, 0))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (did, item_name) = if ns == Ns::Value {
|
let (did, item_name) = if ns == Ns::Value {
|
||||||
@ -107,15 +108,12 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
|||||||
(did, None)
|
(did, None)
|
||||||
};
|
};
|
||||||
write!(f, "{}", tcx.item_path_str(did))?;
|
write!(f, "{}", tcx.item_path_str(did))?;
|
||||||
Ok((tcx.lang_items.fn_trait_kind(did),
|
Ok((tcx.lang_items.fn_trait_kind(did), item_name))
|
||||||
tcx.sess.verbose(),
|
|
||||||
item_name,
|
|
||||||
is_in_trait))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
|
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
|
||||||
let projection_ty = projections[0].ty;
|
let projection_ty = projections[0].ty;
|
||||||
if let TyTuple(ref args) = substs.types.get(subst::TypeSpace, 0).sty {
|
if let TyTuple(ref args) = substs.types.get(subst::TypeSpace, 1).sty {
|
||||||
return fn_sig(f, args, false, projection_ty);
|
return fn_sig(f, args, false, projection_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,18 +158,9 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
|||||||
|
|
||||||
print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?;
|
print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?;
|
||||||
|
|
||||||
let num_supplied_defaults = if verbose {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
ty::tls::with(|tcx| {
|
|
||||||
let generics = tcx.lookup_generics(did);
|
|
||||||
number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let tps = substs.types.get_slice(subst::TypeSpace);
|
let tps = substs.types.get_slice(subst::TypeSpace);
|
||||||
|
|
||||||
for &ty in &tps[..tps.len() - num_supplied_defaults] {
|
for &ty in &tps[has_self as usize..tps.len() - num_supplied_defaults] {
|
||||||
start_or_continue(f, "<", ", ")?;
|
start_or_continue(f, "<", ", ")?;
|
||||||
write!(f, "{}", ty)?;
|
write!(f, "{}", ty)?;
|
||||||
}
|
}
|
||||||
@ -189,7 +178,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
|||||||
if ns == Ns::Value {
|
if ns == Ns::Value {
|
||||||
empty.set(true);
|
empty.set(true);
|
||||||
|
|
||||||
if is_in_trait {
|
if has_self {
|
||||||
write!(f, ">")?;
|
write!(f, ">")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use super::{drop_flag_effects_for_location, on_all_children_bits};
|
|||||||
use super::{DropFlagState, MoveDataParamEnv};
|
use super::{DropFlagState, MoveDataParamEnv};
|
||||||
use super::patch::MirPatch;
|
use super::patch::MirPatch;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::subst::{Subst, Substs, VecPerParamSpace};
|
use rustc::ty::subst::{Subst, Substs};
|
||||||
use rustc::mir::repr::*;
|
use rustc::mir::repr::*;
|
||||||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||||
use rustc::middle::const_val::ConstVal;
|
use rustc::middle::const_val::ConstVal;
|
||||||
@ -859,9 +859,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||||||
let unit_temp = Lvalue::Temp(self.patch.new_temp(tcx.mk_nil()));
|
let unit_temp = Lvalue::Temp(self.patch.new_temp(tcx.mk_nil()));
|
||||||
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
|
let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
|
||||||
.unwrap_or_else(|e| tcx.sess.fatal(&e));
|
.unwrap_or_else(|e| tcx.sess.fatal(&e));
|
||||||
let substs = Substs::new(tcx,
|
let substs = Substs::new_fn(tcx, vec![ty], vec![]);
|
||||||
VecPerParamSpace::new(vec![], vec![], vec![ty]),
|
|
||||||
VecPerParamSpace::new(vec![], vec![], vec![]));
|
|
||||||
let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
|
let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
|
||||||
|
|
||||||
self.patch.new_block(BasicBlockData {
|
self.patch.new_block(BasicBlockData {
|
||||||
|
@ -413,7 +413,7 @@ impl tr for Def {
|
|||||||
Def::AssociatedTy(trait_did, did) =>
|
Def::AssociatedTy(trait_did, did) =>
|
||||||
Def::AssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
|
Def::AssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
|
||||||
Def::PrimTy(p) => Def::PrimTy(p),
|
Def::PrimTy(p) => Def::PrimTy(p),
|
||||||
Def::TyParam(s, index, def_id, n) => Def::TyParam(s, index, def_id.tr(dcx), n),
|
Def::TyParam(did) => Def::TyParam(did.tr(dcx)),
|
||||||
Def::Upvar(_, nid1, index, nid2) => {
|
Def::Upvar(_, nid1, index, nid2) => {
|
||||||
let nid1 = dcx.tr_id(nid1);
|
let nid1 = dcx.tr_id(nid1);
|
||||||
let nid2 = dcx.tr_id(nid2);
|
let nid2 = dcx.tr_id(nid2);
|
||||||
|
@ -131,15 +131,15 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
|
|||||||
fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
|
fn parse_vec_per_param_space<T, F>(&mut self, mut f: F) -> VecPerParamSpace<T> where
|
||||||
F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
|
F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
|
||||||
{
|
{
|
||||||
let (mut a, mut b, mut c) = (vec![], vec![], vec![]);
|
let (mut a, mut b) = (vec![], vec![]);
|
||||||
for r in &mut [&mut a, &mut b, &mut c] {
|
for r in &mut [&mut a, &mut b] {
|
||||||
assert_eq!(self.next(), '[');
|
assert_eq!(self.next(), '[');
|
||||||
while self.peek() != ']' {
|
while self.peek() != ']' {
|
||||||
r.push(f(self));
|
r.push(f(self));
|
||||||
}
|
}
|
||||||
assert_eq!(self.next(), ']');
|
assert_eq!(self.next(), ']');
|
||||||
}
|
}
|
||||||
VecPerParamSpace::new(a, b, c)
|
VecPerParamSpace::new(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
|
pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
|
||||||
|
@ -49,7 +49,6 @@ use rustc::lint;
|
|||||||
use rustc::hir::def::*;
|
use rustc::hir::def::*;
|
||||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
|
|
||||||
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
|
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
|
||||||
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
|
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
|
||||||
|
|
||||||
@ -557,7 +556,7 @@ impl<'a> Visitor for Resolver<'a> {
|
|||||||
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
||||||
let type_parameters = match foreign_item.node {
|
let type_parameters = match foreign_item.node {
|
||||||
ForeignItemKind::Fn(_, ref generics) => {
|
ForeignItemKind::Fn(_, ref generics) => {
|
||||||
HasTypeParameters(generics, FnSpace, ItemRibKind)
|
HasTypeParameters(generics, ItemRibKind)
|
||||||
}
|
}
|
||||||
ForeignItemKind::Static(..) => NoTypeParameters,
|
ForeignItemKind::Static(..) => NoTypeParameters,
|
||||||
};
|
};
|
||||||
@ -625,10 +624,6 @@ enum TypeParameters<'a, 'b> {
|
|||||||
HasTypeParameters(// Type parameters.
|
HasTypeParameters(// Type parameters.
|
||||||
&'b Generics,
|
&'b Generics,
|
||||||
|
|
||||||
// Identifies the things that these parameters
|
|
||||||
// were declared on (type, fn, etc)
|
|
||||||
ParamSpace,
|
|
||||||
|
|
||||||
// The kind of the rib used for type parameters.
|
// The kind of the rib used for type parameters.
|
||||||
RibKind<'a>),
|
RibKind<'a>),
|
||||||
}
|
}
|
||||||
@ -1613,12 +1608,9 @@ impl<'a> Resolver<'a> {
|
|||||||
match item.node {
|
match item.node {
|
||||||
ItemKind::Enum(_, ref generics) |
|
ItemKind::Enum(_, ref generics) |
|
||||||
ItemKind::Ty(_, ref generics) |
|
ItemKind::Ty(_, ref generics) |
|
||||||
ItemKind::Struct(_, ref generics) => {
|
ItemKind::Struct(_, ref generics) |
|
||||||
self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
|
|
||||||
|this| visit::walk_item(this, item));
|
|
||||||
}
|
|
||||||
ItemKind::Fn(_, _, _, _, ref generics, _) => {
|
ItemKind::Fn(_, _, _, _, ref generics, _) => {
|
||||||
self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
|
self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind),
|
||||||
|this| visit::walk_item(this, item));
|
|this| visit::walk_item(this, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1634,10 +1626,7 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
|
ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
|
||||||
// Create a new rib for the trait-wide type parameters.
|
// Create a new rib for the trait-wide type parameters.
|
||||||
self.with_type_parameter_rib(HasTypeParameters(generics,
|
self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
|
||||||
TypeSpace,
|
|
||||||
ItemRibKind),
|
|
||||||
|this| {
|
|
||||||
let local_def_id = this.definitions.local_def_id(item.id);
|
let local_def_id = this.definitions.local_def_id(item.id);
|
||||||
this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
|
this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
@ -1660,7 +1649,6 @@ impl<'a> Resolver<'a> {
|
|||||||
TraitItemKind::Method(ref sig, _) => {
|
TraitItemKind::Method(ref sig, _) => {
|
||||||
let type_parameters =
|
let type_parameters =
|
||||||
HasTypeParameters(&sig.generics,
|
HasTypeParameters(&sig.generics,
|
||||||
FnSpace,
|
|
||||||
MethodRibKind(!sig.decl.has_self()));
|
MethodRibKind(!sig.decl.has_self()));
|
||||||
this.with_type_parameter_rib(type_parameters, |this| {
|
this.with_type_parameter_rib(type_parameters, |this| {
|
||||||
visit::walk_trait_item(this, trait_item)
|
visit::walk_trait_item(this, trait_item)
|
||||||
@ -1729,10 +1717,10 @@ impl<'a> Resolver<'a> {
|
|||||||
where F: FnOnce(&mut Resolver)
|
where F: FnOnce(&mut Resolver)
|
||||||
{
|
{
|
||||||
match type_parameters {
|
match type_parameters {
|
||||||
HasTypeParameters(generics, space, rib_kind) => {
|
HasTypeParameters(generics, rib_kind) => {
|
||||||
let mut function_type_rib = Rib::new(rib_kind);
|
let mut function_type_rib = Rib::new(rib_kind);
|
||||||
let mut seen_bindings = HashSet::new();
|
let mut seen_bindings = HashSet::new();
|
||||||
for (index, type_parameter) in generics.ty_params.iter().enumerate() {
|
for type_parameter in &generics.ty_params {
|
||||||
let name = type_parameter.ident.name;
|
let name = type_parameter.ident.name;
|
||||||
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
||||||
|
|
||||||
@ -1745,7 +1733,7 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
// plain insert (no renaming)
|
// plain insert (no renaming)
|
||||||
let def_id = self.definitions.local_def_id(type_parameter.id);
|
let def_id = self.definitions.local_def_id(type_parameter.id);
|
||||||
let def = Def::TyParam(space, index as u32, def_id, name);
|
let def = Def::TyParam(def_id);
|
||||||
function_type_rib.bindings.insert(ast::Ident::with_empty_ctxt(name), def);
|
function_type_rib.bindings.insert(ast::Ident::with_empty_ctxt(name), def);
|
||||||
self.record_def(type_parameter.id, PathResolution::new(def));
|
self.record_def(type_parameter.id, PathResolution::new(def));
|
||||||
}
|
}
|
||||||
@ -1917,10 +1905,7 @@ impl<'a> Resolver<'a> {
|
|||||||
item_id: NodeId,
|
item_id: NodeId,
|
||||||
impl_items: &[ImplItem]) {
|
impl_items: &[ImplItem]) {
|
||||||
// If applicable, create a rib for the type parameters.
|
// If applicable, create a rib for the type parameters.
|
||||||
self.with_type_parameter_rib(HasTypeParameters(generics,
|
self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
|
||||||
TypeSpace,
|
|
||||||
ItemRibKind),
|
|
||||||
|this| {
|
|
||||||
// Resolve the type parameters.
|
// Resolve the type parameters.
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
|
|
||||||
@ -1953,7 +1938,6 @@ impl<'a> Resolver<'a> {
|
|||||||
// specific type parameters.
|
// specific type parameters.
|
||||||
let type_parameters =
|
let type_parameters =
|
||||||
HasTypeParameters(&sig.generics,
|
HasTypeParameters(&sig.generics,
|
||||||
FnSpace,
|
|
||||||
MethodRibKind(!sig.decl.has_self()));
|
MethodRibKind(!sig.decl.has_self()));
|
||||||
this.with_type_parameter_rib(type_parameters, |this| {
|
this.with_type_parameter_rib(type_parameters, |this| {
|
||||||
visit::walk_impl_item(this, impl_item);
|
visit::walk_impl_item(this, impl_item);
|
||||||
|
@ -490,7 +490,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||||||
Def::Enum(def_id) |
|
Def::Enum(def_id) |
|
||||||
Def::TyAlias(def_id) |
|
Def::TyAlias(def_id) |
|
||||||
Def::Trait(def_id) |
|
Def::Trait(def_id) |
|
||||||
Def::TyParam(_, _, def_id, _) => {
|
Def::TyParam(def_id) => {
|
||||||
Some(Data::TypeRefData(TypeRefData {
|
Some(Data::TypeRefData(TypeRefData {
|
||||||
span: sub_span.unwrap(),
|
span: sub_span.unwrap(),
|
||||||
ref_id: Some(def_id),
|
ref_id: Some(def_id),
|
||||||
|
@ -488,7 +488,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
// DefId, we use the location of the impl after all.
|
// DefId, we use the location of the impl after all.
|
||||||
|
|
||||||
if tcx.trait_of_item(instance.def).is_some() {
|
if tcx.trait_of_item(instance.def).is_some() {
|
||||||
let self_ty = *instance.substs.types.get(subst::SelfSpace, 0);
|
let self_ty = *instance.substs.types.get(subst::TypeSpace, 0);
|
||||||
// This is an implementation of a trait method.
|
// This is an implementation of a trait method.
|
||||||
return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
|
return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ use hir::def_id::DefId;
|
|||||||
use hir::print as pprust;
|
use hir::print as pprust;
|
||||||
use middle::resolve_lifetime as rl;
|
use middle::resolve_lifetime as rl;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::ty::subst::{TypeSpace, SelfSpace, Subst, Substs};
|
use rustc::ty::subst::{TypeSpace, Subst, Substs};
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
|
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
|
||||||
use rustc::ty::wf::object_region_bounds;
|
use rustc::ty::wf::object_region_bounds;
|
||||||
@ -455,6 +455,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
// Check the number of type parameters supplied by the user.
|
// Check the number of type parameters supplied by the user.
|
||||||
if let Some(num_provided) = num_types_provided {
|
if let Some(num_provided) = num_types_provided {
|
||||||
let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
|
let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
|
||||||
|
let ty_param_defs = &ty_param_defs[self_ty.is_some() as usize..];
|
||||||
check_type_argument_count(tcx, span, num_provided, ty_param_defs);
|
check_type_argument_count(tcx, span, num_provided, ty_param_defs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,13 +477,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
assert_eq!(def.space, TypeSpace);
|
assert_eq!(def.space, TypeSpace);
|
||||||
regions[def.index as usize]
|
regions[def.index as usize]
|
||||||
}, |def, substs| {
|
}, |def, substs| {
|
||||||
assert!(def.space == SelfSpace || def.space == TypeSpace);
|
assert!(def.space == TypeSpace);
|
||||||
let i = def.index as usize;
|
let i = def.index as usize;
|
||||||
if def.space == SelfSpace {
|
|
||||||
// Self, which must have been provided.
|
// Handle Self first, so we can adjust the index to match the AST.
|
||||||
assert_eq!(i, 0);
|
if let (0, Some(ty)) = (i, self_ty) {
|
||||||
self_ty.expect("Self type parameter missing")
|
return ty;
|
||||||
} else if num_types_provided.map_or(false, |n| i < n) {
|
}
|
||||||
|
|
||||||
|
let i = i - self_ty.is_some() as usize;
|
||||||
|
if num_types_provided.map_or(false, |n| i < n) {
|
||||||
// A provided type parameter.
|
// A provided type parameter.
|
||||||
match *parameters {
|
match *parameters {
|
||||||
hir::AngleBracketedParameters(ref data) => {
|
hir::AngleBracketedParameters(ref data) => {
|
||||||
@ -1325,8 +1329,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
Err(ErrorReported) => return (tcx.types.err, Def::Err),
|
Err(ErrorReported) => return (tcx.types.err, Def::Err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&ty::TyParam(_), Def::TyParam(_, _, param_did, param_name)) => {
|
(&ty::TyParam(_), Def::TyParam(param_did)) => {
|
||||||
let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
|
let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
|
||||||
|
let param_name = tcx.type_parameter_def(param_node_id).name;
|
||||||
match self.find_bound_for_assoc_item(param_node_id,
|
match self.find_bound_for_assoc_item(param_node_id,
|
||||||
param_name,
|
param_name,
|
||||||
assoc_name,
|
assoc_name,
|
||||||
@ -1336,10 +1341,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
// Don't print TyErr to the user.
|
||||||
|
if !ty.references_error() {
|
||||||
self.report_ambiguous_associated_type(span,
|
self.report_ambiguous_associated_type(span,
|
||||||
&ty.to_string(),
|
&ty.to_string(),
|
||||||
"Trait",
|
"Trait",
|
||||||
&assoc_name.as_str());
|
&assoc_name.as_str());
|
||||||
|
}
|
||||||
return (tcx.types.err, Def::Err);
|
return (tcx.types.err, Def::Err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1477,9 +1485,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
did,
|
did,
|
||||||
base_segments.last().unwrap())
|
base_segments.last().unwrap())
|
||||||
}
|
}
|
||||||
Def::TyParam(space, index, _, name) => {
|
Def::TyParam(did) => {
|
||||||
tcx.prohibit_type_params(base_segments);
|
tcx.prohibit_type_params(base_segments);
|
||||||
tcx.mk_param(space, index, name)
|
|
||||||
|
let node_id = tcx.map.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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Def::SelfTy(_, Some(impl_id)) => {
|
Def::SelfTy(_, Some(impl_id)) => {
|
||||||
// Self in impl (we know the concrete type).
|
// Self in impl (we know the concrete type).
|
||||||
|
@ -204,7 +204,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 0);
|
let arg_param_ty = *trait_ref.substs().types.get(subst::TypeSpace, 1);
|
||||||
let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
|
let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
|
||||||
debug!("deduce_sig_from_projection: arg_param_ty {:?}", arg_param_ty);
|
debug!("deduce_sig_from_projection: arg_param_ty {:?}", arg_param_ty);
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
|
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
|
||||||
|
|
||||||
if let Some(ref input_types) = opt_input_types {
|
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::TypeSpace) - 1, input_types.len());
|
||||||
}
|
}
|
||||||
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());
|
||||||
@ -192,10 +192,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
|
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
|
||||||
self.region_var_for_def(span, def)
|
self.region_var_for_def(span, def)
|
||||||
}, |def, substs| {
|
}, |def, substs| {
|
||||||
if def.space == subst::SelfSpace {
|
if def.index == 0 {
|
||||||
self_ty
|
self_ty
|
||||||
} else if let Some(ref input_types) = opt_input_types {
|
} else if let Some(ref input_types) = opt_input_types {
|
||||||
input_types[def.index as usize]
|
input_types[def.index as usize - 1]
|
||||||
} else {
|
} else {
|
||||||
self.type_var_for_def(span, def, substs)
|
self.type_var_for_def(span, def, substs)
|
||||||
}
|
}
|
||||||
|
@ -522,10 +522,6 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
trait_ref.substs.types.len(subst::TypeSpace));
|
trait_ref.substs.types.len(subst::TypeSpace));
|
||||||
assert_eq!(m.generics.regions.len(subst::TypeSpace),
|
assert_eq!(m.generics.regions.len(subst::TypeSpace),
|
||||||
trait_ref.substs.regions.len(subst::TypeSpace));
|
trait_ref.substs.regions.len(subst::TypeSpace));
|
||||||
assert_eq!(m.generics.types.len(subst::SelfSpace),
|
|
||||||
trait_ref.substs.types.len(subst::SelfSpace));
|
|
||||||
assert_eq!(m.generics.regions.len(subst::SelfSpace),
|
|
||||||
trait_ref.substs.regions.len(subst::SelfSpace));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Because this trait derives from a where-clause, it
|
// Because this trait derives from a where-clause, it
|
||||||
@ -755,11 +751,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
|
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
|
||||||
self.region_var_for_def(self.span, def)
|
self.region_var_for_def(self.span, def)
|
||||||
}, |def, substs| {
|
}, |def, substs| {
|
||||||
if def.space == subst::SelfSpace {
|
if def.index == 0 {
|
||||||
assert_eq!(def.index, 0);
|
|
||||||
step.self_ty
|
step.self_ty
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(def.space, subst::TypeSpace);
|
|
||||||
self.type_var_for_def(self.span, def, substs)
|
self.type_var_for_def(self.span, def, substs)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4225,7 +4225,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
|
let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
|
||||||
let i = def.index as usize;
|
let i = def.index as usize;
|
||||||
let segment = match def.space {
|
let segment = match def.space {
|
||||||
subst::SelfSpace => None,
|
|
||||||
subst::TypeSpace => type_segment,
|
subst::TypeSpace => type_segment,
|
||||||
subst::FnSpace => fn_segment
|
subst::FnSpace => fn_segment
|
||||||
};
|
};
|
||||||
@ -4241,9 +4240,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.region_var_for_def(span, def)
|
self.region_var_for_def(span, def)
|
||||||
}
|
}
|
||||||
}, |def, substs| {
|
}, |def, substs| {
|
||||||
let i = def.index as usize;
|
let mut i = def.index as usize;
|
||||||
let segment = match def.space {
|
let segment = match def.space {
|
||||||
subst::SelfSpace => None,
|
|
||||||
subst::TypeSpace => type_segment,
|
subst::TypeSpace => type_segment,
|
||||||
subst::FnSpace => fn_segment
|
subst::FnSpace => fn_segment
|
||||||
};
|
};
|
||||||
@ -4252,18 +4250,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
Some(&hir::ParenthesizedParameters(_)) => bug!(),
|
Some(&hir::ParenthesizedParameters(_)) => bug!(),
|
||||||
None => &[]
|
None => &[]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle Self first, so we can adjust the index to match the AST.
|
||||||
|
if scheme.generics.has_self && def.space == subst::TypeSpace {
|
||||||
|
if i == 0 {
|
||||||
|
return opt_self_ty.unwrap_or_else(|| {
|
||||||
|
self.type_var_for_def(span, def, substs)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
let can_omit = def.space != subst::TypeSpace || !require_type_space;
|
let can_omit = def.space != subst::TypeSpace || !require_type_space;
|
||||||
let default = if can_omit && types.len() == 0 {
|
let default = if can_omit && types.len() == 0 {
|
||||||
def.default
|
def.default
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
if let Some(ast_ty) = types.get(i) {
|
||||||
if def.space == subst::SelfSpace && opt_self_ty.is_some() {
|
|
||||||
// Self, which has been provided.
|
|
||||||
assert_eq!(i, 0);
|
|
||||||
opt_self_ty.unwrap()
|
|
||||||
} else if let Some(ast_ty) = types.get(i) {
|
|
||||||
// A provided type parameter.
|
// A provided type parameter.
|
||||||
self.to_ty(ast_ty)
|
self.to_ty(ast_ty)
|
||||||
} else if let Some(default) = default {
|
} else if let Some(default) = default {
|
||||||
@ -4371,6 +4375,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
// Check provided type parameters.
|
// Check provided type parameters.
|
||||||
let type_defs = generics.types.get_slice(space);
|
let type_defs = generics.types.get_slice(space);
|
||||||
|
let type_defs = if space == subst::TypeSpace {
|
||||||
|
&type_defs[generics.has_self as usize..]
|
||||||
|
} else {
|
||||||
|
type_defs
|
||||||
|
};
|
||||||
let required_len = type_defs.iter()
|
let required_len = type_defs.iter()
|
||||||
.take_while(|d| d.default.is_none())
|
.take_while(|d| d.default.is_none())
|
||||||
.count();
|
.count();
|
||||||
|
@ -14,13 +14,12 @@ use CrateCtxt;
|
|||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use middle::region::{CodeExtent};
|
use middle::region::{CodeExtent};
|
||||||
use rustc::infer::TypeOrigin;
|
use rustc::infer::TypeOrigin;
|
||||||
use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
|
use rustc::ty::subst;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::parse::token::keywords;
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
|
|
||||||
@ -461,7 +460,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||||||
variances.types
|
variances.types
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter(|&(_, _, &variance)| variance != ty::Bivariant)
|
.filter(|&(_, _, &variance)| variance != ty::Bivariant)
|
||||||
.map(|(space, index, _)| self.param_ty(ast_generics, space, index))
|
.map(|(_, index, _)| self.param_ty(ast_generics, index))
|
||||||
.map(|p| Parameter::Type(p))
|
.map(|p| Parameter::Type(p))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -470,52 +469,34 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||||||
&mut constrained_parameters);
|
&mut constrained_parameters);
|
||||||
|
|
||||||
for (space, index, _) in variances.types.iter_enumerated() {
|
for (space, index, _) in variances.types.iter_enumerated() {
|
||||||
let param_ty = self.param_ty(ast_generics, space, index);
|
assert_eq!(space, subst::TypeSpace);
|
||||||
|
|
||||||
|
let param_ty = self.param_ty(ast_generics, index);
|
||||||
if constrained_parameters.contains(&Parameter::Type(param_ty)) {
|
if constrained_parameters.contains(&Parameter::Type(param_ty)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let span = self.ty_param_span(ast_generics, item, space, index);
|
let span = ast_generics.ty_params[index].span;
|
||||||
self.report_bivariance(span, param_ty.name);
|
self.report_bivariance(span, param_ty.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (space, index, &variance) in variances.regions.iter_enumerated() {
|
for (space, index, &variance) in variances.regions.iter_enumerated() {
|
||||||
|
assert_eq!(space, subst::TypeSpace);
|
||||||
|
|
||||||
if variance != ty::Bivariant {
|
if variance != ty::Bivariant {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(space, TypeSpace);
|
|
||||||
let span = ast_generics.lifetimes[index].lifetime.span;
|
let span = ast_generics.lifetimes[index].lifetime.span;
|
||||||
let name = ast_generics.lifetimes[index].lifetime.name;
|
let name = ast_generics.lifetimes[index].lifetime.name;
|
||||||
self.report_bivariance(span, name);
|
self.report_bivariance(span, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_ty(&self,
|
fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy {
|
||||||
ast_generics: &hir::Generics,
|
ty::ParamTy {
|
||||||
space: ParamSpace,
|
space: subst::TypeSpace,
|
||||||
index: usize)
|
idx: index as u32,
|
||||||
-> ty::ParamTy
|
name: ast_generics.ty_params[index].name
|
||||||
{
|
|
||||||
let name = match space {
|
|
||||||
TypeSpace => ast_generics.ty_params[index].name,
|
|
||||||
SelfSpace => keywords::SelfType.name(),
|
|
||||||
FnSpace => bug!("Fn space occupied?"),
|
|
||||||
};
|
|
||||||
|
|
||||||
ty::ParamTy { space: space, idx: index as u32, name: name }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ty_param_span(&self,
|
|
||||||
ast_generics: &hir::Generics,
|
|
||||||
item: &hir::Item,
|
|
||||||
space: ParamSpace,
|
|
||||||
index: usize)
|
|
||||||
-> Span
|
|
||||||
{
|
|
||||||
match space {
|
|
||||||
TypeSpace => ast_generics.ty_params[index].span,
|
|
||||||
SelfSpace => item.span,
|
|
||||||
FnSpace => span_bug!(item.span, "Fn space occupied?"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
|||||||
|
|
||||||
let source = tcx.lookup_item_type(impl_did).ty;
|
let source = tcx.lookup_item_type(impl_did).ty;
|
||||||
let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
|
let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
|
||||||
let target = *trait_ref.substs.types.get(subst::TypeSpace, 0);
|
let target = *trait_ref.substs.types.get(subst::TypeSpace, 1);
|
||||||
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
|
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
|
||||||
source, target);
|
source, target);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem;
|
|||||||
use middle::const_val::ConstVal;
|
use middle::const_val::ConstVal;
|
||||||
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
||||||
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
|
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
|
||||||
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
|
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace, VecPerParamSpace};
|
||||||
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
||||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
||||||
use rustc::ty::{VariantKind};
|
use rustc::ty::{VariantKind};
|
||||||
@ -85,7 +85,6 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use syntax::{abi, ast, attr};
|
use syntax::{abi, ast, attr};
|
||||||
use syntax::parse::token::keywords;
|
use syntax::parse::token::keywords;
|
||||||
use syntax::ptr::P;
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
|
use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
|
||||||
@ -546,7 +545,7 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
let path_res = tcx.expect_resolution(ast_ty.id);
|
let path_res = tcx.expect_resolution(ast_ty.id);
|
||||||
match path_res.base_def {
|
match path_res.base_def {
|
||||||
Def::SelfTy(Some(def_id), None) |
|
Def::SelfTy(Some(def_id), None) |
|
||||||
Def::TyParam(_, _, def_id, _) if path_res.depth == 0 => {
|
Def::TyParam(def_id) if path_res.depth == 0 => {
|
||||||
def_id == tcx.map.local_def_id(param_id)
|
def_id == tcx.map.local_def_id(param_id)
|
||||||
}
|
}
|
||||||
_ => false
|
_ => false
|
||||||
@ -1333,7 +1332,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
|
|||||||
|
|
||||||
// add in the explicit where-clauses
|
// add in the explicit where-clauses
|
||||||
let mut trait_predicates =
|
let mut trait_predicates =
|
||||||
ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates);
|
ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates, true);
|
||||||
|
|
||||||
let assoc_predicates = predicates_for_associated_types(ccx,
|
let assoc_predicates = predicates_for_associated_types(ccx,
|
||||||
generics,
|
generics,
|
||||||
@ -1430,7 +1429,7 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
let parent = ccx.tcx.map.get_parent(param_id);
|
let parent = ccx.tcx.map.get_parent(param_id);
|
||||||
|
|
||||||
let def = ty::TypeParameterDef {
|
let def = ty::TypeParameterDef {
|
||||||
space: SelfSpace,
|
space: TypeSpace,
|
||||||
index: 0,
|
index: 0,
|
||||||
name: keywords::SelfType.name(),
|
name: keywords::SelfType.name(),
|
||||||
def_id: tcx.map.local_def_id(param_id),
|
def_id: tcx.map.local_def_id(param_id),
|
||||||
@ -1477,27 +1476,25 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
// Now create the real type parameters.
|
// Now create the real type parameters.
|
||||||
let types = ast_generics.ty_params.iter().enumerate().map(|(i, _)| {
|
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
|
||||||
get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32, allow_defaults)
|
let i = opt_self.is_some() as u32 + i as u32;
|
||||||
|
get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
let has_self = base_generics.has_self || opt_self.is_some();
|
let has_self = base_generics.has_self || opt_self.is_some();
|
||||||
let (regions, types) = match space {
|
let (regions, types) = match space {
|
||||||
SelfSpace => bug!(),
|
|
||||||
TypeSpace => {
|
TypeSpace => {
|
||||||
assert_eq!(base_generics.regions.as_full_slice().len(), 0);
|
assert_eq!(base_generics.regions.as_full_slice().len(), 0);
|
||||||
assert_eq!(base_generics.types.as_full_slice().len(), 0);
|
assert_eq!(base_generics.types.as_full_slice().len(), 0);
|
||||||
(VecPerParamSpace::new(vec![], regions, vec![]),
|
(VecPerParamSpace::new(regions, vec![]),
|
||||||
VecPerParamSpace::new(opt_self.into_iter().collect(), types, vec![]))
|
VecPerParamSpace::new(opt_self.into_iter().chain(types).collect(), vec![]))
|
||||||
}
|
}
|
||||||
FnSpace => {
|
FnSpace => {
|
||||||
assert_eq!(base_generics.regions.len(FnSpace), 0);
|
assert_eq!(base_generics.regions.len(FnSpace), 0);
|
||||||
assert_eq!(base_generics.types.len(FnSpace), 0);
|
assert_eq!(base_generics.types.len(FnSpace), 0);
|
||||||
(VecPerParamSpace::new(base_generics.regions.get_slice(SelfSpace).to_vec(),
|
(VecPerParamSpace::new(base_generics.regions.get_slice(TypeSpace).to_vec(),
|
||||||
base_generics.regions.get_slice(TypeSpace).to_vec(),
|
|
||||||
regions),
|
regions),
|
||||||
VecPerParamSpace::new(base_generics.types.get_slice(SelfSpace).to_vec(),
|
VecPerParamSpace::new(base_generics.types.get_slice(TypeSpace).to_vec(),
|
||||||
base_generics.types.get_slice(TypeSpace).to_vec(),
|
|
||||||
types))
|
types))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1674,7 +1671,7 @@ fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||||||
generics: &hir::Generics)
|
generics: &hir::Generics)
|
||||||
-> ty::GenericPredicates<'tcx>
|
-> ty::GenericPredicates<'tcx>
|
||||||
{
|
{
|
||||||
ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty())
|
ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||||
@ -1682,7 +1679,7 @@ fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||||||
base_predicates: &ty::GenericPredicates<'tcx>)
|
base_predicates: &ty::GenericPredicates<'tcx>)
|
||||||
-> ty::GenericPredicates<'tcx>
|
-> ty::GenericPredicates<'tcx>
|
||||||
{
|
{
|
||||||
ty_generic_predicates(ccx, FnSpace, generics, base_predicates)
|
ty_generic_predicates(ccx, FnSpace, generics, base_predicates, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
|
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
|
||||||
@ -1752,7 +1749,8 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>(
|
|||||||
fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||||
space: ParamSpace,
|
space: ParamSpace,
|
||||||
ast_generics: &hir::Generics,
|
ast_generics: &hir::Generics,
|
||||||
base_predicates: &ty::GenericPredicates<'tcx>)
|
base_predicates: &ty::GenericPredicates<'tcx>,
|
||||||
|
has_self: bool)
|
||||||
-> ty::GenericPredicates<'tcx>
|
-> ty::GenericPredicates<'tcx>
|
||||||
{
|
{
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
@ -1761,7 +1759,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||||||
// Collect the predicates that were written inline by the user on each
|
// Collect the predicates that were written inline by the user on each
|
||||||
// type parameter (e.g., `<T:Foo>`).
|
// type parameter (e.g., `<T:Foo>`).
|
||||||
for (index, param) in ast_generics.ty_params.iter().enumerate() {
|
for (index, param) in ast_generics.ty_params.iter().enumerate() {
|
||||||
let index = index as u32;
|
let index = has_self as u32 + index as u32;
|
||||||
let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
|
let param_ty = ty::ParamTy::new(space, index, param.name).to_ty(ccx.tcx);
|
||||||
let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
|
let bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
|
||||||
param_ty,
|
param_ty,
|
||||||
@ -1850,50 +1848,22 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|
||||||
path: &P<hir::Ty>,
|
|
||||||
space: ParamSpace,
|
|
||||||
index: u32)
|
|
||||||
-> Ty<'tcx>
|
|
||||||
{
|
|
||||||
let ty = AstConv::ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
|
|
||||||
|
|
||||||
for leaf_ty in ty.walk() {
|
|
||||||
if let ty::TyParam(p) = leaf_ty.sty {
|
|
||||||
if p.space == space && p.idx >= index {
|
|
||||||
struct_span_err!(ccx.tcx.sess, path.span, E0128,
|
|
||||||
"type parameters with a default cannot use \
|
|
||||||
forward declared identifiers")
|
|
||||||
.span_label(path.span, &format!("defaulted type parameters \
|
|
||||||
cannot be forward declared"))
|
|
||||||
.emit();
|
|
||||||
|
|
||||||
return ccx.tcx.types.err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ty
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||||
ast_generics: &hir::Generics,
|
ast_generics: &hir::Generics,
|
||||||
space: ParamSpace,
|
space: ParamSpace,
|
||||||
index: u32,
|
index: u32,
|
||||||
|
param: &hir::TyParam,
|
||||||
allow_defaults: bool)
|
allow_defaults: bool)
|
||||||
-> ty::TypeParameterDef<'tcx>
|
-> ty::TypeParameterDef<'tcx>
|
||||||
{
|
{
|
||||||
let param = &ast_generics.ty_params[index as usize];
|
|
||||||
|
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
match tcx.ty_param_defs.borrow().get(¶m.id) {
|
match tcx.ty_param_defs.borrow().get(¶m.id) {
|
||||||
Some(d) => { return d.clone(); }
|
Some(d) => { return d.clone(); }
|
||||||
None => { }
|
None => { }
|
||||||
}
|
}
|
||||||
|
|
||||||
let default = param.default.as_ref().map(
|
let default =
|
||||||
|def| convert_default_type_parameter(ccx, def, space, index)
|
param.default.as_ref().map(|def| ccx.icx(&()).to_ty(&ExplicitRscope, def));
|
||||||
);
|
|
||||||
|
|
||||||
let object_lifetime_default =
|
let object_lifetime_default =
|
||||||
compute_object_lifetime_default(ccx, param.id,
|
compute_object_lifetime_default(ccx, param.id,
|
||||||
@ -1922,6 +1892,10 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
|||||||
object_lifetime_default: object_lifetime_default,
|
object_lifetime_default: object_lifetime_default,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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());
|
tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
|
||||||
|
|
||||||
debug!("get_or_create_type_parameter_def: def for type param: {:?}, {:?}",
|
debug!("get_or_create_type_parameter_def: def for type param: {:?}, {:?}",
|
||||||
@ -2153,7 +2127,7 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
|||||||
|
|
||||||
/// Checks that all the type parameters on an impl
|
/// Checks that all the type parameters on an impl
|
||||||
fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
ast_generics: &hir::Generics,
|
generics: &hir::Generics,
|
||||||
impl_predicates: &mut ty::GenericPredicates<'tcx>,
|
impl_predicates: &mut ty::GenericPredicates<'tcx>,
|
||||||
impl_def_id: DefId)
|
impl_def_id: DefId)
|
||||||
{
|
{
|
||||||
@ -2173,12 +2147,11 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
impl_trait_ref,
|
impl_trait_ref,
|
||||||
&mut input_parameters);
|
&mut input_parameters);
|
||||||
|
|
||||||
for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
|
let ty_generics = generics_of_def_id(ccx, impl_def_id);
|
||||||
let param_ty = ty::ParamTy { space: TypeSpace,
|
for (ty_param, param) in ty_generics.types.as_full_slice().iter().zip(&generics.ty_params) {
|
||||||
idx: index as u32,
|
let param_ty = ty::ParamTy::for_def(ty_param);
|
||||||
name: ty_param.name };
|
|
||||||
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
|
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
|
||||||
report_unused_parameter(ccx, ty_param.span, "type", ¶m_ty.to_string());
|
report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,9 +361,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
|
|
||||||
// All type parameters on enums and structs should be
|
// All type parameters on enums and structs should be
|
||||||
// in the TypeSpace.
|
// in the TypeSpace.
|
||||||
assert!(item_type.generics.types.is_empty_in(subst::SelfSpace));
|
|
||||||
assert!(item_type.generics.types.is_empty_in(subst::FnSpace));
|
assert!(item_type.generics.types.is_empty_in(subst::FnSpace));
|
||||||
assert!(item_type.generics.regions.is_empty_in(subst::SelfSpace));
|
|
||||||
assert!(item_type.generics.regions.is_empty_in(subst::FnSpace));
|
assert!(item_type.generics.regions.is_empty_in(subst::FnSpace));
|
||||||
|
|
||||||
self.add_constraints_from_substs(
|
self.add_constraints_from_substs(
|
||||||
@ -394,14 +392,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::TyTrait(ref data) => {
|
ty::TyTrait(ref data) => {
|
||||||
let poly_trait_ref =
|
|
||||||
data.principal.with_self_ty(self.tcx(), self.tcx().types.err);
|
|
||||||
|
|
||||||
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
|
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
|
||||||
let contra = self.contravariant(variance);
|
let contra = self.contravariant(variance);
|
||||||
self.add_constraints_from_region(generics, data.region_bound, contra);
|
self.add_constraints_from_region(generics, data.region_bound, contra);
|
||||||
|
|
||||||
// Ignore the SelfSpace, it is erased.
|
let poly_trait_ref =
|
||||||
|
data.principal.with_self_ty(self.tcx(), self.tcx().types.err);
|
||||||
self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
|
self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
|
||||||
|
|
||||||
for projection in &data.projection_bounds {
|
for projection in &data.projection_bounds {
|
||||||
|
@ -110,8 +110,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||||||
while index < num_inferred {
|
while index < num_inferred {
|
||||||
let item_id = inferred_infos[index].item_id;
|
let item_id = inferred_infos[index].item_id;
|
||||||
|
|
||||||
let (mut rs, mut rt, mut rf) = (vec![], vec![], vec![]);
|
let (mut rt, mut rf) = (vec![], vec![]);
|
||||||
let (mut ts, mut tt, mut tf) = (vec![], vec![], vec![]);
|
let (mut tt, mut tf) = (vec![], vec![]);
|
||||||
|
|
||||||
while index < num_inferred && inferred_infos[index].item_id == item_id {
|
while index < num_inferred && inferred_infos[index].item_id == item_id {
|
||||||
let info = &inferred_infos[index];
|
let info = &inferred_infos[index];
|
||||||
@ -121,7 +121,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||||||
match info.kind {
|
match info.kind {
|
||||||
TypeParam => {
|
TypeParam => {
|
||||||
let types = match info.space {
|
let types = match info.space {
|
||||||
subst::SelfSpace => &mut ts,
|
|
||||||
subst::TypeSpace => &mut tt,
|
subst::TypeSpace => &mut tt,
|
||||||
subst::FnSpace => &mut tf
|
subst::FnSpace => &mut tf
|
||||||
};
|
};
|
||||||
@ -130,7 +129,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
RegionParam => {
|
RegionParam => {
|
||||||
let regions = match info.space {
|
let regions = match info.space {
|
||||||
subst::SelfSpace => &mut rs,
|
|
||||||
subst::TypeSpace => &mut rt,
|
subst::TypeSpace => &mut rt,
|
||||||
subst::FnSpace => &mut rf
|
subst::FnSpace => &mut rf
|
||||||
};
|
};
|
||||||
@ -143,8 +141,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let item_variances = ty::ItemVariances {
|
let item_variances = ty::ItemVariances {
|
||||||
regions: subst::VecPerParamSpace::new(rs, rt, rf),
|
regions: subst::VecPerParamSpace::new(rt, rf),
|
||||||
types: subst::VecPerParamSpace::new(ts, tt, tf)
|
types: subst::VecPerParamSpace::new(tt, tf)
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("item_id={} item_variances={:?}",
|
debug!("item_id={} item_variances={:?}",
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
use dep_graph::DepTrackingMapConfig;
|
use dep_graph::DepTrackingMapConfig;
|
||||||
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace};
|
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::ty::maps::ItemVariances;
|
use rustc::ty::maps::ItemVariances;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -164,16 +164,16 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
|||||||
|
|
||||||
let inferreds_on_entry = self.num_inferred();
|
let inferreds_on_entry = self.num_inferred();
|
||||||
|
|
||||||
if has_self {
|
|
||||||
self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, p) in generics.lifetimes.iter().enumerate() {
|
for (i, p) in generics.lifetimes.iter().enumerate() {
|
||||||
let id = p.lifetime.id;
|
let id = p.lifetime.id;
|
||||||
self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
|
self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if has_self {
|
||||||
|
self.add_inferred(item_id, TypeParam, TypeSpace, 0, item_id);
|
||||||
|
}
|
||||||
for (i, p) in generics.ty_params.iter().enumerate() {
|
for (i, p) in generics.ty_params.iter().enumerate() {
|
||||||
|
let i = has_self as usize + i;
|
||||||
self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
|
self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
|||||||
-> ty::Variance
|
-> ty::Variance
|
||||||
{
|
{
|
||||||
match space {
|
match space {
|
||||||
SelfSpace | FnSpace => {
|
FnSpace => {
|
||||||
ty::Bivariant
|
ty::Bivariant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ use rustc::hir::def::Def;
|
|||||||
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
||||||
use rustc::hir::fold::Folder;
|
use rustc::hir::fold::Folder;
|
||||||
use rustc::hir::print as pprust;
|
use rustc::hir::print as pprust;
|
||||||
use rustc::ty::subst::{self, ParamSpace, Substs, VecPerParamSpace};
|
use rustc::ty::subst::{self, Substs, VecPerParamSpace};
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::middle::stability;
|
use rustc::middle::stability;
|
||||||
|
|
||||||
@ -630,13 +630,14 @@ impl Clean<TyParamBound> for hir::TyParamBound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>,
|
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
|
||||||
bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
|
bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
|
||||||
let lifetimes = substs.regions.get_slice(subst::TypeSpace)
|
let lifetimes = substs.regions.get_slice(subst::TypeSpace)
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|v| v.clean(cx))
|
.filter_map(|v| v.clean(cx))
|
||||||
.collect();
|
.collect();
|
||||||
let types = substs.types.get_slice(subst::TypeSpace).to_vec();
|
let types = substs.types.get_slice(subst::TypeSpace);
|
||||||
|
let types = types[has_self as usize..].to_vec();
|
||||||
|
|
||||||
match (trait_did, cx.tcx_opt()) {
|
match (trait_did, cx.tcx_opt()) {
|
||||||
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
||||||
@ -675,13 +676,13 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>,
|
|||||||
|
|
||||||
// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
|
// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
|
||||||
// from Fn<(A, B,), C> to Fn(A, B) -> C
|
// from Fn<(A, B,), C> to Fn(A, B) -> C
|
||||||
fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>,
|
fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self: bool,
|
||||||
bindings: Vec<TypeBinding>, substs: &Substs) -> Path {
|
bindings: Vec<TypeBinding>, substs: &Substs) -> Path {
|
||||||
Path {
|
Path {
|
||||||
global: false,
|
global: false,
|
||||||
segments: vec![PathSegment {
|
segments: vec![PathSegment {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
params: external_path_params(cx, trait_did, bindings, substs)
|
params: external_path_params(cx, trait_did, has_self, bindings, substs)
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,16 +697,16 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
|
|||||||
let (did, path) = match *self {
|
let (did, path) = match *self {
|
||||||
ty::BoundSend =>
|
ty::BoundSend =>
|
||||||
(tcx.lang_items.send_trait().unwrap(),
|
(tcx.lang_items.send_trait().unwrap(),
|
||||||
external_path(cx, "Send", None, vec![], empty)),
|
external_path(cx, "Send", None, false, vec![], empty)),
|
||||||
ty::BoundSized =>
|
ty::BoundSized =>
|
||||||
(tcx.lang_items.sized_trait().unwrap(),
|
(tcx.lang_items.sized_trait().unwrap(),
|
||||||
external_path(cx, "Sized", None, vec![], empty)),
|
external_path(cx, "Sized", None, false, vec![], empty)),
|
||||||
ty::BoundCopy =>
|
ty::BoundCopy =>
|
||||||
(tcx.lang_items.copy_trait().unwrap(),
|
(tcx.lang_items.copy_trait().unwrap(),
|
||||||
external_path(cx, "Copy", None, vec![], empty)),
|
external_path(cx, "Copy", None, false, vec![], empty)),
|
||||||
ty::BoundSync =>
|
ty::BoundSync =>
|
||||||
(tcx.lang_items.sync_trait().unwrap(),
|
(tcx.lang_items.sync_trait().unwrap(),
|
||||||
external_path(cx, "Sync", None, vec![], empty)),
|
external_path(cx, "Sync", None, false, vec![], empty)),
|
||||||
};
|
};
|
||||||
inline::record_extern_fqn(cx, did, TypeTrait);
|
inline::record_extern_fqn(cx, did, TypeTrait);
|
||||||
TraitBound(PolyTrait {
|
TraitBound(PolyTrait {
|
||||||
@ -728,14 +729,14 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
|||||||
};
|
};
|
||||||
inline::record_extern_fqn(cx, self.def_id, TypeTrait);
|
inline::record_extern_fqn(cx, self.def_id, TypeTrait);
|
||||||
let path = external_path(cx, &tcx.item_name(self.def_id).as_str(),
|
let path = external_path(cx, &tcx.item_name(self.def_id).as_str(),
|
||||||
Some(self.def_id), vec![], self.substs);
|
Some(self.def_id), true, vec![], self.substs);
|
||||||
|
|
||||||
debug!("ty::TraitRef\n substs.types(TypeSpace): {:?}\n",
|
debug!("ty::TraitRef\n substs.types(TypeSpace): {:?}\n",
|
||||||
self.substs.types.get_slice(ParamSpace::TypeSpace));
|
&self.input_types()[1..]);
|
||||||
|
|
||||||
// collect any late bound regions
|
// collect any late bound regions
|
||||||
let mut late_bounds = vec![];
|
let mut late_bounds = vec![];
|
||||||
for &ty_s in self.substs.types.get_slice(ParamSpace::TypeSpace) {
|
for &ty_s in &self.input_types()[1..] {
|
||||||
if let ty::TyTuple(ts) = ty_s.sty {
|
if let ty::TyTuple(ts) = ty_s.sty {
|
||||||
for &ty_s in ts {
|
for &ty_s in ts {
|
||||||
if let ty::TyRef(ref reg, _) = ty_s.sty {
|
if let ty::TyRef(ref reg, _) = ty_s.sty {
|
||||||
@ -982,8 +983,13 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
|
|||||||
// Bounds in the type_params and lifetimes fields are repeated in the
|
// Bounds in the type_params and lifetimes fields are repeated in the
|
||||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||||
// them.
|
// them.
|
||||||
let stripped_typarams = gens.types.get_slice(space).iter().map(|tp| {
|
let stripped_typarams = gens.types.get_slice(space).iter().filter_map(|tp| {
|
||||||
tp.clean(cx)
|
if tp.name == keywords::SelfType.name() {
|
||||||
|
assert_eq!(tp.index, 0);
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(tp.clean(cx))
|
||||||
|
}
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| {
|
let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| {
|
||||||
let mut srp = rp.clone();
|
let mut srp = rp.clone();
|
||||||
@ -1820,7 +1826,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||||||
};
|
};
|
||||||
inline::record_extern_fqn(cx, did, kind);
|
inline::record_extern_fqn(cx, did, kind);
|
||||||
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
|
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
|
||||||
None, vec![], substs);
|
None, false, vec![], substs);
|
||||||
ResolvedPath {
|
ResolvedPath {
|
||||||
path: path,
|
path: path,
|
||||||
typarams: None,
|
typarams: None,
|
||||||
@ -1847,7 +1853,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
|
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
|
||||||
Some(did), bindings, obj.principal.0.substs);
|
Some(did), false, bindings, obj.principal.0.substs);
|
||||||
ResolvedPath {
|
ResolvedPath {
|
||||||
path: path,
|
path: path,
|
||||||
typarams: Some(typarams),
|
typarams: Some(typarams),
|
||||||
|
@ -8,15 +8,13 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
// error-pattern: overflow representing the type `S`
|
// error-pattern: overflow representing the type
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
|
||||||
|
|
||||||
trait Mirror { type It: ?Sized; }
|
trait Mirror { type It: ?Sized; }
|
||||||
impl<T: ?Sized> Mirror for T { type It = Self; }
|
impl<T: ?Sized> Mirror for T { type It = Self; }
|
||||||
struct S(Option<<S as Mirror>::It>);
|
struct S(Option<<S as Mirror>::It>);
|
||||||
|
|
||||||
#[rustc_no_mir] // FIXME #27840 MIR tries to represent `std::option::Option<S>` first.
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _s = S(None);
|
let _s = S(None);
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,7 @@
|
|||||||
|
|
||||||
#![feature(default_type_parameter_fallback)]
|
#![feature(default_type_parameter_fallback)]
|
||||||
|
|
||||||
fn avg<T=T::Item>(_: T) {} //~ ERROR associated type `Item` not found for `T`
|
fn avg<T=T::Item>(_: T) {}
|
||||||
|
//~^ ERROR type parameters with a default cannot use forward declared identifiers
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -20,12 +20,12 @@ trait Trait<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[];[+];[]], regions=[[];[-];[]])
|
struct Foo<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[+];[]], regions=[[-];[]])
|
||||||
field: (T, &'a ())
|
field: (T, &'a ())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[];[o];[]], regions=[[];[o];[]])
|
struct Bar<'a, T : Trait<'a>> { //~ ERROR ItemVariances(types=[[o];[]], regions=[[o];[]])
|
||||||
field: <T as Trait<'a>>::Type
|
field: <T as Trait<'a>>::Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use std::cell::Cell;
|
|||||||
// For better or worse, associated types are invariant, and hence we
|
// For better or worse, associated types are invariant, and hence we
|
||||||
// get an invariant result for `'a`.
|
// get an invariant result for `'a`.
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Foo<'a> { //~ ERROR regions=[[];[o];[]]
|
struct Foo<'a> { //~ ERROR regions=[[o];[]]
|
||||||
x: Box<Fn(i32) -> &'a i32 + 'static>
|
x: Box<Fn(i32) -> &'a i32 + 'static>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait Foo: 'static { //~ ERROR types=[[o];[];[]]
|
trait Foo: 'static { //~ ERROR types=[[o];[]]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait Bar<T> { //~ ERROR types=[[o];[o];[]]
|
trait Bar<T> { //~ ERROR types=[[o, o];[]]
|
||||||
fn do_it(&self)
|
fn do_it(&self)
|
||||||
where T: 'static;
|
where T: 'static;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,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 isize,
|
x: &'a isize,
|
||||||
y: &'b [isize],
|
y: &'b [isize],
|
||||||
c: &'c str
|
c: &'c str
|
||||||
@ -25,7 +25,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 isize),
|
x: extern "Rust" fn(&'a isize),
|
||||||
y: extern "Rust" fn(&'b [isize]),
|
y: extern "Rust" fn(&'b [isize]),
|
||||||
c: extern "Rust" fn(&'c str),
|
c: extern "Rust" fn(&'c str),
|
||||||
@ -34,7 +34,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 isize,
|
x: &'a mut &'b isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[[];[-, o];[]]
|
|||||||
// contravariant context:
|
// contravariant context:
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Test5<'a, 'b:'a> { //~ ERROR regions=[[];[+, o];[]]
|
struct Test5<'a, 'b:'a> { //~ ERROR regions=[[+, o];[]]
|
||||||
x: extern "Rust" fn(&'a mut &'b isize),
|
x: extern "Rust" fn(&'a mut &'b isize),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,14 +52,14 @@ struct Test5<'a, 'b:'a> { //~ 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:'a> { //~ ERROR regions=[[];[-, o];[]]
|
struct Test6<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]]
|
||||||
x: &'a mut extern "Rust" fn(&'b isize),
|
x: &'a mut extern "Rust" fn(&'b isize),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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=[[*];[]]
|
||||||
//~^ ERROR parameter `'a` is never used
|
//~^ ERROR parameter `'a` is never used
|
||||||
x: isize
|
x: isize
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ struct Test7<'a> { //~ ERROR regions=[[];[*];[]]
|
|||||||
// 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 isize)),
|
Test8A(extern "Rust" fn(&'a isize)),
|
||||||
Test8B(&'b [isize]),
|
Test8B(&'b [isize]),
|
||||||
Test8C(&'b mut &'c str),
|
Test8C(&'b mut &'c str),
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[];[+, -, o, *];[]]
|
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[]]
|
||||||
//~^ ERROR parameter `'d` is never used
|
//~^ ERROR parameter `'d` is never used
|
||||||
Test8A(extern "Rust" fn(&'a isize)),
|
Test8A(extern "Rust" fn(&'a isize)),
|
||||||
Test8B(&'b [isize]),
|
Test8B(&'b [isize]),
|
||||||
@ -23,25 +23,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[];[+, -, o, *];[]]
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[];[*, o, -, +];[]]
|
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[]]
|
||||||
//~^ ERROR parameter `'w` is never used
|
//~^ ERROR parameter `'w` is never used
|
||||||
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, *];[]]
|
||||||
//~^ ERROR parameter `'c` is never used
|
//~^ ERROR parameter `'c` is never used
|
||||||
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, -, *];[]]
|
||||||
//~^ ERROR parameter `'c` is never used
|
//~^ ERROR parameter `'c` is never used
|
||||||
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>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,48 +15,48 @@
|
|||||||
// influence variance.
|
// influence variance.
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait Getter<T> { //~ ERROR types=[[o];[o];[]]
|
trait Getter<T> { //~ ERROR types=[[o, o];[]]
|
||||||
fn get(&self) -> T;
|
fn get(&self) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait Setter<T> { //~ ERROR types=[[o];[o];[]]
|
trait Setter<T> { //~ ERROR types=[[o, o];[]]
|
||||||
fn get(&self, T);
|
fn get(&self, T);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[];[+, +];[]]
|
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[]]
|
||||||
t: T, u: U
|
t: T, u: U
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[];[*, +];[]]
|
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[]]
|
||||||
//~^ ERROR parameter `U` is never used
|
//~^ ERROR parameter `U` is never used
|
||||||
Foo(T)
|
Foo(T)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[o];[o, o];[]]
|
trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[o, o, o];[]]
|
||||||
fn getter(&self, u: U) -> T;
|
fn getter(&self, u: U) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[o];[o];[]]
|
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[o, o];[]]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait TestTrait3<U> { //~ ERROR types=[[o];[o];[]]
|
trait TestTrait3<U> { //~ ERROR types=[[o, o];[]]
|
||||||
fn getter<T:Getter<U>>(&self);
|
fn getter<T:Getter<U>>(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[];[*, +];[]]
|
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[]]
|
||||||
//~^ ERROR parameter `U` is never used
|
//~^ ERROR parameter `U` is never used
|
||||||
t: T
|
t: T
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[];[*, +];[]]
|
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[*, +];[]]
|
||||||
//~^ ERROR parameter `U` is never used
|
//~^ ERROR parameter `U` is never used
|
||||||
t: T
|
t: T
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ use std::mem;
|
|||||||
trait T { fn foo(&self); }
|
trait T { fn foo(&self); }
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TOption<'a> { //~ ERROR regions=[[];[-];[]]
|
struct TOption<'a> { //~ ERROR regions=[[-];[]]
|
||||||
v: Option<Box<T + 'a>>,
|
v: Option<Box<T + 'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,46 +14,46 @@
|
|||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestImm<A, B> { //~ ERROR types=[[];[+, +];[]]
|
struct TestImm<A, B> { //~ ERROR types=[[+, +];[]]
|
||||||
x: A,
|
x: A,
|
||||||
y: B,
|
y: B,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestMut<A, B:'static> { //~ ERROR types=[[];[+, o];[]]
|
struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[]]
|
||||||
x: A,
|
x: A,
|
||||||
y: &'static mut B,
|
y: &'static mut B,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[];[+, o];[]]
|
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[]]
|
||||||
m: TestMut<A, B>
|
m: TestMut<A, B>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[];[o, o];[]]
|
struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[]]
|
||||||
n: TestMut<A, B>,
|
n: TestMut<A, B>,
|
||||||
m: TestMut<B, A>
|
m: TestMut<B, A>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait Getter<A> { //~ ERROR types=[[o];[o];[]]
|
trait Getter<A> { //~ ERROR types=[[o, o];[]]
|
||||||
fn get(&self) -> A;
|
fn get(&self) -> A;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait Setter<A> { //~ ERROR types=[[o];[o];[]]
|
trait Setter<A> { //~ ERROR types=[[o, o];[]]
|
||||||
fn set(&mut self, a: A);
|
fn set(&mut self, a: A);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
|
trait GetterSetter<A> { //~ ERROR types=[[o, o];[]]
|
||||||
fn get(&self) -> A;
|
fn get(&self) -> A;
|
||||||
fn set(&mut self, a: A);
|
fn set(&mut self, a: A);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait GetterInTypeBound<A> { //~ ERROR types=[[o];[o];[]]
|
trait GetterInTypeBound<A> { //~ ERROR types=[[o, o];[]]
|
||||||
// Here, the use of `A` in the method bound *does* affect
|
// Here, the use of `A` in the method bound *does* affect
|
||||||
// variance. Think of it as if the method requested a dictionary
|
// variance. Think of it as if the method requested a dictionary
|
||||||
// for `T:Getter<A>`. Since this dictionary is an input, it is
|
// for `T:Getter<A>`. Since this dictionary is an input, it is
|
||||||
@ -63,12 +63,12 @@ trait GetterInTypeBound<A> { //~ ERROR types=[[o];[o];[]]
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
trait SetterInTypeBound<A> { //~ ERROR types=[[o];[o];[]]
|
trait SetterInTypeBound<A> { //~ ERROR types=[[o, o];[]]
|
||||||
fn do_it<T:Setter<A>>(&self);
|
fn do_it<T:Setter<A>>(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct TestObject<A, R> { //~ ERROR types=[[];[o, o];[]]
|
struct TestObject<A, R> { //~ ERROR types=[[o, o];[]]
|
||||||
n: Box<Setter<A>+Send>,
|
n: Box<Setter<A>+Send>,
|
||||||
m: Box<Getter<R>+Send>,
|
m: Box<Getter<R>+Send>,
|
||||||
}
|
}
|
||||||
|
@ -17,32 +17,32 @@ use std::cell::Cell;
|
|||||||
// not considered bivariant.
|
// not considered bivariant.
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[];[o, o];[]], regions=[[];[-];[]]
|
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[]], regions=[[-];[]]
|
||||||
t: &'a mut (A,B)
|
t: &'a mut (A,B)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct InvariantCell<A> { //~ ERROR types=[[];[o];[]]
|
struct InvariantCell<A> { //~ ERROR types=[[o];[]]
|
||||||
t: Cell<A>
|
t: Cell<A>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct InvariantIndirect<A> { //~ ERROR types=[[];[o];[]]
|
struct InvariantIndirect<A> { //~ ERROR types=[[o];[]]
|
||||||
t: InvariantCell<A>
|
t: InvariantCell<A>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Covariant<A> { //~ ERROR types=[[];[+];[]]
|
struct Covariant<A> { //~ ERROR types=[[+];[]]
|
||||||
t: A, u: fn() -> A
|
t: A, u: fn() -> A
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
struct Contravariant<A> { //~ ERROR types=[[];[-];[]]
|
struct Contravariant<A> { //~ ERROR types=[[-];[]]
|
||||||
t: fn(A)
|
t: fn(A)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_variance]
|
#[rustc_variance]
|
||||||
enum Enum<A,B,C> { //~ ERROR types=[[];[+, -, o];[]]
|
enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[]]
|
||||||
Foo(Covariant<A>),
|
Foo(Covariant<A>),
|
||||||
Bar(Contravariant<B>),
|
Bar(Contravariant<B>),
|
||||||
Zed(Covariant<C>,Contravariant<C>)
|
Zed(Covariant<C>,Contravariant<C>)
|
||||||
|
Loading…
Reference in New Issue
Block a user