rustc: split Generics of a method from its parent Generics.
This commit is contained in:
parent
c1cfd58cbd
commit
3e74e5bffe
@ -82,7 +82,6 @@ use hir::def::Def;
|
|||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use infer::{self, TypeOrigin};
|
use infer::{self, TypeOrigin};
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use ty::subst;
|
|
||||||
use ty::{self, TyCtxt, TypeFoldable};
|
use ty::{self, TyCtxt, TypeFoldable};
|
||||||
use ty::{Region, ReFree};
|
use ty::{Region, ReFree};
|
||||||
use ty::error::TypeError;
|
use ty::error::TypeError;
|
||||||
@ -1369,7 +1368,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
|
|||||||
let generics = self.tcx.lookup_generics(did);
|
let generics = self.tcx.lookup_generics(did);
|
||||||
|
|
||||||
let expected =
|
let expected =
|
||||||
generics.regions.len(subst::TypeSpace) as u32;
|
generics.regions.len() as u32;
|
||||||
let lifetimes =
|
let lifetimes =
|
||||||
path.segments.last().unwrap().parameters.lifetimes();
|
path.segments.last().unwrap().parameters.lifetimes();
|
||||||
let mut insert = Vec::new();
|
let mut insert = Vec::new();
|
||||||
|
@ -271,14 +271,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let def = self.tcx.lookup_trait_def(trait_ref.def_id);
|
let def = self.tcx.lookup_trait_def(trait_ref.def_id);
|
||||||
let trait_str = def.trait_ref.to_string();
|
let trait_str = def.trait_ref.to_string();
|
||||||
if let Some(ref istring) = item.value_str() {
|
if let Some(ref istring) = item.value_str() {
|
||||||
let mut generic_map = def.generics.types.iter_enumerated()
|
let generic_map = def.generics.types.iter().map(|param| {
|
||||||
.map(|(param, i, gen)| {
|
(param.name.as_str().to_string(),
|
||||||
(gen.name.as_str().to_string(),
|
trait_ref.substs.type_for_def(param).to_string())
|
||||||
trait_ref.substs.types.get(param, i)
|
}).collect::<FnvHashMap<String, String>>();
|
||||||
.to_string())
|
|
||||||
}).collect::<FnvHashMap<String, String>>();
|
|
||||||
generic_map.insert("Self".to_string(),
|
|
||||||
trait_ref.self_ty().to_string());
|
|
||||||
let parser = Parser::new(&istring);
|
let parser = Parser::new(&istring);
|
||||||
let mut errored = false;
|
let mut errored = false;
|
||||||
let err: String = parser.filter_map(|p| {
|
let err: String = parser.filter_map(|p| {
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
use super::elaborate_predicates;
|
use super::elaborate_predicates;
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
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;
|
||||||
@ -266,7 +265,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We can't monomorphize things like `fn foo<A>(...)`.
|
// We can't monomorphize things like `fn foo<A>(...)`.
|
||||||
if !method.generics.types.is_empty_in(subst::FnSpace) {
|
if !method.generics.types.is_empty() {
|
||||||
return Some(MethodViolationCode::Generic);
|
return Some(MethodViolationCode::Generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,33 +757,14 @@ impl RegionParameterDef {
|
|||||||
/// with an item or method. Analogous to hir::Generics.
|
/// with an item or method. Analogous to hir::Generics.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Generics<'tcx> {
|
pub struct Generics<'tcx> {
|
||||||
pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
|
pub parent: Option<DefId>,
|
||||||
pub regions: VecPerParamSpace<RegionParameterDef>,
|
pub parent_regions: u32,
|
||||||
|
pub parent_types: u32,
|
||||||
|
pub regions: Vec<RegionParameterDef>,
|
||||||
|
pub types: Vec<TypeParameterDef<'tcx>>,
|
||||||
pub has_self: bool,
|
pub has_self: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Generics<'tcx> {
|
|
||||||
pub fn empty() -> Generics<'tcx> {
|
|
||||||
Generics {
|
|
||||||
types: VecPerParamSpace::empty(),
|
|
||||||
regions: VecPerParamSpace::empty(),
|
|
||||||
has_self: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
|
||||||
self.types.is_empty() && self.regions.is_empty()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
|
|
||||||
!self.types.is_empty_in(space)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
|
|
||||||
!self.regions.is_empty_in(space)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bounds on generics.
|
/// Bounds on generics.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GenericPredicates<'tcx> {
|
pub struct GenericPredicates<'tcx> {
|
||||||
|
@ -832,20 +832,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> {
|
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
|
||||||
ty::Generics {
|
|
||||||
types: self.types.fold_with(folder),
|
|
||||||
regions: self.regions.fold_with(folder),
|
|
||||||
has_self: self.has_self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
|
||||||
self.types.visit_with(visitor) || self.regions.visit_with(visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
|
||||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||||
ty::GenericPredicates {
|
ty::GenericPredicates {
|
||||||
|
@ -89,42 +89,55 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||||||
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
|
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
|
||||||
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
|
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
|
||||||
let defs = tcx.lookup_generics(def_id);
|
let defs = tcx.lookup_generics(def_id);
|
||||||
|
let num_regions = defs.parent_regions as usize + defs.regions.len();
|
||||||
|
let num_types = defs.parent_types as usize + defs.types.len();
|
||||||
let mut substs = Substs {
|
let mut substs = Substs {
|
||||||
types: VecPerParamSpace {
|
|
||||||
type_limit: 0,
|
|
||||||
content: Vec::with_capacity(defs.types.content.len())
|
|
||||||
},
|
|
||||||
regions: VecPerParamSpace {
|
regions: VecPerParamSpace {
|
||||||
type_limit: 0,
|
type_limit: 0,
|
||||||
content: Vec::with_capacity(defs.regions.content.len())
|
content: Vec::with_capacity(num_regions)
|
||||||
|
},
|
||||||
|
types: VecPerParamSpace {
|
||||||
|
type_limit: 0,
|
||||||
|
content: Vec::with_capacity(num_types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for &space in &ParamSpace::all() {
|
substs.fill_item(tcx, defs, &mut mk_region, &mut mk_type);
|
||||||
for def in defs.regions.get_slice(space) {
|
|
||||||
assert_eq!(def.space, space);
|
|
||||||
|
|
||||||
let region = mk_region(def, &substs);
|
Substs::new(tcx, substs.types, substs.regions)
|
||||||
substs.regions.content.push(region);
|
}
|
||||||
|
|
||||||
if space == TypeSpace {
|
fn fill_item<FR, FT>(&mut self,
|
||||||
substs.regions.type_limit += 1;
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
}
|
defs: &ty::Generics<'tcx>,
|
||||||
}
|
mk_region: &mut FR,
|
||||||
|
mk_type: &mut FT)
|
||||||
|
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
|
||||||
|
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
|
||||||
|
if let Some(def_id) = defs.parent {
|
||||||
|
let parent_defs = tcx.lookup_generics(def_id);
|
||||||
|
self.fill_item(tcx, parent_defs, mk_region, mk_type);
|
||||||
|
}
|
||||||
|
|
||||||
for def in defs.types.get_slice(space) {
|
for def in &defs.regions {
|
||||||
assert_eq!(def.space, space);
|
let region = mk_region(def, self);
|
||||||
|
self.regions.content.push(region);
|
||||||
|
|
||||||
let ty = mk_type(def, &substs);
|
if def.space == TypeSpace {
|
||||||
substs.types.content.push(ty);
|
self.regions.type_limit += 1;
|
||||||
|
assert_eq!(self.regions.content.len(), self.regions.type_limit);
|
||||||
if space == TypeSpace {
|
|
||||||
substs.types.type_limit += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Substs::new(tcx, substs.types, substs.regions)
|
for def in &defs.types {
|
||||||
|
let ty = mk_type(def, self);
|
||||||
|
self.types.content.push(ty);
|
||||||
|
|
||||||
|
if def.space == TypeSpace {
|
||||||
|
self.types.type_limit += 1;
|
||||||
|
assert_eq!(self.types.content.len(), self.types.type_limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_noop(&self) -> bool {
|
pub fn is_noop(&self) -> bool {
|
||||||
@ -149,16 +162,14 @@ 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(TypeSpace), defs.types.len(TypeSpace));
|
assert_eq!(self.types.len(TypeSpace), defs.types.len());
|
||||||
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!(self.regions.len(TypeSpace), defs.regions.len());
|
||||||
assert_eq!(self.regions.len(TypeSpace), defs.regions.len(TypeSpace));
|
|
||||||
assert_eq!(target_substs.regions.len(FnSpace), 0);
|
assert_eq!(target_substs.regions.len(FnSpace), 0);
|
||||||
assert_eq!(defs.regions.len(FnSpace), 0);
|
|
||||||
|
|
||||||
let Substs { mut types, mut regions } = target_substs.clone();
|
let Substs { mut types, mut regions } = target_substs.clone();
|
||||||
types.content.extend(&self.types.as_full_slice()[defs.types.content.len()..]);
|
types.content.extend(&self.types.as_full_slice()[defs.types.len()..]);
|
||||||
regions.content.extend(&self.regions.as_full_slice()[defs.regions.content.len()..]);
|
regions.content.extend(&self.regions.as_full_slice()[defs.regions.len()..]);
|
||||||
Substs::new(tcx, types, regions)
|
Substs::new(tcx, types, regions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -597,8 +608,8 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
|
|||||||
-> ty::TraitRef<'tcx> {
|
-> ty::TraitRef<'tcx> {
|
||||||
let Substs { mut types, mut regions } = substs.clone();
|
let Substs { mut types, mut regions } = substs.clone();
|
||||||
let defs = tcx.lookup_generics(trait_id);
|
let defs = tcx.lookup_generics(trait_id);
|
||||||
types.content.truncate(defs.types.type_limit);
|
types.content.truncate(defs.types.len());
|
||||||
regions.content.truncate(defs.regions.type_limit);
|
regions.content.truncate(defs.regions.len());
|
||||||
|
|
||||||
ty::TraitRef {
|
ty::TraitRef {
|
||||||
def_id: trait_id,
|
def_id: trait_id,
|
||||||
|
@ -73,13 +73,15 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
|||||||
let mut has_self = false;
|
let mut has_self = false;
|
||||||
let (fn_trait_kind, item_name) = ty::tls::with(|tcx| {
|
let (fn_trait_kind, item_name) = ty::tls::with(|tcx| {
|
||||||
verbose = tcx.sess.verbose();
|
verbose = tcx.sess.verbose();
|
||||||
let generics = tcx.lookup_generics(did);
|
let mut generics = tcx.lookup_generics(did);
|
||||||
|
if let Some(def_id) = generics.parent {
|
||||||
|
generics = tcx.lookup_generics(def_id);
|
||||||
|
}
|
||||||
if !verbose {
|
if !verbose {
|
||||||
let ty_params = generics.types.get_slice(subst::TypeSpace);
|
if generics.types.last().map_or(false, |def| def.default.is_some()) {
|
||||||
if ty_params.last().map_or(false, |def| def.default.is_some()) {
|
|
||||||
if let Some(substs) = tcx.lift(&substs) {
|
if let Some(substs) = tcx.lift(&substs) {
|
||||||
let tps = substs.types.get_slice(subst::TypeSpace);
|
let tps = substs.types.get_slice(subst::TypeSpace);
|
||||||
for (def, actual) in ty_params.iter().zip(tps).rev() {
|
for (def, actual) in generics.types.iter().zip(tps).rev() {
|
||||||
if def.default.subst(tcx, substs) != Some(actual) {
|
if def.default.subst(tcx, substs) != Some(actual) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -620,9 +620,9 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
|
|||||||
if let Some(impl_item) = impl_item_opt {
|
if let Some(impl_item) = impl_item_opt {
|
||||||
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
|
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
|
||||||
encode_attributes(rbml_w, &impl_item.attrs);
|
encode_attributes(rbml_w, &impl_item.attrs);
|
||||||
let scheme = ecx.tcx.lookup_item_type(m.def_id);
|
let generics = ecx.tcx.lookup_generics(m.def_id);
|
||||||
let any_types = !scheme.generics.types.is_empty();
|
let types = generics.parent_types as usize + generics.types.len();
|
||||||
let needs_inline = any_types || is_default_impl ||
|
let needs_inline = types > 0 || is_default_impl ||
|
||||||
attr::requests_inline(&impl_item.attrs);
|
attr::requests_inline(&impl_item.attrs);
|
||||||
if needs_inline || sig.constness == hir::Constness::Const {
|
if needs_inline || sig.constness == hir::Constness::Const {
|
||||||
encode_inlined_item(ecx,
|
encode_inlined_item(ecx,
|
||||||
|
@ -149,9 +149,29 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
|
pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
|
||||||
let regions = self.parse_vec_per_param_space(|this| this.parse_region_param_def());
|
let parent = self.parse_opt(|this| this.parse_def());
|
||||||
let types = self.parse_vec_per_param_space(|this| this.parse_type_param_def());
|
let parent_regions = self.parse_u32();
|
||||||
|
assert_eq!(self.next(), '|');
|
||||||
|
let parent_types = self.parse_u32();
|
||||||
|
|
||||||
|
let mut regions = vec![];
|
||||||
|
assert_eq!(self.next(), '[');
|
||||||
|
while self.peek() != ']' {
|
||||||
|
regions.push(self.parse_region_param_def());
|
||||||
|
}
|
||||||
|
assert_eq!(self.next(), ']');
|
||||||
|
|
||||||
|
let mut types = vec![];
|
||||||
|
assert_eq!(self.next(), '[');
|
||||||
|
while self.peek() != ']' {
|
||||||
|
types.push(self.parse_type_param_def());
|
||||||
|
}
|
||||||
|
assert_eq!(self.next(), ']');
|
||||||
|
|
||||||
self.tcx.alloc_generics(ty::Generics {
|
self.tcx.alloc_generics(ty::Generics {
|
||||||
|
parent: parent,
|
||||||
|
parent_regions: parent_regions,
|
||||||
|
parent_types: parent_types,
|
||||||
regions: regions,
|
regions: regions,
|
||||||
types: types,
|
types: types,
|
||||||
has_self: self.next() == 'S'
|
has_self: self.next() == 'S'
|
||||||
|
@ -274,10 +274,21 @@ pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
|
|||||||
|
|
||||||
pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
|
pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
|
||||||
generics: &ty::Generics<'tcx>) {
|
generics: &ty::Generics<'tcx>) {
|
||||||
enc_vec_per_param_space(w, cx, &generics.regions,
|
enc_opt(w, generics.parent, |w, def_id| {
|
||||||
|w, cx, r| enc_region_param_def(w, cx, r));
|
write!(w, "{}|", (cx.ds)(cx.tcx, def_id));
|
||||||
enc_vec_per_param_space(w, cx, &generics.types,
|
});
|
||||||
|w, cx, ty| enc_type_param_def(w, cx, ty));
|
write!(w, "{}|{}[",
|
||||||
|
generics.parent_regions,
|
||||||
|
generics.parent_types);
|
||||||
|
|
||||||
|
for r in &generics.regions {
|
||||||
|
enc_region_param_def(w, cx, r)
|
||||||
|
}
|
||||||
|
write!(w, "][");
|
||||||
|
for t in &generics.types {
|
||||||
|
enc_type_param_def(w, cx, t);
|
||||||
|
}
|
||||||
|
write!(w, "]");
|
||||||
|
|
||||||
if generics.has_self {
|
if generics.has_self {
|
||||||
write!(w, "S");
|
write!(w, "S");
|
||||||
|
@ -2470,8 +2470,8 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
|
|||||||
hir_map::NodeImplItem(&hir::ImplItem {
|
hir_map::NodeImplItem(&hir::ImplItem {
|
||||||
node: hir::ImplItemKind::Method(..), .. }) => {
|
node: hir::ImplItemKind::Method(..), .. }) => {
|
||||||
let def_id = tcx.map.local_def_id(id);
|
let def_id = tcx.map.local_def_id(id);
|
||||||
let scheme = tcx.lookup_item_type(def_id);
|
let generics = tcx.lookup_generics(def_id);
|
||||||
scheme.generics.types.is_empty()
|
generics.parent_types == 0 && generics.types.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => false
|
_ => false
|
||||||
|
@ -195,7 +195,7 @@ use rustc::hir::map as hir_map;
|
|||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem};
|
use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem};
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::ty::subst::{self, Substs, Subst};
|
use rustc::ty::subst::{Substs, Subst};
|
||||||
use rustc::ty::{self, TypeFoldable, TyCtxt};
|
use rustc::ty::{self, TypeFoldable, TyCtxt};
|
||||||
use rustc::ty::adjustment::CustomCoerceUnsized;
|
use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||||
use rustc::mir::repr as mir;
|
use rustc::mir::repr as mir;
|
||||||
@ -1219,17 +1219,16 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
def_id_to_string(tcx, impl_def_id));
|
def_id_to_string(tcx, impl_def_id));
|
||||||
|
|
||||||
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
|
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
|
||||||
let default_impls = tcx.provided_trait_methods(trait_ref.def_id);
|
|
||||||
let callee_substs = tcx.erase_regions(&trait_ref.substs);
|
let callee_substs = tcx.erase_regions(&trait_ref.substs);
|
||||||
let overridden_methods: FnvHashSet<_> = items.iter()
|
let overridden_methods: FnvHashSet<_> = items.iter()
|
||||||
.map(|item| item.name)
|
.map(|item| item.name)
|
||||||
.collect();
|
.collect();
|
||||||
for default_impl in default_impls {
|
for method in tcx.provided_trait_methods(trait_ref.def_id) {
|
||||||
if overridden_methods.contains(&default_impl.name) {
|
if overridden_methods.contains(&method.name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if default_impl.generics.has_type_params(subst::FnSpace) {
|
if !method.generics.types.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1242,7 +1241,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
callee_substs,
|
callee_substs,
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
impl_substs,
|
impl_substs,
|
||||||
default_impl.name);
|
method.name);
|
||||||
|
|
||||||
assert!(mth.is_provided);
|
assert!(mth.is_provided);
|
||||||
|
|
||||||
@ -1251,10 +1250,10 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if can_have_local_instance(tcx, default_impl.def_id) {
|
if can_have_local_instance(tcx, method.def_id) {
|
||||||
let empty_substs = tcx.erase_regions(&mth.substs);
|
let empty_substs = tcx.erase_regions(&mth.substs);
|
||||||
let item = create_fn_trans_item(tcx,
|
let item = create_fn_trans_item(tcx,
|
||||||
default_impl.def_id,
|
method.def_id,
|
||||||
callee_substs,
|
callee_substs,
|
||||||
empty_substs);
|
empty_substs);
|
||||||
output.push(item);
|
output.push(item);
|
||||||
|
@ -381,10 +381,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
// Again, only create type information if full debuginfo is enabled
|
// Again, only create type information if full debuginfo is enabled
|
||||||
let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo {
|
let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo {
|
||||||
generics.types.as_full_slice().iter().enumerate().map(|(i, param)| {
|
let names = get_type_parameter_names(cx, generics);
|
||||||
let actual_type = cx.tcx().normalize_associated_type(&actual_types[i]);
|
actual_types.iter().zip(names).map(|(ty, name)| {
|
||||||
|
let actual_type = cx.tcx().normalize_associated_type(ty);
|
||||||
let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
||||||
let name = CString::new(param.name.as_str().as_bytes()).unwrap();
|
let name = CString::new(name.as_str().as_bytes()).unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
@ -403,6 +404,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
return create_DIArray(DIB(cx), &template_params[..]);
|
return create_DIArray(DIB(cx), &template_params[..]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_type_parameter_names<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
|
generics: &ty::Generics<'tcx>)
|
||||||
|
-> Vec<ast::Name> {
|
||||||
|
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||||
|
get_type_parameter_names(cx, cx.tcx().lookup_generics(def_id))
|
||||||
|
});
|
||||||
|
names.extend(generics.types.iter().map(|param| param.name));
|
||||||
|
names
|
||||||
|
}
|
||||||
|
|
||||||
fn get_containing_scope_and_span<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
|
fn get_containing_scope_and_span<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
|
||||||
instance: Instance<'tcx>)
|
instance: Instance<'tcx>)
|
||||||
-> (DIScope, Span) {
|
-> (DIScope, Span) {
|
||||||
|
@ -429,7 +429,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||||||
bug!("ErrorReported returned, but no errors reports?")
|
bug!("ErrorReported returned, but no errors reports?")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let expected_num_region_params = decl_generics.regions.len(TypeSpace);
|
let expected_num_region_params = decl_generics.regions.len();
|
||||||
let supplied_num_region_params = lifetimes.len();
|
let supplied_num_region_params = lifetimes.len();
|
||||||
let regions = if expected_num_region_params == supplied_num_region_params {
|
let regions = if expected_num_region_params == supplied_num_region_params {
|
||||||
lifetimes.iter().map(|l| ast_region_to_region(tcx, l)).collect()
|
lifetimes.iter().map(|l| ast_region_to_region(tcx, l)).collect()
|
||||||
@ -454,8 +454,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[self_ty.is_some() as usize..];
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ use rustc::infer::{self, InferOk, TypeOrigin};
|
|||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::traits::{self, Reveal};
|
use rustc::traits::{self, Reveal};
|
||||||
use rustc::ty::error::ExpectedFound;
|
use rustc::ty::error::ExpectedFound;
|
||||||
use rustc::ty::subst::{self, Subst, Substs};
|
use rustc::ty::subst::{Subst, Substs};
|
||||||
use rustc::hir::map::Node;
|
use rustc::hir::map::Node;
|
||||||
use rustc::hir::{ImplItemKind, TraitItem_};
|
use rustc::hir::{ImplItemKind, TraitItem_};
|
||||||
|
|
||||||
@ -95,8 +95,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let num_impl_m_type_params = impl_m.generics.types.len(subst::FnSpace);
|
let num_impl_m_type_params = impl_m.generics.types.len();
|
||||||
let num_trait_m_type_params = trait_m.generics.types.len(subst::FnSpace);
|
let num_trait_m_type_params = trait_m.generics.types.len();
|
||||||
if num_impl_m_type_params != num_trait_m_type_params {
|
if num_impl_m_type_params != num_trait_m_type_params {
|
||||||
span_err!(tcx.sess, impl_m_span, E0049,
|
span_err!(tcx.sess, impl_m_span, E0049,
|
||||||
"method `{}` has {} type parameter{} \
|
"method `{}` has {} type parameter{} \
|
||||||
@ -389,8 +389,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
|
|
||||||
let trait_params = trait_generics.regions.get_slice(subst::FnSpace);
|
let trait_params = &trait_generics.regions[..];
|
||||||
let impl_params = impl_generics.regions.get_slice(subst::FnSpace);
|
let impl_params = &impl_generics.regions[..];
|
||||||
|
|
||||||
debug!("check_region_bounds_on_impl_method: \
|
debug!("check_region_bounds_on_impl_method: \
|
||||||
trait_generics={:?} \
|
trait_generics={:?} \
|
||||||
|
@ -49,7 +49,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
variadic: false,
|
variadic: false,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
|
let i_n_tps = i_ty.generics.types.len();
|
||||||
if i_n_tps != n_tps {
|
if i_n_tps != n_tps {
|
||||||
struct_span_err!(tcx.sess, it.span, E0094,
|
struct_span_err!(tcx.sess, it.span, E0094,
|
||||||
"intrinsic has wrong number of type \
|
"intrinsic has wrong number of type \
|
||||||
@ -321,7 +321,7 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
|
|||||||
|
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
let i_ty = tcx.lookup_item_type(tcx.map.local_def_id(it.id));
|
let i_ty = tcx.lookup_item_type(tcx.map.local_def_id(it.id));
|
||||||
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
|
let i_n_tps = i_ty.generics.types.len();
|
||||||
let name = it.name.as_str();
|
let name = it.name.as_str();
|
||||||
|
|
||||||
let (n_tps, inputs, output) = match &*name {
|
let (n_tps, inputs, output) = match &*name {
|
||||||
|
@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||||||
// variables.
|
// variables.
|
||||||
let num_supplied_types = supplied_method_types.len();
|
let num_supplied_types = supplied_method_types.len();
|
||||||
let method = pick.item.as_opt_method().unwrap();
|
let method = pick.item.as_opt_method().unwrap();
|
||||||
let num_method_types = method.generics.types.len(subst::FnSpace);
|
let num_method_types = method.generics.types.len();
|
||||||
|
|
||||||
if num_supplied_types > 0 && num_supplied_types != num_method_types {
|
if num_supplied_types > 0 && num_supplied_types != num_method_types {
|
||||||
if num_method_types == 0 {
|
if num_method_types == 0 {
|
||||||
|
@ -183,15 +183,15 @@ 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) - 1, input_types.len());
|
assert_eq!(trait_def.generics.types.len() - 1, input_types.len());
|
||||||
}
|
}
|
||||||
assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0);
|
|
||||||
assert!(trait_def.generics.regions.is_empty());
|
assert!(trait_def.generics.regions.is_empty());
|
||||||
|
|
||||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||||
let substs = 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| {
|
||||||
|
assert_eq!(def.space, subst::TypeSpace);
|
||||||
if def.index == 0 {
|
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 {
|
||||||
@ -221,8 +221,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let method_item = self.trait_item(trait_def_id, m_name).unwrap();
|
let method_item = self.trait_item(trait_def_id, m_name).unwrap();
|
||||||
let method_ty = method_item.as_opt_method().unwrap();
|
let method_ty = method_item.as_opt_method().unwrap();
|
||||||
assert_eq!(method_ty.generics.types.len(subst::FnSpace), 0);
|
assert_eq!(method_ty.generics.types.len(), 0);
|
||||||
assert_eq!(method_ty.generics.regions.len(subst::FnSpace), 0);
|
assert_eq!(method_ty.generics.regions.len(), 0);
|
||||||
|
|
||||||
debug!("lookup_in_trait_adjusted: method_item={:?} method_ty={:?}",
|
debug!("lookup_in_trait_adjusted: method_item={:?} method_ty={:?}",
|
||||||
method_item, method_ty);
|
method_item, method_ty);
|
||||||
|
@ -518,9 +518,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
trait_ref,
|
trait_ref,
|
||||||
trait_ref.substs,
|
trait_ref.substs,
|
||||||
m);
|
m);
|
||||||
assert_eq!(m.generics.types.len(subst::TypeSpace),
|
assert_eq!(m.generics.parent_types as usize,
|
||||||
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.parent_regions as usize,
|
||||||
trait_ref.substs.regions.len(subst::TypeSpace));
|
trait_ref.substs.regions.len(subst::TypeSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1232,8 +1232,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
let xform_self_ty = method.fty.sig.input(0);
|
let xform_self_ty = method.fty.sig.input(0);
|
||||||
let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty);
|
let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty);
|
||||||
|
|
||||||
if method.generics.types.is_empty_in(subst::FnSpace) &&
|
if method.generics.types.is_empty() && method.generics.regions.is_empty() {
|
||||||
method.generics.regions.is_empty_in(subst::FnSpace) {
|
|
||||||
xform_self_ty.subst(self.tcx, substs)
|
xform_self_ty.subst(self.tcx, substs)
|
||||||
} else {
|
} else {
|
||||||
let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
|
let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
|
||||||
@ -1260,17 +1259,13 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||||||
impl_def_id: DefId)
|
impl_def_id: DefId)
|
||||||
-> (Ty<'tcx>, &'tcx Substs<'tcx>)
|
-> (Ty<'tcx>, &'tcx Substs<'tcx>)
|
||||||
{
|
{
|
||||||
let impl_pty = self.tcx.lookup_item_type(impl_def_id);
|
let impl_ty = self.tcx.lookup_item_type(impl_def_id).ty;
|
||||||
|
|
||||||
let type_vars =
|
let substs = Substs::for_item(self.tcx, impl_def_id,
|
||||||
impl_pty.generics.types.map(
|
|_, _| ty::ReErased,
|
||||||
|_| self.next_ty_var());
|
|_, _| self.next_ty_var());
|
||||||
|
|
||||||
let region_placeholders =
|
(impl_ty, substs)
|
||||||
impl_pty.generics.regions.map(
|
|
||||||
|_| ty::ReErased); // see erase_late_bound_regions() for an expl of why 'erased
|
|
||||||
|
|
||||||
(impl_pty.ty, Substs::new(self.tcx, type_vars, region_placeholders))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace late-bound-regions bound by `value` with `'static` using
|
/// Replace late-bound-regions bound by `value` with `'static` using
|
||||||
|
@ -881,8 +881,7 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
// `{Self}` is allowed
|
// `{Self}` is allowed
|
||||||
Position::ArgumentNamed(s) if s == "Self" => (),
|
Position::ArgumentNamed(s) if s == "Self" => (),
|
||||||
// So is `{A}` if A is a type parameter
|
// So is `{A}` if A is a type parameter
|
||||||
Position::ArgumentNamed(s) => match types.as_full_slice()
|
Position::ArgumentNamed(s) => match types.iter().find(|t| {
|
||||||
.iter().find(|t| {
|
|
||||||
t.name.as_str() == s
|
t.name.as_str() == s
|
||||||
}) {
|
}) {
|
||||||
Some(_) => (),
|
Some(_) => (),
|
||||||
@ -1693,7 +1692,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let mut ty = self.tcx.lookup_item_type(did).ty;
|
let mut ty = self.tcx.lookup_item_type(did).ty;
|
||||||
if ty.is_fn() {
|
if ty.is_fn() {
|
||||||
// Tuple variants have fn type even in type namespace, extract true variant type from it
|
// Tuple variants have fn type even in type namespace, extract true variant type from it
|
||||||
ty = self.tcx.no_late_bound_regions(&type_scheme.ty.fn_ret()).unwrap();
|
ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap();
|
||||||
}
|
}
|
||||||
let type_predicates = self.tcx.lookup_predicates(did);
|
let type_predicates = self.tcx.lookup_predicates(did);
|
||||||
let substs = AstConv::ast_path_substs_for_ty(self, self,
|
let substs = AstConv::ast_path_substs_for_ty(self, self,
|
||||||
@ -3222,13 +3221,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors();
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Def::Variant(..) | Def::Struct(..) => {
|
Def::Variant(type_did, _) | Def::Struct(type_did) => {
|
||||||
Some(self.tcx.expect_variant_def(def))
|
Some((type_did, self.tcx.expect_variant_def(def)))
|
||||||
}
|
}
|
||||||
Def::TyAlias(did) | Def::AssociatedTy(_, did) => {
|
Def::TyAlias(did) => {
|
||||||
if let Some(&ty::TyStruct(adt, _)) = self.tcx.opt_lookup_item_type(did)
|
if let Some(&ty::TyStruct(adt, _)) = self.tcx.opt_lookup_item_type(did)
|
||||||
.map(|scheme| &scheme.ty.sty) {
|
.map(|scheme| &scheme.ty.sty) {
|
||||||
Some(adt.struct_variant())
|
Some((did, adt.struct_variant()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -3236,14 +3235,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(variant) = variant {
|
if let Some((def_id, variant)) = variant {
|
||||||
if variant.kind == ty::VariantKind::Tuple &&
|
if variant.kind == ty::VariantKind::Tuple &&
|
||||||
!self.tcx.sess.features.borrow().relaxed_adts {
|
!self.tcx.sess.features.borrow().relaxed_adts {
|
||||||
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
|
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
|
||||||
"relaxed_adts", span, GateIssue::Language,
|
"relaxed_adts", span, GateIssue::Language,
|
||||||
"tuple structs and variants in struct patterns are unstable");
|
"tuple structs and variants in struct patterns are unstable");
|
||||||
}
|
}
|
||||||
let ty = self.instantiate_type_path(def.def_id(), path, node_id);
|
let ty = self.instantiate_type_path(def_id, path, node_id);
|
||||||
Some((variant, ty))
|
Some((variant, ty))
|
||||||
} else {
|
} else {
|
||||||
struct_span_err!(self.tcx.sess, path.span, E0071,
|
struct_span_err!(self.tcx.sess, path.span, E0071,
|
||||||
@ -4122,25 +4121,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let mut fn_segment = None;
|
let mut fn_segment = None;
|
||||||
match def {
|
match def {
|
||||||
// Case 1 and 1b. Reference to a *type* or *enum variant*.
|
// Case 1 and 1b. Reference to a *type* or *enum variant*.
|
||||||
Def::SelfTy(..) |
|
Def::Struct(def_id) |
|
||||||
Def::Struct(..) |
|
Def::Variant(_, def_id) |
|
||||||
Def::Variant(..) |
|
Def::Enum(def_id) |
|
||||||
Def::Enum(..) |
|
Def::TyAlias(def_id) |
|
||||||
Def::TyAlias(..) |
|
Def::AssociatedTy(_, def_id) |
|
||||||
Def::AssociatedTy(..) |
|
Def::Trait(def_id) => {
|
||||||
Def::Trait(..) |
|
|
||||||
Def::PrimTy(..) |
|
|
||||||
Def::TyParam(..) => {
|
|
||||||
// Everything but the final segment should have no
|
// Everything but the final segment should have no
|
||||||
// parameters at all.
|
// parameters at all.
|
||||||
type_segment = segments.last();
|
let mut generics = self.tcx.lookup_generics(def_id);
|
||||||
|
if let Some(def_id) = generics.parent {
|
||||||
|
// Variant and struct constructors use the
|
||||||
|
// generics of their parent type definition.
|
||||||
|
generics = self.tcx.lookup_generics(def_id);
|
||||||
|
}
|
||||||
|
type_segment = Some((segments.last().unwrap(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 2. Reference to a top-level value.
|
// Case 2. Reference to a top-level value.
|
||||||
Def::Fn(..) |
|
Def::Fn(def_id) |
|
||||||
Def::Const(..) |
|
Def::Const(def_id) |
|
||||||
Def::Static(..) => {
|
Def::Static(def_id, _) => {
|
||||||
fn_segment = segments.last();
|
fn_segment = Some((segments.last().unwrap(),
|
||||||
|
self.tcx.lookup_generics(def_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case 3. Reference to a method or associated const.
|
// Case 3. Reference to a method or associated const.
|
||||||
@ -4154,14 +4157,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
ty::ImplContainer(_) => {}
|
ty::ImplContainer(_) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let generics = self.tcx.lookup_generics(def_id);
|
||||||
if segments.len() >= 2 {
|
if segments.len() >= 2 {
|
||||||
type_segment = Some(&segments[segments.len() - 2]);
|
let parent_generics = self.tcx.lookup_generics(generics.parent.unwrap());
|
||||||
|
type_segment = Some((&segments[segments.len() - 2], parent_generics));
|
||||||
} else {
|
} else {
|
||||||
// `<T>::assoc` will end up here, and so can `T::assoc`.
|
// `<T>::assoc` will end up here, and so can `T::assoc`.
|
||||||
let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
|
let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
|
||||||
ufcs_associated = Some((container, self_ty));
|
ufcs_associated = Some((container, self_ty));
|
||||||
}
|
}
|
||||||
fn_segment = segments.last();
|
fn_segment = Some((segments.last().unwrap(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other cases. Various nonsense that really shouldn't show up
|
// Other cases. Various nonsense that really shouldn't show up
|
||||||
@ -4169,6 +4174,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// elsewhere. (I hope)
|
// elsewhere. (I hope)
|
||||||
Def::Mod(..) |
|
Def::Mod(..) |
|
||||||
Def::ForeignMod(..) |
|
Def::ForeignMod(..) |
|
||||||
|
Def::PrimTy(..) |
|
||||||
|
Def::SelfTy(..) |
|
||||||
|
Def::TyParam(..) |
|
||||||
Def::Local(..) |
|
Def::Local(..) |
|
||||||
Def::Label(..) |
|
Def::Label(..) |
|
||||||
Def::Upvar(..) |
|
Def::Upvar(..) |
|
||||||
@ -4213,12 +4221,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// a problem.
|
// a problem.
|
||||||
self.check_path_parameter_count(subst::TypeSpace,
|
self.check_path_parameter_count(subst::TypeSpace,
|
||||||
span,
|
span,
|
||||||
scheme.generics,
|
|
||||||
!require_type_space,
|
!require_type_space,
|
||||||
&mut type_segment);
|
&mut type_segment);
|
||||||
self.check_path_parameter_count(subst::FnSpace,
|
self.check_path_parameter_count(subst::FnSpace,
|
||||||
span,
|
span,
|
||||||
scheme.generics,
|
|
||||||
true,
|
true,
|
||||||
&mut fn_segment);
|
&mut fn_segment);
|
||||||
|
|
||||||
@ -4228,7 +4234,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
subst::TypeSpace => type_segment,
|
subst::TypeSpace => type_segment,
|
||||||
subst::FnSpace => fn_segment
|
subst::FnSpace => fn_segment
|
||||||
};
|
};
|
||||||
let lifetimes = match segment.map(|s| &s.parameters) {
|
let lifetimes = match segment.map(|(s, _)| &s.parameters) {
|
||||||
Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
|
Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
|
||||||
Some(&hir::ParenthesizedParameters(_)) => bug!(),
|
Some(&hir::ParenthesizedParameters(_)) => bug!(),
|
||||||
None => &[]
|
None => &[]
|
||||||
@ -4242,25 +4248,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}, |def, substs| {
|
}, |def, substs| {
|
||||||
let mut i = def.index as usize;
|
let mut i = def.index as usize;
|
||||||
let segment = match def.space {
|
let segment = match def.space {
|
||||||
subst::TypeSpace => type_segment,
|
subst::TypeSpace => {
|
||||||
|
// Handle Self first, so we can adjust the index to match the AST.
|
||||||
|
match (type_segment, fn_segment) {
|
||||||
|
(Some((_, generics)), _) | (_, Some((_, generics))) => {
|
||||||
|
if generics.has_self {
|
||||||
|
if i == 0 {
|
||||||
|
return opt_self_ty.unwrap_or_else(|| {
|
||||||
|
self.type_var_for_def(span, def, substs)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
type_segment
|
||||||
|
}
|
||||||
subst::FnSpace => fn_segment
|
subst::FnSpace => fn_segment
|
||||||
};
|
};
|
||||||
let types = match segment.map(|s| &s.parameters) {
|
let types = match segment.map(|(s, _)| &s.parameters) {
|
||||||
Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..],
|
Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..],
|
||||||
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
|
||||||
@ -4306,9 +4318,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// with the substituted impl type.
|
// with the substituted impl type.
|
||||||
let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
|
let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
|
||||||
assert_eq!(substs.types.len(subst::TypeSpace),
|
assert_eq!(substs.types.len(subst::TypeSpace),
|
||||||
impl_scheme.generics.types.len(subst::TypeSpace));
|
impl_scheme.generics.types.len());
|
||||||
assert_eq!(substs.regions.len(subst::TypeSpace),
|
assert_eq!(substs.regions.len(subst::TypeSpace),
|
||||||
impl_scheme.generics.regions.len(subst::TypeSpace));
|
impl_scheme.generics.regions.len());
|
||||||
|
|
||||||
let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
|
let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
|
||||||
match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
|
match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
|
||||||
@ -4339,10 +4351,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
fn check_path_parameter_count(&self,
|
fn check_path_parameter_count(&self,
|
||||||
space: subst::ParamSpace,
|
space: subst::ParamSpace,
|
||||||
span: Span,
|
span: Span,
|
||||||
generics: &ty::Generics<'tcx>,
|
|
||||||
can_omit: bool,
|
can_omit: bool,
|
||||||
segment: &mut Option<&hir::PathSegment>) {
|
segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
|
||||||
let (lifetimes, types, bindings) = match segment.map(|s| &s.parameters) {
|
let (lifetimes, types, bindings) = match segment.map(|(s, _)| &s.parameters) {
|
||||||
Some(&hir::AngleBracketedParameters(ref data)) => {
|
Some(&hir::AngleBracketedParameters(ref data)) => {
|
||||||
(&data.lifetimes[..], &data.types[..], &data.bindings[..])
|
(&data.lifetimes[..], &data.types[..], &data.bindings[..])
|
||||||
}
|
}
|
||||||
@ -4357,7 +4368,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Check provided lifetime parameters.
|
// Check provided lifetime parameters.
|
||||||
let lifetime_defs = generics.regions.get_slice(space);
|
let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
|
||||||
if lifetimes.len() > lifetime_defs.len() {
|
if lifetimes.len() > lifetime_defs.len() {
|
||||||
let span = lifetimes[lifetime_defs.len()].span;
|
let span = lifetimes[lifetime_defs.len()].span;
|
||||||
span_err!(self.tcx.sess, span, E0088,
|
span_err!(self.tcx.sess, span, E0088,
|
||||||
@ -4374,12 +4385,13 @@ 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 = segment.map_or(&[][..], |(_, generics)| {
|
||||||
let type_defs = if space == subst::TypeSpace {
|
if space == subst::TypeSpace {
|
||||||
&type_defs[generics.has_self as usize..]
|
&generics.types[generics.has_self as usize..]
|
||||||
} else {
|
} else {
|
||||||
type_defs
|
&generics.types
|
||||||
};
|
}
|
||||||
|
});
|
||||||
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();
|
||||||
|
@ -523,10 +523,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
|
fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
|
||||||
let impl_params = generics.types.get_slice(subst::TypeSpace).iter()
|
let parent = tcx.lookup_generics(generics.parent.unwrap());
|
||||||
.map(|tp| tp.name).collect::<HashSet<_>>();
|
let impl_params: HashSet<_> = parent.types.iter().map(|tp| tp.name).collect();
|
||||||
|
|
||||||
for method_param in generics.types.get_slice(subst::FnSpace) {
|
for method_param in &generics.types {
|
||||||
if impl_params.contains(&method_param.name) {
|
if impl_params.contains(&method_param.name) {
|
||||||
error_194(tcx, span, method_param.name);
|
error_194(tcx, span, method_param.name);
|
||||||
}
|
}
|
||||||
|
@ -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, TypeSpace, VecPerParamSpace};
|
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace};
|
||||||
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};
|
||||||
@ -793,9 +793,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
|
if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
|
||||||
|
let const_def_id = ccx.tcx.map.local_def_id(impl_item.id);
|
||||||
|
let ty_generics = generics_of_def_id(ccx, const_def_id);
|
||||||
let ty = ccx.icx(&ty_predicates)
|
let ty = ccx.icx(&ty_predicates)
|
||||||
.to_ty(&ExplicitRscope, &ty);
|
.to_ty(&ExplicitRscope, &ty);
|
||||||
tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
|
tcx.register_item_type(const_def_id,
|
||||||
TypeScheme {
|
TypeScheme {
|
||||||
generics: ty_generics,
|
generics: ty_generics,
|
||||||
ty: ty,
|
ty: ty,
|
||||||
@ -858,11 +860,13 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
|||||||
// Convert all the associated constants.
|
// Convert all the associated constants.
|
||||||
for trait_item in trait_items {
|
for trait_item in trait_items {
|
||||||
if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node {
|
if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node {
|
||||||
|
let const_def_id = ccx.tcx.map.local_def_id(trait_item.id);
|
||||||
|
let ty_generics = generics_of_def_id(ccx, const_def_id);
|
||||||
let ty = ccx.icx(&trait_predicates)
|
let ty = ccx.icx(&trait_predicates)
|
||||||
.to_ty(&ExplicitRscope, ty);
|
.to_ty(&ExplicitRscope, ty);
|
||||||
tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
|
tcx.register_item_type(const_def_id,
|
||||||
TypeScheme {
|
TypeScheme {
|
||||||
generics: trait_def.generics,
|
generics: ty_generics,
|
||||||
ty: ty,
|
ty: ty,
|
||||||
});
|
});
|
||||||
convert_associated_const(ccx,
|
convert_associated_const(ccx,
|
||||||
@ -957,7 +961,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
predicates: ty::GenericPredicates<'tcx>) {
|
predicates: ty::GenericPredicates<'tcx>) {
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
let def_id = tcx.map.local_def_id(ctor_id);
|
let def_id = tcx.map.local_def_id(ctor_id);
|
||||||
tcx.generics.borrow_mut().insert(def_id, scheme.generics);
|
generics_of_def_id(ccx, def_id);
|
||||||
let ctor_ty = match variant.kind {
|
let ctor_ty = match variant.kind {
|
||||||
VariantKind::Unit | VariantKind::Struct => scheme.ty,
|
VariantKind::Unit | VariantKind::Struct => scheme.ty,
|
||||||
VariantKind::Tuple => {
|
VariantKind::Tuple => {
|
||||||
@ -1389,24 +1393,35 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
use rustc::hir::map::*;
|
use rustc::hir::map::*;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
|
|
||||||
|
let node = tcx.map.get(node_id);
|
||||||
|
let parent_def_id = match node {
|
||||||
|
NodeImplItem(_) |
|
||||||
|
NodeTraitItem(_) |
|
||||||
|
NodeVariant(_) |
|
||||||
|
NodeStructCtor(_) => {
|
||||||
|
let parent_id = tcx.map.get_parent(node_id);
|
||||||
|
Some(tcx.map.local_def_id(parent_id))
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
};
|
||||||
|
|
||||||
let mut opt_self = None;
|
let mut opt_self = None;
|
||||||
let mut base_def_id = None;
|
|
||||||
let mut allow_defaults = false;
|
let mut allow_defaults = false;
|
||||||
|
|
||||||
let no_generics = hir::Generics::empty();
|
let no_generics = hir::Generics::empty();
|
||||||
let (space, ast_generics) = match tcx.map.get(node_id) {
|
let (space, ast_generics) = match node {
|
||||||
NodeImplItem(&ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) |
|
NodeTraitItem(item) => {
|
||||||
NodeTraitItem(&TraitItem { node: MethodTraitItem(ref sig, _), .. }) => {
|
match item.node {
|
||||||
let parent_id = tcx.map.get_parent(node_id);
|
MethodTraitItem(ref sig, _) => (FnSpace, &sig.generics),
|
||||||
base_def_id = Some(tcx.map.local_def_id(parent_id));
|
_ => (FnSpace, &no_generics)
|
||||||
(FnSpace, &sig.generics)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeImplItem(_) |
|
NodeImplItem(item) => {
|
||||||
NodeTraitItem(_) => {
|
match item.node {
|
||||||
let parent_id = tcx.map.get_parent(node_id);
|
ImplItemKind::Method(ref sig, _) => (FnSpace, &sig.generics),
|
||||||
base_def_id = Some(tcx.map.local_def_id(parent_id));
|
_ => (FnSpace, &no_generics)
|
||||||
(FnSpace, &no_generics)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem(item) => {
|
NodeItem(item) => {
|
||||||
@ -1457,9 +1472,16 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
_ => (TypeSpace, &no_generics)
|
_ => (TypeSpace, &no_generics)
|
||||||
};
|
};
|
||||||
|
|
||||||
let empty_generics = ty::Generics::empty();
|
let has_self = opt_self.is_some();
|
||||||
let base_generics = base_def_id.map_or(&empty_generics, |def_id| {
|
let mut parent_has_self = false;
|
||||||
generics_of_def_id(ccx, def_id)
|
let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
|
||||||
|
let generics = generics_of_def_id(ccx, def_id);
|
||||||
|
assert_eq!(generics.parent, None);
|
||||||
|
assert_eq!(generics.parent_regions, 0);
|
||||||
|
assert_eq!(generics.parent_types, 0);
|
||||||
|
assert_eq!(has_self, false);
|
||||||
|
parent_has_self = generics.has_self;
|
||||||
|
(generics.regions.len(), generics.types.len())
|
||||||
});
|
});
|
||||||
|
|
||||||
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
|
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
|
||||||
@ -1477,32 +1499,15 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
|
|
||||||
// Now create the real type parameters.
|
// Now create the real type parameters.
|
||||||
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
|
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
|
||||||
let i = opt_self.is_some() as u32 + i as u32;
|
let i = has_self as u32 + i as u32;
|
||||||
get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults)
|
get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults)
|
||||||
}).collect();
|
});
|
||||||
|
let types: Vec<_> = opt_self.into_iter().chain(types).collect();
|
||||||
let has_self = base_generics.has_self || opt_self.is_some();
|
|
||||||
let (regions, types) = match space {
|
|
||||||
TypeSpace => {
|
|
||||||
assert_eq!(base_generics.regions.as_full_slice().len(), 0);
|
|
||||||
assert_eq!(base_generics.types.as_full_slice().len(), 0);
|
|
||||||
(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(TypeSpace).to_vec(),
|
|
||||||
regions),
|
|
||||||
VecPerParamSpace::new(base_generics.types.get_slice(TypeSpace).to_vec(),
|
|
||||||
types))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Debugging aid.
|
// Debugging aid.
|
||||||
if tcx.has_attr(def_id, "rustc_object_lifetime_default") {
|
if tcx.has_attr(def_id, "rustc_object_lifetime_default") {
|
||||||
let object_lifetime_default_reprs: String =
|
let object_lifetime_default_reprs: String =
|
||||||
types.as_full_slice().iter().map(|t| {
|
types.iter().map(|t| {
|
||||||
match t.object_lifetime_default {
|
match t.object_lifetime_default {
|
||||||
ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
|
ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
|
||||||
d => format!("{:?}", d),
|
d => format!("{:?}", d),
|
||||||
@ -1512,9 +1517,12 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
tcx.alloc_generics(ty::Generics {
|
tcx.alloc_generics(ty::Generics {
|
||||||
|
parent: parent_def_id,
|
||||||
|
parent_regions: parent_regions as u32,
|
||||||
|
parent_types: parent_types as u32,
|
||||||
regions: regions,
|
regions: regions,
|
||||||
types: types,
|
types: types,
|
||||||
has_self: has_self
|
has_self: has_self || parent_has_self
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -2148,7 +2156,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
&mut input_parameters);
|
&mut input_parameters);
|
||||||
|
|
||||||
let ty_generics = generics_of_def_id(ccx, impl_def_id);
|
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) {
|
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
|
||||||
let param_ty = ty::ParamTy::for_def(ty_param);
|
let param_ty = ty::ParamTy::for_def(ty_param);
|
||||||
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
|
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
|
||||||
report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string());
|
report_unused_parameter(ccx, param.span, "type", ¶m_ty.to_string());
|
||||||
|
@ -301,8 +301,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
self.add_constraints_from_substs(
|
self.add_constraints_from_substs(
|
||||||
generics,
|
generics,
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
trait_def.generics.types.as_full_slice(),
|
&trait_def.generics.types,
|
||||||
trait_def.generics.regions.as_full_slice(),
|
&trait_def.generics.regions,
|
||||||
trait_ref.substs,
|
trait_ref.substs,
|
||||||
variance);
|
variance);
|
||||||
}
|
}
|
||||||
@ -359,16 +359,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
// README.md for a discussion on dep-graph management.
|
// README.md for a discussion on dep-graph management.
|
||||||
self.tcx().dep_graph.read(ItemVariances::to_dep_node(&def.did));
|
self.tcx().dep_graph.read(ItemVariances::to_dep_node(&def.did));
|
||||||
|
|
||||||
// All type parameters on enums and structs should be
|
|
||||||
// in the TypeSpace.
|
|
||||||
assert!(item_type.generics.types.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(
|
||||||
generics,
|
generics,
|
||||||
def.did,
|
def.did,
|
||||||
item_type.generics.types.as_full_slice(),
|
&item_type.generics.types,
|
||||||
item_type.generics.regions.as_full_slice(),
|
&item_type.generics.regions,
|
||||||
substs,
|
substs,
|
||||||
variance);
|
variance);
|
||||||
}
|
}
|
||||||
@ -385,8 +380,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
self.add_constraints_from_substs(
|
self.add_constraints_from_substs(
|
||||||
generics,
|
generics,
|
||||||
trait_ref.def_id,
|
trait_ref.def_id,
|
||||||
trait_def.generics.types.as_full_slice(),
|
&trait_def.generics.types,
|
||||||
trait_def.generics.regions.as_full_slice(),
|
&trait_def.generics.regions,
|
||||||
trait_ref.substs,
|
trait_ref.substs,
|
||||||
variance);
|
variance);
|
||||||
}
|
}
|
||||||
@ -406,7 +401,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::TyParam(ref data) => {
|
ty::TyParam(ref data) => {
|
||||||
let def_id = generics.types.get(data.space, data.idx as usize).def_id;
|
assert_eq!(data.space, subst::TypeSpace);
|
||||||
|
assert_eq!(generics.parent, None);
|
||||||
|
let def_id = generics.types[data.idx as usize].def_id;
|
||||||
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
|
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
|
||||||
match self.terms_cx.inferred_map.get(&node_id) {
|
match self.terms_cx.inferred_map.get(&node_id) {
|
||||||
Some(&index) => {
|
Some(&index) => {
|
||||||
@ -493,8 +490,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
variance: VarianceTermPtr<'a>) {
|
variance: VarianceTermPtr<'a>) {
|
||||||
match region {
|
match region {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => {
|
||||||
let def_id =
|
assert_eq!(data.space, subst::TypeSpace);
|
||||||
generics.regions.get(data.space, data.index as usize).def_id;
|
assert_eq!(generics.parent, None);
|
||||||
|
let def_id = generics.regions[data.index as usize].def_id;
|
||||||
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
|
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
|
||||||
if self.is_to_be_inferred(node_id) {
|
if self.is_to_be_inferred(node_id) {
|
||||||
let index = self.inferred_index(node_id);
|
let index = self.inferred_index(node_id);
|
||||||
|
@ -21,7 +21,6 @@ use rustc::hir::def::Def;
|
|||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir::print as pprust;
|
use rustc::hir::print as pprust;
|
||||||
use rustc::ty::{self, TyCtxt};
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::ty::subst;
|
|
||||||
|
|
||||||
use rustc_const_eval::lookup_const_by_id;
|
use rustc_const_eval::lookup_const_by_id;
|
||||||
|
|
||||||
@ -161,7 +160,7 @@ pub fn build_external_trait<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tc
|
|||||||
let def = tcx.lookup_trait_def(did);
|
let def = tcx.lookup_trait_def(did);
|
||||||
let trait_items = tcx.trait_items(did).clean(cx);
|
let trait_items = tcx.trait_items(did).clean(cx);
|
||||||
let predicates = tcx.lookup_predicates(did);
|
let predicates = tcx.lookup_predicates(did);
|
||||||
let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx);
|
let generics = (def.generics, &predicates).clean(cx);
|
||||||
let generics = filter_non_trait_generics(did, generics);
|
let generics = filter_non_trait_generics(did, generics);
|
||||||
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
|
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
|
||||||
clean::Trait {
|
clean::Trait {
|
||||||
@ -189,7 +188,7 @@ fn build_external_function<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx
|
|||||||
let predicates = tcx.lookup_predicates(did);
|
let predicates = tcx.lookup_predicates(did);
|
||||||
clean::Function {
|
clean::Function {
|
||||||
decl: decl,
|
decl: decl,
|
||||||
generics: (t.generics, &predicates, subst::FnSpace).clean(cx),
|
generics: (t.generics, &predicates).clean(cx),
|
||||||
unsafety: style,
|
unsafety: style,
|
||||||
constness: constness,
|
constness: constness,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
@ -209,7 +208,7 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
&[..] if variant.kind == ty::VariantKind::Tuple => doctree::Tuple,
|
&[..] if variant.kind == ty::VariantKind::Tuple => doctree::Tuple,
|
||||||
_ => doctree::Plain,
|
_ => doctree::Plain,
|
||||||
},
|
},
|
||||||
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
|
generics: (t.generics, &predicates).clean(cx),
|
||||||
fields: variant.fields.clean(cx),
|
fields: variant.fields.clean(cx),
|
||||||
fields_stripped: false,
|
fields_stripped: false,
|
||||||
}
|
}
|
||||||
@ -222,7 +221,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
match t.ty.sty {
|
match t.ty.sty {
|
||||||
ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => {
|
ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => {
|
||||||
return clean::EnumItem(clean::Enum {
|
return clean::EnumItem(clean::Enum {
|
||||||
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
|
generics: (t.generics, &predicates).clean(cx),
|
||||||
variants_stripped: false,
|
variants_stripped: false,
|
||||||
variants: edef.variants.clean(cx),
|
variants: edef.variants.clean(cx),
|
||||||
})
|
})
|
||||||
@ -232,7 +231,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
clean::TypedefItem(clean::Typedef {
|
clean::TypedefItem(clean::Typedef {
|
||||||
type_: t.ty.clean(cx),
|
type_: t.ty.clean(cx),
|
||||||
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
|
generics: (t.generics, &predicates).clean(cx),
|
||||||
}, false)
|
}, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,9 +392,11 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
|
|||||||
// because an associated type won't have generics on the LHS
|
// because an associated type won't have generics on the LHS
|
||||||
let typedef = clean::Typedef {
|
let typedef = clean::Typedef {
|
||||||
type_: assoc_ty.ty.unwrap().clean(cx),
|
type_: assoc_ty.ty.unwrap().clean(cx),
|
||||||
generics: (&ty::Generics::empty(),
|
generics: clean::Generics {
|
||||||
&ty::GenericPredicates::empty(),
|
lifetimes: vec![],
|
||||||
subst::TypeSpace).clean(cx)
|
type_params: vec![],
|
||||||
|
where_predicates: vec![]
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Some(clean::Item {
|
Some(clean::Item {
|
||||||
name: Some(assoc_ty.name.clean(cx)),
|
name: Some(assoc_ty.name.clean(cx)),
|
||||||
@ -434,7 +435,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
|
|||||||
provided_trait_methods: provided,
|
provided_trait_methods: provided,
|
||||||
trait_: trait_,
|
trait_: trait_,
|
||||||
for_: for_,
|
for_: for_,
|
||||||
generics: (ty.generics, &predicates, subst::TypeSpace).clean(cx),
|
generics: (ty.generics, &predicates).clean(cx),
|
||||||
items: trait_items,
|
items: trait_items,
|
||||||
polarity: polarity.map(|p| { p.clean(cx) }),
|
polarity: polarity.map(|p| { p.clean(cx) }),
|
||||||
}),
|
}),
|
||||||
|
@ -973,17 +973,16 @@ impl Clean<Generics> for hir::Generics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
|
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
|
||||||
&'a ty::GenericPredicates<'tcx>,
|
&'a ty::GenericPredicates<'tcx>) {
|
||||||
subst::ParamSpace) {
|
|
||||||
fn clean(&self, cx: &DocContext) -> Generics {
|
fn clean(&self, cx: &DocContext) -> Generics {
|
||||||
use self::WherePredicate as WP;
|
use self::WherePredicate as WP;
|
||||||
|
|
||||||
let (gens, preds, space) = *self;
|
let (gens, preds) = *self;
|
||||||
|
|
||||||
// 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().filter_map(|tp| {
|
let stripped_typarams = gens.types.iter().filter_map(|tp| {
|
||||||
if tp.name == keywords::SelfType.name() {
|
if tp.name == keywords::SelfType.name() {
|
||||||
assert_eq!(tp.index, 0);
|
assert_eq!(tp.index, 0);
|
||||||
None
|
None
|
||||||
@ -991,7 +990,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
|
|||||||
Some(tp.clean(cx))
|
Some(tp.clean(cx))
|
||||||
}
|
}
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| {
|
let stripped_lifetimes = gens.regions.iter().map(|rp| {
|
||||||
let mut srp = rp.clone();
|
let mut srp = rp.clone();
|
||||||
srp.bounds = Vec::new();
|
srp.bounds = Vec::new();
|
||||||
srp.clean(cx)
|
srp.clean(cx)
|
||||||
@ -1359,8 +1358,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
|
|||||||
predicates: self.predicates.predicates[method_start..].to_vec()
|
predicates: self.predicates.predicates[method_start..].to_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
let generics = (self.generics, &method_predicates,
|
let generics = (self.generics, &method_predicates).clean(cx);
|
||||||
subst::FnSpace).clean(cx);
|
|
||||||
let mut decl = (self.def_id, &self.fty.sig).clean(cx);
|
let mut decl = (self.def_id, &self.fty.sig).clean(cx);
|
||||||
match self.explicit_self {
|
match self.explicit_self {
|
||||||
ty::ExplicitSelfCategory::ByValue => {
|
ty::ExplicitSelfCategory::ByValue => {
|
||||||
@ -2929,7 +2927,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedType<'tcx> {
|
|||||||
// applied to this associated type in question.
|
// applied to this associated type in question.
|
||||||
let def = cx.tcx().lookup_trait_def(did);
|
let def = cx.tcx().lookup_trait_def(did);
|
||||||
let predicates = cx.tcx().lookup_predicates(did);
|
let predicates = cx.tcx().lookup_predicates(did);
|
||||||
let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx);
|
let generics = (def.generics, &predicates).clean(cx);
|
||||||
generics.where_predicates.iter().filter_map(|pred| {
|
generics.where_predicates.iter().filter_map(|pred| {
|
||||||
let (name, self_type, trait_, bounds) = match *pred {
|
let (name, self_type, trait_, bounds) = match *pred {
|
||||||
WherePredicate::BoundPredicate {
|
WherePredicate::BoundPredicate {
|
||||||
|
Loading…
Reference in New Issue
Block a user