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.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::ParamSpace;
|
||||
use util::nodemap::NodeMap;
|
||||
use syntax::ast;
|
||||
use hir;
|
||||
@ -31,7 +30,7 @@ pub enum Def {
|
||||
AssociatedTy(DefId /* trait */, DefId),
|
||||
Trait(DefId),
|
||||
PrimTy(hir::PrimTy),
|
||||
TyParam(ParamSpace, u32, DefId, ast::Name),
|
||||
TyParam(DefId),
|
||||
Upvar(DefId, // def id of closed over local
|
||||
ast::NodeId, // node id of closed over local
|
||||
usize, // index in the freevars list of the closure
|
||||
@ -122,7 +121,7 @@ impl Def {
|
||||
match *self {
|
||||
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::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::Local(id, _) | Def::Upvar(id, _, _, _) => {
|
||||
id
|
||||
|
@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
|
||||
if self.tcx.trait_of_item(def.def_id()).is_some() => {
|
||||
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, _) => {
|
||||
self.check_def_id(tyid.did)
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ use super::{SelectionContext, Obligation, ObligationCause};
|
||||
|
||||
use middle::cstore::LOCAL_CRATE;
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::TypeSpace;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use infer::{InferCtxt, TypeOrigin};
|
||||
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
|
||||
// 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
|
||||
// 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) {
|
||||
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) {
|
||||
self_match_impls.push(def_id);
|
||||
|
||||
if trait_ref.substs.types.get_slice(TypeSpace).iter()
|
||||
.zip(impl_trait_ref.substs.types.get_slice(TypeSpace))
|
||||
if trait_ref.substs.types.get_slice(TypeSpace)[1..].iter()
|
||||
.zip(&impl_trait_ref.substs.types.get_slice(TypeSpace)[1..])
|
||||
.all(|(u,v)| self.fuzzy_match_tys(u, v))
|
||||
{
|
||||
fuzzy_match_impls.push(def_id);
|
||||
|
@ -20,7 +20,7 @@
|
||||
use super::elaborate_predicates;
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::{self, SelfSpace, TypeSpace};
|
||||
use ty::subst;
|
||||
use traits;
|
||||
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||
use std::rc::Rc;
|
||||
@ -146,10 +146,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
match predicate {
|
||||
ty::Predicate::Trait(ref data) => {
|
||||
// In the case of a trait predicate, we can skip the "self" type.
|
||||
data.0.trait_ref.substs.types.get_slice(TypeSpace)
|
||||
.iter()
|
||||
.cloned()
|
||||
.any(|t| t.has_self_ty())
|
||||
data.0.trait_ref.input_types()[1..].iter().any(|t| t.has_self_ty())
|
||||
}
|
||||
ty::Predicate::Projection(..) |
|
||||
ty::Predicate::WellFormed(..) |
|
||||
@ -325,7 +322,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
ty.maybe_walk(|ty| {
|
||||
match ty.sty {
|
||||
ty::TyParam(ref param_ty) => {
|
||||
if param_ty.space == SelfSpace {
|
||||
if param_ty.is_self() {
|
||||
error = true;
|
||||
}
|
||||
|
||||
|
@ -1353,7 +1353,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, '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> {
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst;
|
||||
use infer::type_variable;
|
||||
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::TyProjection(_) => "associated type".to_string(),
|
||||
ty::TyParam(ref p) => {
|
||||
if p.space == subst::SelfSpace {
|
||||
if p.is_self() {
|
||||
"Self".to_string()
|
||||
} else {
|
||||
"type parameter".to_string()
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ty::subst::{self, Substs};
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, Ty, TypeFlags, TypeFoldable};
|
||||
|
||||
pub struct FlagComputation {
|
||||
@ -77,7 +77,7 @@ impl FlagComputation {
|
||||
|
||||
&ty::TyParam(ref p) => {
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||
if p.space == subst::SelfSpace {
|
||||
if p.is_self() {
|
||||
self.add_flags(TypeFlags::HAS_SELF);
|
||||
} else {
|
||||
self.add_flags(TypeFlags::HAS_PARAMS);
|
||||
|
@ -1225,7 +1225,7 @@ impl<'tcx> TraitRef<'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>] {
|
||||
|
@ -305,7 +305,7 @@ pub struct TraitObject<'tcx> {
|
||||
///
|
||||
/// 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
|
||||
/// `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
|
||||
/// that case the `Self` parameter is absent from the substitutions.
|
||||
@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> 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 {
|
||||
@ -524,7 +524,13 @@ impl<'a, 'gcx, 'tcx> ParamTy {
|
||||
}
|
||||
|
||||
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 {
|
||||
match self.sty {
|
||||
TyParam(ref p) => p.space == subst::SelfSpace,
|
||||
TyParam(ref p) => p.is_self(),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
r: Vec<ty::Region>)
|
||||
-> &'tcx Substs<'tcx>
|
||||
{
|
||||
Substs::new(tcx, VecPerParamSpace::new(vec![], vec![], t),
|
||||
VecPerParamSpace::new(vec![], vec![], r))
|
||||
Substs::new(tcx, VecPerParamSpace::new(vec![], t),
|
||||
VecPerParamSpace::new(vec![], r))
|
||||
}
|
||||
|
||||
pub fn new_type(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
@ -56,18 +56,19 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
r: Vec<ty::Region>)
|
||||
-> &'tcx Substs<'tcx>
|
||||
{
|
||||
Substs::new(tcx, VecPerParamSpace::new(vec![], t, vec![]),
|
||||
VecPerParamSpace::new(vec![], r, vec![]))
|
||||
Substs::new(tcx, VecPerParamSpace::new(t, vec![]),
|
||||
VecPerParamSpace::new(r, vec![]))
|
||||
}
|
||||
|
||||
pub fn new_trait(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
t: Vec<Ty<'tcx>>,
|
||||
mut t: Vec<Ty<'tcx>>,
|
||||
r: Vec<ty::Region>,
|
||||
s: Ty<'tcx>)
|
||||
-> &'tcx Substs<'tcx>
|
||||
{
|
||||
Substs::new(tcx, VecPerParamSpace::new(vec![s], t, vec![]),
|
||||
VecPerParamSpace::new(vec![], r, vec![]))
|
||||
t.insert(0, s);
|
||||
Substs::new(tcx, VecPerParamSpace::new(t, vec![]),
|
||||
VecPerParamSpace::new(r, vec![]))
|
||||
}
|
||||
|
||||
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 mut substs = Substs {
|
||||
types: VecPerParamSpace {
|
||||
self_limit: 0,
|
||||
type_limit: 0,
|
||||
content: Vec::with_capacity(defs.types.content.len())
|
||||
},
|
||||
regions: VecPerParamSpace {
|
||||
self_limit: 0,
|
||||
type_limit: 0,
|
||||
content: Vec::with_capacity(defs.regions.content.len())
|
||||
}
|
||||
@ -104,7 +103,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
for &space in &ParamSpace::all() {
|
||||
for def in defs.regions.get_slice(space) {
|
||||
assert_eq!(def.space, space);
|
||||
assert!(space != SelfSpace);
|
||||
|
||||
let region = mk_region(def, &substs);
|
||||
substs.regions.content.push(region);
|
||||
@ -120,11 +118,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
let ty = mk_type(def, &substs);
|
||||
substs.types.content.push(ty);
|
||||
|
||||
if space == SelfSpace {
|
||||
substs.types.self_limit += 1;
|
||||
}
|
||||
|
||||
if space <= TypeSpace {
|
||||
if space == TypeSpace {
|
||||
substs.types.type_limit += 1;
|
||||
}
|
||||
}
|
||||
@ -155,7 +149,6 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
target_substs: &Substs<'tcx>)
|
||||
-> &'tcx Substs<'tcx> {
|
||||
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!(target_substs.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,
|
||||
Clone, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum ParamSpace {
|
||||
SelfSpace, // Self parameter on a trait
|
||||
TypeSpace, // Type parameters attached to a type definition, trait, or impl
|
||||
FnSpace, // Type parameters attached to a method or fn
|
||||
}
|
||||
|
||||
impl ParamSpace {
|
||||
pub fn all() -> [ParamSpace; 3] {
|
||||
[SelfSpace, TypeSpace, FnSpace]
|
||||
pub fn all() -> [ParamSpace; 2] {
|
||||
[TypeSpace, FnSpace]
|
||||
}
|
||||
|
||||
pub fn to_uint(self) -> usize {
|
||||
match self {
|
||||
SelfSpace => 0,
|
||||
TypeSpace => 1,
|
||||
FnSpace => 2,
|
||||
TypeSpace => 0,
|
||||
FnSpace => 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_uint(u: usize) -> ParamSpace {
|
||||
match u {
|
||||
0 => SelfSpace,
|
||||
1 => TypeSpace,
|
||||
2 => FnSpace,
|
||||
0 => TypeSpace,
|
||||
1 => FnSpace,
|
||||
_ => bug!("Invalid ParamSpace: {}", u)
|
||||
}
|
||||
}
|
||||
@ -235,18 +225,15 @@ pub struct VecPerParamSpace<T> {
|
||||
// Here is how the representation corresponds to the abstraction
|
||||
// i.e. the "abstraction function" AF:
|
||||
//
|
||||
// AF(self) = (self.content[..self.self_limit],
|
||||
// self.content[self.self_limit..self.type_limit],
|
||||
// AF(self) = (self.content[..self.type_limit],
|
||||
// self.content[self.type_limit..])
|
||||
self_limit: usize,
|
||||
type_limit: usize,
|
||||
content: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{:?};{:?};{:?}]",
|
||||
self.get_slice(SelfSpace),
|
||||
write!(f, "[{:?};{:?}]",
|
||||
self.get_slice(TypeSpace),
|
||||
self.get_slice(FnSpace))
|
||||
}
|
||||
@ -255,43 +242,34 @@ impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
|
||||
impl<T> VecPerParamSpace<T> {
|
||||
fn limits(&self, space: ParamSpace) -> (usize, usize) {
|
||||
match space {
|
||||
SelfSpace => (0, self.self_limit),
|
||||
TypeSpace => (self.self_limit, self.type_limit),
|
||||
TypeSpace => (0, self.type_limit),
|
||||
FnSpace => (self.type_limit, self.content.len()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> VecPerParamSpace<T> {
|
||||
VecPerParamSpace {
|
||||
self_limit: 0,
|
||||
type_limit: 0,
|
||||
content: Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// `s` is the self space.
|
||||
/// `t` is the type space.
|
||||
/// `f` is the fn space.
|
||||
pub fn new(s: Vec<T>, t: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
|
||||
let self_limit = s.len();
|
||||
let type_limit = self_limit + t.len();
|
||||
pub fn new(t: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
|
||||
let type_limit = t.len();
|
||||
|
||||
let mut content = s;
|
||||
content.extend(t);
|
||||
let mut content = t;
|
||||
content.extend(f);
|
||||
|
||||
VecPerParamSpace {
|
||||
self_limit: self_limit,
|
||||
type_limit: type_limit,
|
||||
content: content,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_internal(content: Vec<T>, self_limit: usize, type_limit: usize)
|
||||
-> VecPerParamSpace<T>
|
||||
{
|
||||
fn new_internal(content: Vec<T>, type_limit: usize) -> VecPerParamSpace<T> {
|
||||
VecPerParamSpace {
|
||||
self_limit: self_limit,
|
||||
type_limit: type_limit,
|
||||
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 {
|
||||
let result = self.as_full_slice().iter().map(pred).collect();
|
||||
VecPerParamSpace::new_internal(result,
|
||||
self.self_limit,
|
||||
self.type_limit)
|
||||
VecPerParamSpace::new_internal(result, self.type_limit)
|
||||
}
|
||||
|
||||
pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
|
||||
P: FnMut((ParamSpace, usize, &T)) -> U,
|
||||
{
|
||||
let result = self.iter_enumerated().map(pred).collect();
|
||||
VecPerParamSpace::new_internal(result,
|
||||
self.self_limit,
|
||||
self.type_limit)
|
||||
VecPerParamSpace::new_internal(result, self.type_limit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,8 +613,6 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
|
||||
-> ty::ExistentialTraitRef<'tcx> {
|
||||
let Substs { mut types, regions } = trait_ref.substs.clone();
|
||||
|
||||
assert_eq!(types.self_limit, 1);
|
||||
types.self_limit = 0;
|
||||
types.type_limit -= 1;
|
||||
types.content.remove(0);
|
||||
|
||||
@ -665,8 +637,6 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
|
||||
self.map_bound(|trait_ref| {
|
||||
let Substs { mut types, regions } = trait_ref.substs.clone();
|
||||
|
||||
assert_eq!(types.self_limit, 0);
|
||||
types.self_limit = 1;
|
||||
types.type_limit += 1;
|
||||
types.content.insert(0, self_ty);
|
||||
|
||||
|
@ -62,35 +62,36 @@ pub enum Ns {
|
||||
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,
|
||||
substs: &subst::Substs,
|
||||
did: DefId,
|
||||
ns: Ns,
|
||||
projections: &[ty::ProjectionPredicate])
|
||||
-> fmt::Result {
|
||||
let (fn_trait_kind, verbose, item_name, is_in_trait) = ty::tls::with(|tcx| {
|
||||
let is_in_trait = ns == Ns::Value && tcx.trait_of_item(did).is_some();
|
||||
if is_in_trait {
|
||||
write!(f, "<{} as ", substs.types.get(subst::SelfSpace, 0))?;
|
||||
let mut verbose = false;
|
||||
let mut num_supplied_defaults = 0;
|
||||
let mut has_self = false;
|
||||
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 {
|
||||
@ -107,15 +108,12 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
||||
(did, None)
|
||||
};
|
||||
write!(f, "{}", tcx.item_path_str(did))?;
|
||||
Ok((tcx.lang_items.fn_trait_kind(did),
|
||||
tcx.sess.verbose(),
|
||||
item_name,
|
||||
is_in_trait))
|
||||
Ok((tcx.lang_items.fn_trait_kind(did), item_name))
|
||||
})?;
|
||||
|
||||
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -160,18 +158,9 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
||||
|
||||
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);
|
||||
|
||||
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, "<", ", ")?;
|
||||
write!(f, "{}", ty)?;
|
||||
}
|
||||
@ -189,7 +178,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
||||
if ns == Ns::Value {
|
||||
empty.set(true);
|
||||
|
||||
if is_in_trait {
|
||||
if has_self {
|
||||
write!(f, ">")?;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ use super::{drop_flag_effects_for_location, on_all_children_bits};
|
||||
use super::{DropFlagState, MoveDataParamEnv};
|
||||
use super::patch::MirPatch;
|
||||
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::transform::{Pass, MirPass, MirSource};
|
||||
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 free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
|
||||
.unwrap_or_else(|e| tcx.sess.fatal(&e));
|
||||
let substs = Substs::new(tcx,
|
||||
VecPerParamSpace::new(vec![], vec![], vec![ty]),
|
||||
VecPerParamSpace::new(vec![], vec![], vec![]));
|
||||
let substs = Substs::new_fn(tcx, vec![ty], vec![]);
|
||||
let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
|
||||
|
||||
self.patch.new_block(BasicBlockData {
|
||||
|
@ -413,7 +413,7 @@ impl tr for Def {
|
||||
Def::AssociatedTy(trait_did, did) =>
|
||||
Def::AssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
|
||||
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) => {
|
||||
let nid1 = dcx.tr_id(nid1);
|
||||
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
|
||||
F: FnMut(&mut TyDecoder<'a, 'tcx>) -> T,
|
||||
{
|
||||
let (mut a, mut b, mut c) = (vec![], vec![], vec![]);
|
||||
for r in &mut [&mut a, &mut b, &mut c] {
|
||||
let (mut a, mut b) = (vec![], vec![]);
|
||||
for r in &mut [&mut a, &mut b] {
|
||||
assert_eq!(self.next(), '[');
|
||||
while self.peek() != ']' {
|
||||
r.push(f(self));
|
||||
}
|
||||
assert_eq!(self.next(), ']');
|
||||
}
|
||||
VecPerParamSpace::new(a, b, c)
|
||||
VecPerParamSpace::new(a, b)
|
||||
}
|
||||
|
||||
pub fn parse_substs(&mut self) -> &'tcx Substs<'tcx> {
|
||||
|
@ -49,7 +49,6 @@ use rustc::lint;
|
||||
use rustc::hir::def::*;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
|
||||
use rustc::ty;
|
||||
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
|
||||
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
|
||||
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) {
|
||||
let type_parameters = match foreign_item.node {
|
||||
ForeignItemKind::Fn(_, ref generics) => {
|
||||
HasTypeParameters(generics, FnSpace, ItemRibKind)
|
||||
HasTypeParameters(generics, ItemRibKind)
|
||||
}
|
||||
ForeignItemKind::Static(..) => NoTypeParameters,
|
||||
};
|
||||
@ -625,10 +624,6 @@ enum TypeParameters<'a, 'b> {
|
||||
HasTypeParameters(// Type parameters.
|
||||
&'b Generics,
|
||||
|
||||
// Identifies the things that these parameters
|
||||
// were declared on (type, fn, etc)
|
||||
ParamSpace,
|
||||
|
||||
// The kind of the rib used for type parameters.
|
||||
RibKind<'a>),
|
||||
}
|
||||
@ -1613,12 +1608,9 @@ impl<'a> Resolver<'a> {
|
||||
match item.node {
|
||||
ItemKind::Enum(_, ref generics) |
|
||||
ItemKind::Ty(_, ref generics) |
|
||||
ItemKind::Struct(_, ref generics) => {
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
|
||||
|this| visit::walk_item(this, item));
|
||||
}
|
||||
ItemKind::Struct(_, 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));
|
||||
}
|
||||
|
||||
@ -1634,10 +1626,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
|
||||
// Create a new rib for the trait-wide type parameters.
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics,
|
||||
TypeSpace,
|
||||
ItemRibKind),
|
||||
|this| {
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
|
||||
let local_def_id = this.definitions.local_def_id(item.id);
|
||||
this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
|
||||
this.visit_generics(generics);
|
||||
@ -1660,7 +1649,6 @@ impl<'a> Resolver<'a> {
|
||||
TraitItemKind::Method(ref sig, _) => {
|
||||
let type_parameters =
|
||||
HasTypeParameters(&sig.generics,
|
||||
FnSpace,
|
||||
MethodRibKind(!sig.decl.has_self()));
|
||||
this.with_type_parameter_rib(type_parameters, |this| {
|
||||
visit::walk_trait_item(this, trait_item)
|
||||
@ -1729,10 +1717,10 @@ impl<'a> Resolver<'a> {
|
||||
where F: FnOnce(&mut Resolver)
|
||||
{
|
||||
match type_parameters {
|
||||
HasTypeParameters(generics, space, rib_kind) => {
|
||||
HasTypeParameters(generics, rib_kind) => {
|
||||
let mut function_type_rib = Rib::new(rib_kind);
|
||||
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;
|
||||
debug!("with_type_parameter_rib: {}", type_parameter.id);
|
||||
|
||||
@ -1745,7 +1733,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// plain insert (no renaming)
|
||||
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);
|
||||
self.record_def(type_parameter.id, PathResolution::new(def));
|
||||
}
|
||||
@ -1917,10 +1905,7 @@ impl<'a> Resolver<'a> {
|
||||
item_id: NodeId,
|
||||
impl_items: &[ImplItem]) {
|
||||
// If applicable, create a rib for the type parameters.
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics,
|
||||
TypeSpace,
|
||||
ItemRibKind),
|
||||
|this| {
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
|
||||
// Resolve the type parameters.
|
||||
this.visit_generics(generics);
|
||||
|
||||
@ -1953,7 +1938,6 @@ impl<'a> Resolver<'a> {
|
||||
// specific type parameters.
|
||||
let type_parameters =
|
||||
HasTypeParameters(&sig.generics,
|
||||
FnSpace,
|
||||
MethodRibKind(!sig.decl.has_self()));
|
||||
this.with_type_parameter_rib(type_parameters, |this| {
|
||||
visit::walk_impl_item(this, impl_item);
|
||||
|
@ -490,7 +490,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
Def::Enum(def_id) |
|
||||
Def::TyAlias(def_id) |
|
||||
Def::Trait(def_id) |
|
||||
Def::TyParam(_, _, def_id, _) => {
|
||||
Def::TyParam(def_id) => {
|
||||
Some(Data::TypeRefData(TypeRefData {
|
||||
span: sub_span.unwrap(),
|
||||
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.
|
||||
|
||||
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.
|
||||
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 middle::resolve_lifetime as rl;
|
||||
use rustc::lint;
|
||||
use rustc::ty::subst::{TypeSpace, SelfSpace, Subst, Substs};
|
||||
use rustc::ty::subst::{TypeSpace, Subst, Substs};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
|
||||
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.
|
||||
if let Some(num_provided) = num_types_provided {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -476,13 +477,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
assert_eq!(def.space, TypeSpace);
|
||||
regions[def.index as usize]
|
||||
}, |def, substs| {
|
||||
assert!(def.space == SelfSpace || def.space == TypeSpace);
|
||||
assert!(def.space == TypeSpace);
|
||||
let i = def.index as usize;
|
||||
if def.space == SelfSpace {
|
||||
// Self, which must have been provided.
|
||||
assert_eq!(i, 0);
|
||||
self_ty.expect("Self type parameter missing")
|
||||
} else if num_types_provided.map_or(false, |n| i < n) {
|
||||
|
||||
// Handle Self first, so we can adjust the index to match the AST.
|
||||
if let (0, Some(ty)) = (i, self_ty) {
|
||||
return ty;
|
||||
}
|
||||
|
||||
let i = i - self_ty.is_some() as usize;
|
||||
if num_types_provided.map_or(false, |n| i < n) {
|
||||
// A provided type parameter.
|
||||
match *parameters {
|
||||
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),
|
||||
}
|
||||
}
|
||||
(&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_name = tcx.type_parameter_def(param_node_id).name;
|
||||
match self.find_bound_for_assoc_item(param_node_id,
|
||||
param_name,
|
||||
assoc_name,
|
||||
@ -1336,10 +1341,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.report_ambiguous_associated_type(span,
|
||||
&ty.to_string(),
|
||||
"Trait",
|
||||
&assoc_name.as_str());
|
||||
// Don't print TyErr to the user.
|
||||
if !ty.references_error() {
|
||||
self.report_ambiguous_associated_type(span,
|
||||
&ty.to_string(),
|
||||
"Trait",
|
||||
&assoc_name.as_str());
|
||||
}
|
||||
return (tcx.types.err, Def::Err);
|
||||
}
|
||||
};
|
||||
@ -1477,9 +1485,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
did,
|
||||
base_segments.last().unwrap())
|
||||
}
|
||||
Def::TyParam(space, index, _, name) => {
|
||||
Def::TyParam(did) => {
|
||||
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)) => {
|
||||
// Self in impl (we know the concrete type).
|
||||
|
@ -204,7 +204,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
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);
|
||||
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);
|
||||
|
||||
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!(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, _| {
|
||||
self.region_var_for_def(span, def)
|
||||
}, |def, substs| {
|
||||
if def.space == subst::SelfSpace {
|
||||
if def.index == 0 {
|
||||
self_ty
|
||||
} else if let Some(ref input_types) = opt_input_types {
|
||||
input_types[def.index as usize]
|
||||
input_types[def.index as usize - 1]
|
||||
} else {
|
||||
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));
|
||||
assert_eq!(m.generics.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
|
||||
@ -755,11 +751,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
let substs = Substs::for_item(self.tcx, trait_def_id, |def, _| {
|
||||
self.region_var_for_def(self.span, def)
|
||||
}, |def, substs| {
|
||||
if def.space == subst::SelfSpace {
|
||||
assert_eq!(def.index, 0);
|
||||
if def.index == 0 {
|
||||
step.self_ty
|
||||
} else {
|
||||
assert_eq!(def.space, subst::TypeSpace);
|
||||
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 i = def.index as usize;
|
||||
let segment = match def.space {
|
||||
subst::SelfSpace => None,
|
||||
subst::TypeSpace => type_segment,
|
||||
subst::FnSpace => fn_segment
|
||||
};
|
||||
@ -4241,9 +4240,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
self.region_var_for_def(span, def)
|
||||
}
|
||||
}, |def, substs| {
|
||||
let i = def.index as usize;
|
||||
let mut i = def.index as usize;
|
||||
let segment = match def.space {
|
||||
subst::SelfSpace => None,
|
||||
subst::TypeSpace => type_segment,
|
||||
subst::FnSpace => fn_segment
|
||||
};
|
||||
@ -4252,18 +4250,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
Some(&hir::ParenthesizedParameters(_)) => bug!(),
|
||||
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 default = if can_omit && types.len() == 0 {
|
||||
def.default
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
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) {
|
||||
if let Some(ast_ty) = types.get(i) {
|
||||
// A provided type parameter.
|
||||
self.to_ty(ast_ty)
|
||||
} else if let Some(default) = default {
|
||||
@ -4371,6 +4375,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// Check provided type parameters.
|
||||
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()
|
||||
.take_while(|d| d.default.is_none())
|
||||
.count();
|
||||
|
@ -14,13 +14,12 @@ use CrateCtxt;
|
||||
use hir::def_id::DefId;
|
||||
use middle::region::{CodeExtent};
|
||||
use rustc::infer::TypeOrigin;
|
||||
use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
|
||||
use rustc::ty::subst;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
||||
use std::collections::HashSet;
|
||||
use syntax::ast;
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax_pos::Span;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
@ -461,7 +460,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
variances.types
|
||||
.iter_enumerated()
|
||||
.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))
|
||||
.collect();
|
||||
|
||||
@ -470,52 +469,34 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
&mut constrained_parameters);
|
||||
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
|
||||
for (space, index, &variance) in variances.regions.iter_enumerated() {
|
||||
assert_eq!(space, subst::TypeSpace);
|
||||
|
||||
if variance != ty::Bivariant {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert_eq!(space, TypeSpace);
|
||||
let span = ast_generics.lifetimes[index].lifetime.span;
|
||||
let name = ast_generics.lifetimes[index].lifetime.name;
|
||||
self.report_bivariance(span, name);
|
||||
}
|
||||
}
|
||||
|
||||
fn param_ty(&self,
|
||||
ast_generics: &hir::Generics,
|
||||
space: ParamSpace,
|
||||
index: usize)
|
||||
-> ty::ParamTy
|
||||
{
|
||||
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?"),
|
||||
fn param_ty(&self, ast_generics: &hir::Generics, index: usize) -> ty::ParamTy {
|
||||
ty::ParamTy {
|
||||
space: subst::TypeSpace,
|
||||
idx: index as u32,
|
||||
name: ast_generics.ty_params[index].name
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
||||
|
||||
let source = tcx.lookup_item_type(impl_did).ty;
|
||||
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)",
|
||||
source, target);
|
||||
|
||||
|
@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem;
|
||||
use middle::const_val::ConstVal;
|
||||
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
||||
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::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
||||
use rustc::ty::{VariantKind};
|
||||
@ -85,7 +85,6 @@ use std::rc::Rc;
|
||||
|
||||
use syntax::{abi, ast, attr};
|
||||
use syntax::parse::token::keywords;
|
||||
use syntax::ptr::P;
|
||||
use syntax_pos::Span;
|
||||
|
||||
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);
|
||||
match path_res.base_def {
|
||||
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)
|
||||
}
|
||||
_ => false
|
||||
@ -1333,7 +1332,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
|
||||
|
||||
// add in the explicit where-clauses
|
||||
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,
|
||||
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 def = ty::TypeParameterDef {
|
||||
space: SelfSpace,
|
||||
space: TypeSpace,
|
||||
index: 0,
|
||||
name: keywords::SelfType.name(),
|
||||
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();
|
||||
|
||||
// Now create the real type parameters.
|
||||
let types = ast_generics.ty_params.iter().enumerate().map(|(i, _)| {
|
||||
get_or_create_type_parameter_def(ccx, ast_generics, space, i as u32, allow_defaults)
|
||||
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
|
||||
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();
|
||||
|
||||
let has_self = base_generics.has_self || opt_self.is_some();
|
||||
let (regions, types) = match space {
|
||||
SelfSpace => bug!(),
|
||||
TypeSpace => {
|
||||
assert_eq!(base_generics.regions.as_full_slice().len(), 0);
|
||||
assert_eq!(base_generics.types.as_full_slice().len(), 0);
|
||||
(VecPerParamSpace::new(vec![], regions, vec![]),
|
||||
VecPerParamSpace::new(opt_self.into_iter().collect(), types, vec![]))
|
||||
(VecPerParamSpace::new(regions, vec![]),
|
||||
VecPerParamSpace::new(opt_self.into_iter().chain(types).collect(), vec![]))
|
||||
}
|
||||
FnSpace => {
|
||||
assert_eq!(base_generics.regions.len(FnSpace), 0);
|
||||
assert_eq!(base_generics.types.len(FnSpace), 0);
|
||||
(VecPerParamSpace::new(base_generics.regions.get_slice(SelfSpace).to_vec(),
|
||||
base_generics.regions.get_slice(TypeSpace).to_vec(),
|
||||
(VecPerParamSpace::new(base_generics.regions.get_slice(TypeSpace).to_vec(),
|
||||
regions),
|
||||
VecPerParamSpace::new(base_generics.types.get_slice(SelfSpace).to_vec(),
|
||||
base_generics.types.get_slice(TypeSpace).to_vec(),
|
||||
VecPerParamSpace::new(base_generics.types.get_slice(TypeSpace).to_vec(),
|
||||
types))
|
||||
}
|
||||
};
|
||||
@ -1674,7 +1671,7 @@ fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
generics: &hir::Generics)
|
||||
-> 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>,
|
||||
@ -1682,7 +1679,7 @@ fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
base_predicates: &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`.
|
||||
@ -1752,7 +1749,8 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>(
|
||||
fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
space: ParamSpace,
|
||||
ast_generics: &hir::Generics,
|
||||
base_predicates: &ty::GenericPredicates<'tcx>)
|
||||
base_predicates: &ty::GenericPredicates<'tcx>,
|
||||
has_self: bool)
|
||||
-> ty::GenericPredicates<'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
|
||||
// type parameter (e.g., `<T:Foo>`).
|
||||
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 bounds = compute_bounds(&ccx.icx(&(base_predicates, ast_generics)),
|
||||
param_ty,
|
||||
@ -1850,50 +1848,22 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
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>,
|
||||
ast_generics: &hir::Generics,
|
||||
space: ParamSpace,
|
||||
index: u32,
|
||||
param: &hir::TyParam,
|
||||
allow_defaults: bool)
|
||||
-> ty::TypeParameterDef<'tcx>
|
||||
{
|
||||
let param = &ast_generics.ty_params[index as usize];
|
||||
|
||||
let tcx = ccx.tcx;
|
||||
match tcx.ty_param_defs.borrow().get(¶m.id) {
|
||||
Some(d) => { return d.clone(); }
|
||||
None => { }
|
||||
}
|
||||
|
||||
let default = param.default.as_ref().map(
|
||||
|def| convert_default_type_parameter(ccx, def, space, index)
|
||||
);
|
||||
let default =
|
||||
param.default.as_ref().map(|def| ccx.icx(&()).to_ty(&ExplicitRscope, def));
|
||||
|
||||
let object_lifetime_default =
|
||||
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,
|
||||
};
|
||||
|
||||
if def.name == keywords::SelfType.name() {
|
||||
span_bug!(param.span, "`Self` should not be the name of a regular parameter");
|
||||
}
|
||||
|
||||
tcx.ty_param_defs.borrow_mut().insert(param.id, def.clone());
|
||||
|
||||
debug!("get_or_create_type_parameter_def: def for type param: {:?}, {:?}",
|
||||
@ -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
|
||||
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_def_id: DefId)
|
||||
{
|
||||
@ -2173,12 +2147,11 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
impl_trait_ref,
|
||||
&mut input_parameters);
|
||||
|
||||
for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
|
||||
let param_ty = ty::ParamTy { space: TypeSpace,
|
||||
idx: index as u32,
|
||||
name: ty_param.name };
|
||||
let ty_generics = generics_of_def_id(ccx, impl_def_id);
|
||||
for (ty_param, param) in ty_generics.types.as_full_slice().iter().zip(&generics.ty_params) {
|
||||
let param_ty = ty::ParamTy::for_def(ty_param);
|
||||
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
|
||||
// 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.regions.is_empty_in(subst::SelfSpace));
|
||||
assert!(item_type.generics.regions.is_empty_in(subst::FnSpace));
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
@ -394,14 +392,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
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`:
|
||||
let contra = self.contravariant(variance);
|
||||
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);
|
||||
|
||||
for projection in &data.projection_bounds {
|
||||
|
@ -110,8 +110,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
||||
while index < num_inferred {
|
||||
let item_id = inferred_infos[index].item_id;
|
||||
|
||||
let (mut rs, mut rt, mut rf) = (vec![], vec![], vec![]);
|
||||
let (mut ts, mut tt, mut tf) = (vec![], vec![], vec![]);
|
||||
let (mut rt, mut rf) = (vec![], vec![]);
|
||||
let (mut tt, mut tf) = (vec![], vec![]);
|
||||
|
||||
while index < num_inferred && inferred_infos[index].item_id == item_id {
|
||||
let info = &inferred_infos[index];
|
||||
@ -121,7 +121,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
||||
match info.kind {
|
||||
TypeParam => {
|
||||
let types = match info.space {
|
||||
subst::SelfSpace => &mut ts,
|
||||
subst::TypeSpace => &mut tt,
|
||||
subst::FnSpace => &mut tf
|
||||
};
|
||||
@ -130,7 +129,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
||||
}
|
||||
RegionParam => {
|
||||
let regions = match info.space {
|
||||
subst::SelfSpace => &mut rs,
|
||||
subst::TypeSpace => &mut rt,
|
||||
subst::FnSpace => &mut rf
|
||||
};
|
||||
@ -143,8 +141,8 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let item_variances = ty::ItemVariances {
|
||||
regions: subst::VecPerParamSpace::new(rs, rt, rf),
|
||||
types: subst::VecPerParamSpace::new(ts, tt, tf)
|
||||
regions: subst::VecPerParamSpace::new(rt, rf),
|
||||
types: subst::VecPerParamSpace::new(tt, tf)
|
||||
};
|
||||
|
||||
debug!("item_id={} item_variances={:?}",
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
use arena::TypedArena;
|
||||
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::maps::ItemVariances;
|
||||
use std::fmt;
|
||||
@ -164,16 +164,16 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
||||
|
||||
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() {
|
||||
let id = p.lifetime.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() {
|
||||
let i = has_self as usize + i;
|
||||
self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
||||
-> ty::Variance
|
||||
{
|
||||
match space {
|
||||
SelfSpace | FnSpace => {
|
||||
FnSpace => {
|
||||
ty::Bivariant
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use rustc::hir::fold::Folder;
|
||||
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::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 {
|
||||
let lifetimes = substs.regions.get_slice(subst::TypeSpace)
|
||||
.iter()
|
||||
.filter_map(|v| v.clean(cx))
|
||||
.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()) {
|
||||
// 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
|
||||
// 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 {
|
||||
Path {
|
||||
global: false,
|
||||
segments: vec![PathSegment {
|
||||
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 {
|
||||
ty::BoundSend =>
|
||||
(tcx.lang_items.send_trait().unwrap(),
|
||||
external_path(cx, "Send", None, vec![], empty)),
|
||||
external_path(cx, "Send", None, false, vec![], empty)),
|
||||
ty::BoundSized =>
|
||||
(tcx.lang_items.sized_trait().unwrap(),
|
||||
external_path(cx, "Sized", None, vec![], empty)),
|
||||
external_path(cx, "Sized", None, false, vec![], empty)),
|
||||
ty::BoundCopy =>
|
||||
(tcx.lang_items.copy_trait().unwrap(),
|
||||
external_path(cx, "Copy", None, vec![], empty)),
|
||||
external_path(cx, "Copy", None, false, vec![], empty)),
|
||||
ty::BoundSync =>
|
||||
(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);
|
||||
TraitBound(PolyTrait {
|
||||
@ -728,14 +729,14 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
||||
};
|
||||
inline::record_extern_fqn(cx, self.def_id, TypeTrait);
|
||||
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",
|
||||
self.substs.types.get_slice(ParamSpace::TypeSpace));
|
||||
&self.input_types()[1..]);
|
||||
|
||||
// collect any late bound regions
|
||||
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 {
|
||||
for &ty_s in ts {
|
||||
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
|
||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||
// them.
|
||||
let stripped_typarams = gens.types.get_slice(space).iter().map(|tp| {
|
||||
tp.clean(cx)
|
||||
let stripped_typarams = gens.types.get_slice(space).iter().filter_map(|tp| {
|
||||
if tp.name == keywords::SelfType.name() {
|
||||
assert_eq!(tp.index, 0);
|
||||
None
|
||||
} else {
|
||||
Some(tp.clean(cx))
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| {
|
||||
let mut srp = rp.clone();
|
||||
@ -1820,7 +1826,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
};
|
||||
inline::record_extern_fqn(cx, did, kind);
|
||||
let path = external_path(cx, &cx.tcx().item_name(did).as_str(),
|
||||
None, vec![], substs);
|
||||
None, false, vec![], substs);
|
||||
ResolvedPath {
|
||||
path: path,
|
||||
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(),
|
||||
Some(did), bindings, obj.principal.0.substs);
|
||||
Some(did), false, bindings, obj.principal.0.substs);
|
||||
ResolvedPath {
|
||||
path: path,
|
||||
typarams: Some(typarams),
|
||||
|
@ -8,15 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// 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; }
|
||||
impl<T: ?Sized> Mirror for T { type It = Self; }
|
||||
struct S(Option<<S as Mirror>::It>);
|
||||
|
||||
#[rustc_no_mir] // FIXME #27840 MIR tries to represent `std::option::Option<S>` first.
|
||||
fn main() {
|
||||
let _s = S(None);
|
||||
}
|
||||
|
@ -10,5 +10,7 @@
|
||||
|
||||
#![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() {}
|
||||
|
@ -20,12 +20,12 @@ trait Trait<'a> {
|
||||
}
|
||||
|
||||
#[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 ())
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ use std::cell::Cell;
|
||||
// For better or worse, associated types are invariant, and hence we
|
||||
// get an invariant result for `'a`.
|
||||
#[rustc_variance]
|
||||
struct Foo<'a> { //~ ERROR regions=[[];[o];[]]
|
||||
struct Foo<'a> { //~ ERROR regions=[[o];[]]
|
||||
x: Box<Fn(i32) -> &'a i32 + 'static>
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_variance]
|
||||
trait Foo: 'static { //~ ERROR types=[[o];[];[]]
|
||||
trait Foo: 'static { //~ ERROR types=[[o];[]]
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Bar<T> { //~ ERROR types=[[o];[o];[]]
|
||||
trait Bar<T> { //~ ERROR types=[[o, o];[]]
|
||||
fn do_it(&self)
|
||||
where T: 'static;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
// Regions that just appear in normal spots are contravariant:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[];[-, -, -];[]]
|
||||
struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[-, -, -];[]]
|
||||
x: &'a isize,
|
||||
y: &'b [isize],
|
||||
c: &'c str
|
||||
@ -25,7 +25,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR regions=[[];[-, -, -];[]]
|
||||
// Those same annotations in function arguments become covariant:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[];[+, +, +];[]]
|
||||
struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[+, +, +];[]]
|
||||
x: extern "Rust" fn(&'a isize),
|
||||
y: extern "Rust" fn(&'b [isize]),
|
||||
c: extern "Rust" fn(&'c str),
|
||||
@ -34,7 +34,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR regions=[[];[+, +, +];[]]
|
||||
// Mutability induces invariance:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test4<'a, 'b:'a> { //~ ERROR regions=[[];[-, o];[]]
|
||||
struct Test4<'a, 'b:'a> { //~ ERROR regions=[[-, o];[]]
|
||||
x: &'a mut &'b isize,
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR regions=[[];[-, o];[]]
|
||||
// contravariant context:
|
||||
|
||||
#[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),
|
||||
}
|
||||
|
||||
@ -52,14 +52,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR regions=[[];[+, o];[]]
|
||||
// argument list occurs in an invariant context.
|
||||
|
||||
#[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),
|
||||
}
|
||||
|
||||
// No uses at all is bivariant:
|
||||
|
||||
#[rustc_variance]
|
||||
struct Test7<'a> { //~ ERROR regions=[[];[*];[]]
|
||||
struct Test7<'a> { //~ ERROR regions=[[*];[]]
|
||||
//~^ ERROR parameter `'a` is never used
|
||||
x: isize
|
||||
}
|
||||
@ -67,7 +67,7 @@ struct Test7<'a> { //~ ERROR regions=[[];[*];[]]
|
||||
// Try enums too.
|
||||
|
||||
#[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)),
|
||||
Test8B(&'b [isize]),
|
||||
Test8C(&'b mut &'c str),
|
||||
|
@ -15,7 +15,7 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[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
|
||||
Test8A(extern "Rust" fn(&'a isize)),
|
||||
Test8B(&'b [isize]),
|
||||
@ -23,25 +23,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[];[+, -, o, *];[]]
|
||||
}
|
||||
|
||||
#[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
|
||||
f: Base<'z, 'y, 'x, 'w>
|
||||
}
|
||||
|
||||
#[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
|
||||
f: Base<'a, 'a, 'b, 'c>
|
||||
}
|
||||
|
||||
#[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
|
||||
f: Base<'a, 'b, 'a, 'c>
|
||||
}
|
||||
|
||||
#[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>
|
||||
}
|
||||
|
||||
|
@ -15,48 +15,48 @@
|
||||
// influence variance.
|
||||
|
||||
#[rustc_variance]
|
||||
trait Getter<T> { //~ ERROR types=[[o];[o];[]]
|
||||
trait Getter<T> { //~ ERROR types=[[o, o];[]]
|
||||
fn get(&self) -> T;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Setter<T> { //~ ERROR types=[[o];[o];[]]
|
||||
trait Setter<T> { //~ ERROR types=[[o, o];[]]
|
||||
fn get(&self, T);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[];[+, +];[]]
|
||||
struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[]]
|
||||
t: T, u: U
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[];[*, +];[]]
|
||||
enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[]]
|
||||
//~^ ERROR parameter `U` is never used
|
||||
Foo(T)
|
||||
}
|
||||
|
||||
#[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;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[o];[o];[]]
|
||||
trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[o, o];[]]
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait TestTrait3<U> { //~ ERROR types=[[o];[o];[]]
|
||||
trait TestTrait3<U> { //~ ERROR types=[[o, o];[]]
|
||||
fn getter<T:Getter<U>>(&self);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[];[*, +];[]]
|
||||
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[]]
|
||||
//~^ ERROR parameter `U` is never used
|
||||
t: T
|
||||
}
|
||||
|
||||
#[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
|
||||
t: T
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use std::mem;
|
||||
trait T { fn foo(&self); }
|
||||
|
||||
#[rustc_variance]
|
||||
struct TOption<'a> { //~ ERROR regions=[[];[-];[]]
|
||||
struct TOption<'a> { //~ ERROR regions=[[-];[]]
|
||||
v: Option<Box<T + 'a>>,
|
||||
}
|
||||
|
||||
|
@ -14,46 +14,46 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestImm<A, B> { //~ ERROR types=[[];[+, +];[]]
|
||||
struct TestImm<A, B> { //~ ERROR types=[[+, +];[]]
|
||||
x: A,
|
||||
y: B,
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestMut<A, B:'static> { //~ ERROR types=[[];[+, o];[]]
|
||||
struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[]]
|
||||
x: A,
|
||||
y: &'static mut B,
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[];[+, o];[]]
|
||||
struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[]]
|
||||
m: TestMut<A, B>
|
||||
}
|
||||
|
||||
#[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>,
|
||||
m: TestMut<B, A>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Getter<A> { //~ ERROR types=[[o];[o];[]]
|
||||
trait Getter<A> { //~ ERROR types=[[o, o];[]]
|
||||
fn get(&self) -> A;
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait Setter<A> { //~ ERROR types=[[o];[o];[]]
|
||||
trait Setter<A> { //~ ERROR types=[[o, o];[]]
|
||||
fn set(&mut self, a: A);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
|
||||
trait GetterSetter<A> { //~ ERROR types=[[o, o];[]]
|
||||
fn get(&self) -> A;
|
||||
fn set(&mut self, a: A);
|
||||
}
|
||||
|
||||
#[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
|
||||
// variance. Think of it as if the method requested a dictionary
|
||||
// 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]
|
||||
trait SetterInTypeBound<A> { //~ ERROR types=[[o];[o];[]]
|
||||
trait SetterInTypeBound<A> { //~ ERROR types=[[o, o];[]]
|
||||
fn do_it<T:Setter<A>>(&self);
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct TestObject<A, R> { //~ ERROR types=[[];[o, o];[]]
|
||||
struct TestObject<A, R> { //~ ERROR types=[[o, o];[]]
|
||||
n: Box<Setter<A>+Send>,
|
||||
m: Box<Getter<R>+Send>,
|
||||
}
|
||||
|
@ -17,32 +17,32 @@ use std::cell::Cell;
|
||||
// not considered bivariant.
|
||||
|
||||
#[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)
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct InvariantCell<A> { //~ ERROR types=[[];[o];[]]
|
||||
struct InvariantCell<A> { //~ ERROR types=[[o];[]]
|
||||
t: Cell<A>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct InvariantIndirect<A> { //~ ERROR types=[[];[o];[]]
|
||||
struct InvariantIndirect<A> { //~ ERROR types=[[o];[]]
|
||||
t: InvariantCell<A>
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct Covariant<A> { //~ ERROR types=[[];[+];[]]
|
||||
struct Covariant<A> { //~ ERROR types=[[+];[]]
|
||||
t: A, u: fn() -> A
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
struct Contravariant<A> { //~ ERROR types=[[];[-];[]]
|
||||
struct Contravariant<A> { //~ ERROR types=[[-];[]]
|
||||
t: fn(A)
|
||||
}
|
||||
|
||||
#[rustc_variance]
|
||||
enum Enum<A,B,C> { //~ ERROR types=[[];[+, -, o];[]]
|
||||
enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[]]
|
||||
Foo(Covariant<A>),
|
||||
Bar(Contravariant<B>),
|
||||
Zed(Covariant<C>,Contravariant<C>)
|
||||
|
Loading…
Reference in New Issue
Block a user