Consolidate PathParameters and AngleBracketedParameterData
This commit is contained in:
parent
cca43a7f97
commit
494859e8dd
@ -650,8 +650,8 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
|
||||
_path_span: Span,
|
||||
path_parameters: &'v PathParameters) {
|
||||
walk_list!(visitor, visit_lifetime, &path_parameters.lifetimes);
|
||||
walk_list!(visitor, visit_ty, &path_parameters.types);
|
||||
walk_list!(visitor, visit_lifetime, path_parameters.lifetimes());
|
||||
walk_list!(visitor, visit_ty, path_parameters.types());
|
||||
walk_list!(visitor, visit_assoc_type_binding, &path_parameters.bindings);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ use hir::HirVec;
|
||||
use hir::map::{DefKey, DefPathData, Definitions};
|
||||
use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
|
||||
use hir::def::{Def, PathResolution, PerNS};
|
||||
use hir::GenericPathParam;
|
||||
use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
|
||||
use middle::cstore::CrateStore;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
@ -1037,6 +1038,20 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_param(&mut self,
|
||||
p: &GenericAngleBracketedParam,
|
||||
itctx: ImplTraitContext)
|
||||
-> GenericPathParam {
|
||||
match p {
|
||||
GenericAngleBracketedParam::Lifetime(lt) => {
|
||||
GenericPathParam::Lifetime(self.lower_lifetime(<))
|
||||
}
|
||||
GenericAngleBracketedParam::Type(ty) => {
|
||||
GenericPathParam::Type(self.lower_ty(&ty, itctx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
|
||||
let kind = match t.node {
|
||||
TyKind::Infer => hir::TyInfer,
|
||||
@ -1552,7 +1567,7 @@ impl<'a> LoweringContext<'a> {
|
||||
assert!(!def_id.is_local());
|
||||
let item_generics =
|
||||
self.cstore.item_generics_cloned_untracked(def_id, self.sess);
|
||||
let n = item_generics.own_counts().lifetimes;
|
||||
let n = item_generics.own_counts().lifetimes();
|
||||
self.type_def_lifetime_params.insert(def_id, n);
|
||||
n
|
||||
});
|
||||
@ -1671,7 +1686,7 @@ impl<'a> LoweringContext<'a> {
|
||||
) -> hir::PathSegment {
|
||||
let (mut parameters, infer_types) = if let Some(ref parameters) = segment.parameters {
|
||||
let msg = "parenthesized parameters may only be used with a trait";
|
||||
match **parameters {
|
||||
match **path_params {
|
||||
PathParameters::AngleBracketed(ref data) => {
|
||||
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
||||
}
|
||||
@ -1699,12 +1714,14 @@ impl<'a> LoweringContext<'a> {
|
||||
};
|
||||
|
||||
if !parameters.parenthesized && parameters.lifetimes.is_empty() {
|
||||
parameters.lifetimes = self.elided_path_lifetimes(path_span, expected_lifetimes);
|
||||
path_params.parameters = (0..expected_lifetimes).map(|_| {
|
||||
GenericPathParam::Lifetime(self.elided_lifetime(path_span))
|
||||
}).chain(path_params.parameters.into_iter()).collect();
|
||||
}
|
||||
|
||||
hir::PathSegment::new(
|
||||
self.lower_ident(segment.ident),
|
||||
parameters,
|
||||
path_params,
|
||||
infer_types,
|
||||
)
|
||||
}
|
||||
@ -1715,24 +1732,13 @@ impl<'a> LoweringContext<'a> {
|
||||
param_mode: ParamMode,
|
||||
itctx: ImplTraitContext,
|
||||
) -> (hir::PathParameters, bool) {
|
||||
let &AngleBracketedParameterData {
|
||||
ref lifetimes,
|
||||
ref types,
|
||||
ref bindings,
|
||||
..
|
||||
} = data;
|
||||
(
|
||||
hir::PathParameters {
|
||||
lifetimes: self.lower_lifetimes(lifetimes),
|
||||
types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
|
||||
bindings: bindings
|
||||
.iter()
|
||||
.map(|b| self.lower_ty_binding(b, itctx))
|
||||
.collect(),
|
||||
parenthesized: false,
|
||||
},
|
||||
types.is_empty() && param_mode == ParamMode::Optional,
|
||||
)
|
||||
let &AngleBracketedParameterData { ref parameters, ref bindings, .. } = data;
|
||||
(hir::PathParameters {
|
||||
parameters: parameters.iter().map(|p| self.lower_param(p, itctx)).collect(),
|
||||
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
|
||||
parenthesized: false,
|
||||
},
|
||||
types.is_empty() && param_mode == ParamMode::Optional)
|
||||
}
|
||||
|
||||
fn lower_parenthesized_parameter_data(
|
||||
@ -1769,8 +1775,7 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
(
|
||||
hir::PathParameters {
|
||||
lifetimes: hir::HirVec::new(),
|
||||
types: hir_vec![mk_tup(this, inputs, span)],
|
||||
parameters: hir_vec![GenericPathParam::Type(mk_tup(this, inputs, span))],
|
||||
bindings: hir_vec![
|
||||
hir::TypeBinding {
|
||||
id: this.next_id().node_id,
|
||||
@ -1971,7 +1976,7 @@ impl<'a> LoweringContext<'a> {
|
||||
|
||||
let def = hir::LifetimeDef {
|
||||
lifetime: self.lower_lifetime(&l.lifetime),
|
||||
bounds: self.lower_lifetimes(&l.bounds),
|
||||
bounds: l.bounds.iter().map(|l| self.lower_lifetime(l)).collect(),
|
||||
pure_wrt_drop: attr::contains_name(&l.attrs, "may_dangle"),
|
||||
in_band: false,
|
||||
};
|
||||
@ -1981,10 +1986,6 @@ impl<'a> LoweringContext<'a> {
|
||||
def
|
||||
}
|
||||
|
||||
fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
|
||||
lts.iter().map(|l| self.lower_lifetime(l)).collect()
|
||||
}
|
||||
|
||||
fn lower_generic_params(
|
||||
&mut self,
|
||||
params: &Vec<GenericParam>,
|
||||
|
@ -372,12 +372,16 @@ impl PathSegment {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum GenericPathParam {
|
||||
Lifetime(Lifetime),
|
||||
Type(P<Ty>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub struct PathParameters {
|
||||
/// The lifetime parameters for this path segment.
|
||||
pub lifetimes: HirVec<Lifetime>,
|
||||
/// The type parameters for this path segment, if present.
|
||||
pub types: HirVec<P<Ty>>,
|
||||
/// The generic parameters for this path segment.
|
||||
pub parameters: HirVec<GenericPathParam>,
|
||||
/// Bindings (equality constraints) on associated types, if present.
|
||||
/// E.g., `Foo<A=Bar>`.
|
||||
pub bindings: HirVec<TypeBinding>,
|
||||
@ -390,21 +394,19 @@ pub struct PathParameters {
|
||||
impl PathParameters {
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
lifetimes: HirVec::new(),
|
||||
types: HirVec::new(),
|
||||
parameters: HirVec::new(),
|
||||
bindings: HirVec::new(),
|
||||
parenthesized: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.lifetimes.is_empty() && self.types.is_empty() &&
|
||||
self.bindings.is_empty() && !self.parenthesized
|
||||
self.parameters.is_empty() && self.bindings.is_empty() && !self.parenthesized
|
||||
}
|
||||
|
||||
pub fn inputs(&self) -> &[P<Ty>] {
|
||||
if self.parenthesized {
|
||||
if let Some(ref ty) = self.types.get(0) {
|
||||
if let Some(ref ty) = self.types().get(0) {
|
||||
if let TyTup(ref tys) = ty.node {
|
||||
return tys;
|
||||
}
|
||||
@ -412,6 +414,26 @@ impl PathParameters {
|
||||
}
|
||||
bug!("PathParameters::inputs: not a `Fn(T) -> U`");
|
||||
}
|
||||
|
||||
pub fn lifetimes(&self) -> Vec<&Lifetime> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericPathParam::Lifetime(lt) = p {
|
||||
Some(lt)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn types(&self) -> Vec<&P<Ty>> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericPathParam::Type(ty) = p {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// The AST represents all type param bounds as types.
|
||||
|
@ -25,6 +25,7 @@ use syntax_pos::{self, BytePos, FileName};
|
||||
|
||||
use hir;
|
||||
use hir::{PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier, RangeEnd};
|
||||
use hir::GenericPathParam;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::io::{self, Write, Read};
|
||||
@ -1269,8 +1270,7 @@ impl<'a> State<'a> {
|
||||
self.print_name(segment.name)?;
|
||||
|
||||
segment.with_parameters(|parameters| {
|
||||
if !parameters.lifetimes.is_empty() ||
|
||||
!parameters.types.is_empty() ||
|
||||
if !parameters.parameters.is_empty() ||
|
||||
!parameters.bindings.is_empty()
|
||||
{
|
||||
self.print_path_parameters(¶meters, segment.infer_types, true)
|
||||
@ -1707,18 +1707,18 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
fn print_path_parameters(&mut self,
|
||||
parameters: &hir::PathParameters,
|
||||
path_params: &hir::PathParameters,
|
||||
infer_types: bool,
|
||||
colons_before_params: bool)
|
||||
-> io::Result<()> {
|
||||
if parameters.parenthesized {
|
||||
if path_params.parenthesized {
|
||||
self.s.word("(")?;
|
||||
self.commasep(Inconsistent, parameters.inputs(), |s, ty| s.print_type(&ty))?;
|
||||
self.commasep(Inconsistent, path_params.inputs(), |s, ty| s.print_type(&ty))?;
|
||||
self.s.word(")")?;
|
||||
|
||||
self.space_if_not_bol()?;
|
||||
self.word_space("->")?;
|
||||
self.print_type(¶meters.bindings[0].ty)?;
|
||||
self.print_type(&path_params.bindings[0].ty)?;
|
||||
} else {
|
||||
let start = if colons_before_params { "::<" } else { "<" };
|
||||
let empty = Cell::new(true);
|
||||
@ -1731,17 +1731,27 @@ impl<'a> State<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
if !parameters.lifetimes.iter().all(|lt| lt.is_elided()) {
|
||||
for lifetime in ¶meters.lifetimes {
|
||||
start_or_comma(self)?;
|
||||
self.print_lifetime(lifetime)?;
|
||||
let elide_lifetimes = path_params.parameters.iter().all(|p| {
|
||||
if let GenericPathParam::Lifetime(lt) = p {
|
||||
if !lt.is_elided() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
});
|
||||
|
||||
if !parameters.types.is_empty() {
|
||||
start_or_comma(self)?;
|
||||
self.commasep(Inconsistent, ¶meters.types, |s, ty| s.print_type(&ty))?;
|
||||
}
|
||||
self.commasep(Inconsistent, &path_params.parameters, |s, p| {
|
||||
match p {
|
||||
GenericPathParam::Lifetime(lt) => {
|
||||
if !elide_lifetimes {
|
||||
s.print_lifetime(lt)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
GenericPathParam::Type(ty) => s.print_type(ty),
|
||||
}
|
||||
})?;
|
||||
|
||||
// FIXME(eddyb) This would leak into error messages, e.g.:
|
||||
// "non-exhaustive patterns: `Some::<..>(_)` not covered".
|
||||
@ -1750,7 +1760,7 @@ impl<'a> State<'a> {
|
||||
self.s.word("..")?;
|
||||
}
|
||||
|
||||
for binding in parameters.bindings.iter() {
|
||||
for binding in path_params.bindings.iter() {
|
||||
start_or_comma(self)?;
|
||||
self.print_name(binding.name)?;
|
||||
self.s.space()?;
|
||||
|
@ -180,9 +180,13 @@ impl_stable_hash_for!(struct hir::PathSegment {
|
||||
parameters
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(enum hir::GenericPathParam {
|
||||
Lifetime(lt),
|
||||
Type(ty)
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct hir::PathParameters {
|
||||
lifetimes,
|
||||
types,
|
||||
parameters,
|
||||
bindings,
|
||||
parenthesized
|
||||
});
|
||||
|
@ -155,7 +155,7 @@ impl Region {
|
||||
}
|
||||
}
|
||||
|
||||
fn subst(self, params: &[hir::Lifetime], map: &NamedRegionMap) -> Option<Region> {
|
||||
fn subst(self, params: Vec<&hir::Lifetime>, map: &NamedRegionMap) -> Option<Region> {
|
||||
if let Region::EarlyBound(index, _, _) = self {
|
||||
params
|
||||
.get(index as usize)
|
||||
@ -820,7 +820,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
if lifetime_ref.is_elided() {
|
||||
self.resolve_elided_lifetimes(slice::from_ref(lifetime_ref), false);
|
||||
self.resolve_elided_lifetimes(vec![lifetime_ref], false);
|
||||
return;
|
||||
}
|
||||
if lifetime_ref.is_static() {
|
||||
@ -1613,10 +1613,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
if params.lifetimes.iter().all(|l| l.is_elided()) {
|
||||
self.resolve_elided_lifetimes(¶ms.lifetimes, true);
|
||||
if params.lifetimes().iter().all(|l| l.is_elided()) {
|
||||
self.resolve_elided_lifetimes(params.lifetimes(), true);
|
||||
} else {
|
||||
for l in ¶ms.lifetimes {
|
||||
for l in ¶ms.lifetimes() {
|
||||
self.visit_lifetime(l);
|
||||
}
|
||||
}
|
||||
@ -1688,13 +1688,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
} else {
|
||||
Some(Region::Static)
|
||||
},
|
||||
Set1::One(r) => r.subst(¶ms.lifetimes, map),
|
||||
Set1::One(r) => r.subst(params.lifetimes(), map),
|
||||
Set1::Many => None,
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
|
||||
for (i, ty) in params.types.iter().enumerate() {
|
||||
for (i, ty) in params.types().iter().enumerate() {
|
||||
if let Some(<) = object_lifetime_defaults.get(i) {
|
||||
let scope = Scope::ObjectLifetimeDefault {
|
||||
lifetime: lt,
|
||||
@ -1981,7 +1981,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_elided_lifetimes(&mut self, lifetime_refs: &'tcx [hir::Lifetime], deprecated: bool) {
|
||||
fn resolve_elided_lifetimes(&mut self,
|
||||
lifetime_refs: Vec<&'tcx hir::Lifetime>,
|
||||
deprecated: bool) {
|
||||
if lifetime_refs.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
@ -885,6 +885,73 @@ pub struct GenericParamCount {
|
||||
pub types: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum GenericParameterDef {
|
||||
Lifetime(RegionParameterDef),
|
||||
Type(TypeParameterDef),
|
||||
}
|
||||
|
||||
impl GenericParameterDef {
|
||||
pub fn index(&self) -> u32 {
|
||||
match self {
|
||||
GenericParameterDef::Lifetime(lt) => lt.index,
|
||||
GenericParameterDef::Type(ty) => ty.index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub enum KindIndex {
|
||||
Lifetime,
|
||||
Type,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct KindIndexed<L, T> {
|
||||
pub lt: L,
|
||||
pub ty: T,
|
||||
}
|
||||
|
||||
impl<T> KindIndexed<T, T> {
|
||||
pub fn get(&self, idx: KindIndex) -> &T {
|
||||
match idx {
|
||||
KindIndex::Lifetime => &self.lt,
|
||||
KindIndex::Type => &self.ty,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> KindIndexIterator<T> {
|
||||
KindIndexIterator {
|
||||
index: self,
|
||||
next: Some(KindIndex::Lifetime),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct KindIndexIterator<'a, T: 'a> {
|
||||
pub index: &'a KindIndexed<T, T>,
|
||||
pub next: Option<KindIndex>,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for KindIndexIterator<'a, T> {
|
||||
type Item = &'a T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.next {
|
||||
Some(KindIndex::Lifetime) => {
|
||||
self.next = Some(KindIndex::Type);
|
||||
Some(&self.index.lt)
|
||||
}
|
||||
Some(KindIndex::Type) => {
|
||||
self.next = None;
|
||||
Some(&self.index.ty)
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about the formal type/lifetime parameters associated
|
||||
/// with an item or method. Analogous to hir::Generics.
|
||||
///
|
||||
@ -942,6 +1009,34 @@ impl<'a, 'gcx, 'tcx> Generics {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lifetimes(&self) -> Vec<&RegionParameterDef> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericParameterDef::Lifetime(lt) = p {
|
||||
Some(lt)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn types(&self) -> Vec<&TypeParameterDef> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericParameterDef::Type(ty) = p {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn parent_lifetimes(&self) -> u32 {
|
||||
*self.parent_parameters.get(KindIndex::Lifetime)
|
||||
}
|
||||
|
||||
pub fn parent_types(&self) -> u32 {
|
||||
*self.parent_parameters.get(KindIndex::Type)
|
||||
}
|
||||
|
||||
pub fn region_param(&'tcx self,
|
||||
param: &EarlyBoundRegion,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
|
@ -680,7 +680,7 @@ impl<'a> ReplaceBodyWithLoop<'a> {
|
||||
match seg.parameters.as_ref().map(|p| &**p) {
|
||||
None => false,
|
||||
Some(&ast::PathParameters::AngleBracketed(ref data)) =>
|
||||
any_involves_impl_trait(data.types.iter()) ||
|
||||
any_involves_impl_trait(data.types().into_iter()) ||
|
||||
any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty)),
|
||||
Some(&ast::PathParameters::Parenthesized(ref data)) =>
|
||||
any_involves_impl_trait(data.inputs.iter()) ||
|
||||
|
@ -822,7 +822,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
for seg in &path.segments {
|
||||
if let Some(ref params) = seg.parameters {
|
||||
match **params {
|
||||
ast::PathParameters::AngleBracketed(ref data) => for t in &data.types {
|
||||
ast::PathParameters::AngleBracketed(ref data) => for t in data.types() {
|
||||
self.visit_ty(t);
|
||||
},
|
||||
ast::PathParameters::Parenthesized(ref data) => {
|
||||
@ -907,7 +907,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||
// Explicit types in the turbo-fish.
|
||||
if let Some(ref params) = seg.parameters {
|
||||
if let ast::PathParameters::AngleBracketed(ref data) = **params {
|
||||
for t in &data.types {
|
||||
for t in data.types() {
|
||||
self.visit_ty(t);
|
||||
}
|
||||
}
|
||||
|
@ -214,8 +214,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// region with the current anon region binding (in other words,
|
||||
// whatever & would get replaced with).
|
||||
let decl_generics = tcx.generics_of(def_id);
|
||||
let ty_provided = parameters.types.len();
|
||||
let lt_provided = parameters.lifetimes.len();
|
||||
let ty_provided = parameters.types().len();
|
||||
let lt_provided = parameters.lifetimes().len();
|
||||
|
||||
let mut lt_accepted = 0;
|
||||
let mut ty_params = ParamRange { required: 0, accepted: 0 };
|
||||
@ -269,7 +269,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let i = param.index as usize - own_self;
|
||||
if let Some(lifetime) = parameters.lifetimes.get(i) {
|
||||
if let Some(lifetime) = parameters.lifetimes().get(i) {
|
||||
self.ast_region_to_region(lifetime, Some(param)).into()
|
||||
} else {
|
||||
tcx.types.re_static.into()
|
||||
@ -286,7 +286,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
let i = i - (lt_accepted + own_self);
|
||||
if i < ty_provided {
|
||||
// A provided type parameter.
|
||||
self.ast_ty_to_ty(¶meters.types[i]).into()
|
||||
self.ast_ty_to_ty(¶meters.types()[i]).into()
|
||||
} else if infer_types {
|
||||
// No type parameters were provided, we can infer all.
|
||||
if !default_needs_object_self(param) {
|
||||
@ -970,23 +970,27 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
|
||||
for segment in segments {
|
||||
segment.with_parameters(|parameters| {
|
||||
for typ in ¶meters.types {
|
||||
struct_span_err!(self.tcx().sess, typ.span, E0109,
|
||||
"type parameters are not allowed on this type")
|
||||
.span_label(typ.span, "type parameter not allowed")
|
||||
.emit();
|
||||
segment.with_parameters(|params| {
|
||||
for p in ¶ms.parameters {
|
||||
let (mut span_err, span, kind) = match p {
|
||||
hir::GenericPathParam::Lifetime(lt) => {
|
||||
(struct_span_err!(self.tcx().sess, lt.span, E0110,
|
||||
"lifetime parameters are not allowed on this type"),
|
||||
lt.span,
|
||||
"lifetime")
|
||||
}
|
||||
hir::GenericPathParam::Type(ty) => {
|
||||
(struct_span_err!(self.tcx().sess, ty.span, E0109,
|
||||
"type parameters are not allowed on this type"),
|
||||
ty.span,
|
||||
"type")
|
||||
}
|
||||
};
|
||||
span_err.span_label(span, format!("{} parameter not allowed", kind))
|
||||
.emit();
|
||||
break;
|
||||
}
|
||||
for lifetime in ¶meters.lifetimes {
|
||||
struct_span_err!(self.tcx().sess, lifetime.span, E0110,
|
||||
"lifetime parameters are not allowed on this type")
|
||||
.span_label(lifetime.span,
|
||||
"lifetime parameter not allowed on this type")
|
||||
.emit();
|
||||
break;
|
||||
}
|
||||
for binding in ¶meters.bindings {
|
||||
for binding in ¶ms.bindings {
|
||||
self.prohibit_projection(binding.span);
|
||||
break;
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
if let Some(lifetime) = provided.as_ref().and_then(|p| {
|
||||
p.lifetimes.get(i - parent_substs.len())
|
||||
p.lifetimes().get(i - parent_substs.len())
|
||||
}) {
|
||||
return AstConv::ast_region_to_region(
|
||||
self.fcx, lifetime, Some(param)).into();
|
||||
@ -339,7 +339,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
GenericParamDefKind::Type {..} => {
|
||||
if let Some(ast_ty) = provided.as_ref().and_then(|p| {
|
||||
p.types.get(i - parent_substs.len() - own_counts.lifetimes)
|
||||
p.types().get(i - parent_substs.len() - own_counts.lifetimes)
|
||||
}) {
|
||||
return self.to_ty(ast_ty).into();
|
||||
}
|
||||
@ -347,6 +347,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
self.var_for_def(self.span, param)
|
||||
}
|
||||
self.type_var_for_def(self.span, def, cur_substs)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -4833,8 +4833,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let lifetimes = segment.map_or(&[][..], |(s, _)| {
|
||||
s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
|
||||
let lifetimes = segment.map_or(vec![], |(s, _)| {
|
||||
s.parameters.as_ref().map_or(vec![], |p| p.lifetimes())
|
||||
});
|
||||
|
||||
if let Some(lifetime) = lifetimes.get(i) {
|
||||
@ -4844,8 +4844,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Type {..} => {
|
||||
let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
|
||||
(s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
|
||||
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
|
||||
(s.parameters.as_ref().map_or(vec![], |p| |p| p.types()), s.infer_types)
|
||||
});
|
||||
|
||||
// Skip over the lifetimes in the same segment.
|
||||
@ -4961,10 +4961,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
is_method_call: bool,
|
||||
supress_mismatch_error: bool) {
|
||||
let (lifetimes, types, infer_types, bindings) = segment.map_or(
|
||||
(&[][..], &[][..], true, &[][..]),
|
||||
(vec![], vec![], true, &[][..]),
|
||||
|(s, _)| s.parameters.as_ref().map_or(
|
||||
(&[][..], &[][..], s.infer_types, &[][..]),
|
||||
|p| (&p.lifetimes[..], &p.types[..],
|
||||
(vec![], vec![], s.infer_types, &[][..]),
|
||||
|p| (p.lifetimes(), p.types(),
|
||||
s.infer_types, &p.bindings[..])));
|
||||
let infer_lifetimes = lifetimes.len() == 0;
|
||||
|
||||
|
@ -973,6 +973,13 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
.map(|param| (param.def_id, param.index))
|
||||
.collect();
|
||||
|
||||
let parent_parameters = ty::KindIndexed { lt: parent_regions, ty: parent_types };
|
||||
let lifetimes: Vec<ty::GenericParameterDef> =
|
||||
regions.into_iter().map(|lt| ty::GenericParameterDef::Lifetime(lt)).collect();
|
||||
let types: Vec<ty::GenericParameterDef> =
|
||||
types.into_iter().map(|ty| ty::GenericParameterDef::Type(ty)).collect();
|
||||
let parameters = lifetimes.into_iter().chain(types.into_iter()).collect();
|
||||
|
||||
tcx.alloc_generics(ty::Generics {
|
||||
parent: parent_def_id,
|
||||
parent_count,
|
||||
|
@ -167,21 +167,47 @@ impl PathParameters {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||
pub enum GenericAngleBracketedParam {
|
||||
Lifetime(Lifetime),
|
||||
Type(P<Ty>),
|
||||
}
|
||||
|
||||
/// A path like `Foo<'a, T>`
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
|
||||
pub struct AngleBracketedParameterData {
|
||||
/// Overall span
|
||||
pub span: Span,
|
||||
/// The lifetime parameters for this path segment.
|
||||
pub lifetimes: Vec<Lifetime>,
|
||||
/// The type parameters for this path segment, if present.
|
||||
pub types: Vec<P<Ty>>,
|
||||
/// The parameters for this path segment.
|
||||
pub parameters: Vec<GenericAngleBracketedParam>,
|
||||
/// Bindings (equality constraints) on associated types, if present.
|
||||
///
|
||||
/// E.g., `Foo<A=Bar>`.
|
||||
pub bindings: Vec<TypeBinding>,
|
||||
}
|
||||
|
||||
impl AngleBracketedParameterData {
|
||||
pub fn lifetimes(&self) -> Vec<&Lifetime> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericAngleBracketedParam::Lifetime(lt) = p {
|
||||
Some(lt)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn types(&self) -> Vec<&P<Ty>> {
|
||||
self.parameters.iter().filter_map(|p| {
|
||||
if let GenericAngleBracketedParam::Type(ty) = p {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
|
||||
fn into(self) -> Option<P<PathParameters>> {
|
||||
Some(P(PathParameters::AngleBracketed(self)))
|
||||
|
@ -30,10 +30,9 @@ pub trait AstBuilder {
|
||||
fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path;
|
||||
fn path_all(&self, sp: Span,
|
||||
global: bool,
|
||||
idents: Vec<ast::Ident> ,
|
||||
lifetimes: Vec<ast::Lifetime>,
|
||||
types: Vec<P<ast::Ty>>,
|
||||
bindings: Vec<ast::TypeBinding> )
|
||||
idents: Vec<ast::Ident>,
|
||||
parameters: Vec<ast::GenericAngleBracketedParam>,
|
||||
bindings: Vec<ast::TypeBinding>)
|
||||
-> ast::Path;
|
||||
|
||||
fn qpath(&self, self_type: P<ast::Ty>,
|
||||
@ -43,8 +42,7 @@ pub trait AstBuilder {
|
||||
fn qpath_all(&self, self_type: P<ast::Ty>,
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident,
|
||||
lifetimes: Vec<ast::Lifetime>,
|
||||
types: Vec<P<ast::Ty>>,
|
||||
parameters: Vec<ast::GenericAngleBracketedParam>,
|
||||
bindings: Vec<ast::TypeBinding>)
|
||||
-> (ast::QSelf, ast::Path);
|
||||
|
||||
@ -304,20 +302,19 @@ pub trait AstBuilder {
|
||||
|
||||
impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
|
||||
self.path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new())
|
||||
self.path_all(span, false, strs, Vec::new(), Vec::new())
|
||||
}
|
||||
fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
|
||||
self.path(span, vec![id])
|
||||
}
|
||||
fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
|
||||
self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
|
||||
self.path_all(span, true, strs, Vec::new(), Vec::new())
|
||||
}
|
||||
fn path_all(&self,
|
||||
span: Span,
|
||||
global: bool,
|
||||
mut idents: Vec<ast::Ident> ,
|
||||
lifetimes: Vec<ast::Lifetime>,
|
||||
types: Vec<P<ast::Ty>>,
|
||||
parameters: Vec<ast::GenericAngleBracketedParam>,
|
||||
bindings: Vec<ast::TypeBinding> )
|
||||
-> ast::Path {
|
||||
let last_ident = idents.pop().unwrap();
|
||||
@ -326,8 +323,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
segments.extend(idents.into_iter().map(|ident| {
|
||||
ast::PathSegment::from_ident(ident.with_span_pos(span))
|
||||
}));
|
||||
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
|
||||
ast::AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
|
||||
let parameters = if !parameters.is_empty() !bindings.is_empty() {
|
||||
ast::AngleBracketedParameterData { parameters, bindings, span }.into()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -349,7 +346,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident)
|
||||
-> (ast::QSelf, ast::Path) {
|
||||
self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
|
||||
self.qpath_all(self_type, trait_path, ident, vec![], vec![])
|
||||
}
|
||||
|
||||
/// Constructs a qualified path.
|
||||
@ -359,13 +356,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
self_type: P<ast::Ty>,
|
||||
trait_path: ast::Path,
|
||||
ident: ast::Ident,
|
||||
lifetimes: Vec<ast::Lifetime>,
|
||||
types: Vec<P<ast::Ty>>,
|
||||
parameters: Vec<ast::GenericAngleBracketedParam>,
|
||||
bindings: Vec<ast::TypeBinding>)
|
||||
-> (ast::QSelf, ast::Path) {
|
||||
let mut path = trait_path;
|
||||
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
|
||||
ast::AngleBracketedParameterData { lifetimes, types, bindings, span: ident.span }.into()
|
||||
let parameters = if !parameters.is_empty() || !bindings.is_empty() {
|
||||
ast::AngleBracketedParameterData { parameters, bindings, span: ident.span }.into()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -428,8 +424,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
self.path_all(DUMMY_SP,
|
||||
true,
|
||||
self.std_path(&["option", "Option"]),
|
||||
Vec::new(),
|
||||
vec![ ty ],
|
||||
vec![ ast::GenericAngleBracketedParam::Type(ty) ],
|
||||
Vec::new()))
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,10 @@ pub trait Folder : Sized {
|
||||
noop_fold_exprs(es, self)
|
||||
}
|
||||
|
||||
fn fold_param(&mut self, p: GenericAngleBracketedParam) -> GenericAngleBracketedParam {
|
||||
noop_fold_param(p, self)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
|
||||
noop_fold_ty(t, self)
|
||||
}
|
||||
@ -353,6 +357,19 @@ pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBindi
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_param<T: Folder>(p: GenericAngleBracketedParam,
|
||||
fld: &mut T)
|
||||
-> GenericAngleBracketedParam {
|
||||
match p {
|
||||
GenericAngleBracketedParam::Lifetime(lt) => {
|
||||
GenericAngleBracketedParam::Lifetime(noop_fold_lifetime(lt, fld))
|
||||
}
|
||||
GenericAngleBracketedParam::Type(ty) => {
|
||||
GenericAngleBracketedParam::Type(noop_fold_ty(ty, fld))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
||||
t.map(|Ty {id, node, span}| Ty {
|
||||
id: fld.new_id(id),
|
||||
@ -469,9 +486,8 @@ pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedP
|
||||
fld: &mut T)
|
||||
-> AngleBracketedParameterData
|
||||
{
|
||||
let AngleBracketedParameterData { lifetimes, types, bindings, span } = data;
|
||||
AngleBracketedParameterData { lifetimes: lifetimes.move_map(|l| noop_fold_lifetime(l, fld)),
|
||||
types: types.move_map(|ty| fld.fold_ty(ty)),
|
||||
let AngleBracketedParameterData { parameters, bindings, span } = data;
|
||||
AngleBracketedParameterData { parameters: parameters.move_map(|p| fld.fold_param(p)),
|
||||
bindings: bindings.move_map(|b| fld.fold_ty_binding(b)),
|
||||
span: fld.new_span(span) }
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ use ast::{Expr, ExprKind, RangeLimits};
|
||||
use ast::{Field, FnDecl};
|
||||
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
|
||||
use ast::GenericParam;
|
||||
use ast::GenericAngleBracketedParam;
|
||||
use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
|
||||
use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind};
|
||||
use ast::Local;
|
||||
@ -1971,10 +1972,10 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let parameters = if self.eat_lt() {
|
||||
// `<'a, T, A = U>`
|
||||
let (lifetimes, types, bindings) = self.parse_generic_args()?;
|
||||
let (parameters, bindings) = self.parse_generic_args()?;
|
||||
self.expect_gt()?;
|
||||
let span = lo.to(self.prev_span);
|
||||
AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
|
||||
AngleBracketedParameterData { parameters, bindings, span }.into()
|
||||
} else {
|
||||
// `(T, U) -> R`
|
||||
self.bump(); // `(`
|
||||
@ -4936,16 +4937,16 @@ impl<'a> Parser<'a> {
|
||||
|
||||
/// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
|
||||
/// possibly including trailing comma.
|
||||
fn parse_generic_args(&mut self) -> PResult<'a, (Vec<Lifetime>, Vec<P<Ty>>, Vec<TypeBinding>)> {
|
||||
let mut lifetimes = Vec::new();
|
||||
let mut types = Vec::new();
|
||||
fn parse_generic_args(&mut self)
|
||||
-> PResult<'a, (Vec<GenericAngleBracketedParam>, Vec<TypeBinding>)> {
|
||||
let mut parameters = Vec::new();
|
||||
let mut bindings = Vec::new();
|
||||
let mut seen_type = false;
|
||||
let mut seen_binding = false;
|
||||
loop {
|
||||
if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
|
||||
// Parse lifetime argument.
|
||||
lifetimes.push(self.expect_lifetime());
|
||||
parameters.push(GenericAngleBracketedParam::Lifetime(self.expect_lifetime()));
|
||||
if seen_type || seen_binding {
|
||||
self.span_err(self.prev_span,
|
||||
"lifetime parameters must be declared prior to type parameters");
|
||||
@ -4965,11 +4966,12 @@ impl<'a> Parser<'a> {
|
||||
seen_binding = true;
|
||||
} else if self.check_type() {
|
||||
// Parse type argument.
|
||||
types.push(self.parse_ty()?);
|
||||
let ty_param = self.parse_ty()?;
|
||||
if seen_binding {
|
||||
self.span_err(types[types.len() - 1].span,
|
||||
self.span_err(ty_param.span,
|
||||
"type parameters must be declared prior to associated type bindings");
|
||||
}
|
||||
parameters.push(GenericAngleBracketedParam::Type(ty_param));
|
||||
seen_type = true;
|
||||
} else {
|
||||
break
|
||||
@ -4979,7 +4981,7 @@ impl<'a> Parser<'a> {
|
||||
break
|
||||
}
|
||||
}
|
||||
Ok((lifetimes, types, bindings))
|
||||
Ok((parameters, bindings))
|
||||
}
|
||||
|
||||
/// Parses an optional `where` clause and places it in `generics`.
|
||||
|
@ -13,7 +13,7 @@ pub use self::AnnNode::*;
|
||||
use rustc_target::spec::abi::{self, Abi};
|
||||
use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
||||
use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{Attribute, MacDelimiter};
|
||||
use ast::{Attribute, MacDelimiter, GenericAngleBracketedParam};
|
||||
use util::parser::{self, AssocOp, Fixity};
|
||||
use attr;
|
||||
use codemap::{self, CodeMap};
|
||||
@ -1017,6 +1017,13 @@ impl<'a> State<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_param(&mut self, param: &GenericAngleBracketedParam) -> io::Result<()> {
|
||||
match param {
|
||||
GenericAngleBracketedParam::Lifetime(lt) => self.print_lifetime(lt),
|
||||
GenericAngleBracketedParam::Type(ty) => self.print_type(ty),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
|
||||
self.maybe_print_comment(ty.span.lo())?;
|
||||
self.ibox(0)?;
|
||||
@ -2474,25 +2481,9 @@ impl<'a> State<'a> {
|
||||
ast::PathParameters::AngleBracketed(ref data) => {
|
||||
self.s.word("<")?;
|
||||
|
||||
let mut comma = false;
|
||||
for lifetime in &data.lifetimes {
|
||||
if comma {
|
||||
self.word_space(",")?
|
||||
}
|
||||
self.print_lifetime(lifetime)?;
|
||||
comma = true;
|
||||
}
|
||||
self.commasep(Inconsistent, &data.parameters, |s, p| s.print_param(p))?;
|
||||
|
||||
if !data.types.is_empty() {
|
||||
if comma {
|
||||
self.word_space(",")?
|
||||
}
|
||||
self.commasep(
|
||||
Inconsistent,
|
||||
&data.types,
|
||||
|s, ty| s.print_type(ty))?;
|
||||
comma = true;
|
||||
}
|
||||
let mut comma = data.parameters.len() != 0;
|
||||
|
||||
for binding in data.bindings.iter() {
|
||||
if comma {
|
||||
|
@ -387,8 +387,8 @@ pub fn walk_path_parameters<'a, V>(visitor: &mut V,
|
||||
{
|
||||
match *path_parameters {
|
||||
PathParameters::AngleBracketed(ref data) => {
|
||||
walk_list!(visitor, visit_ty, &data.types);
|
||||
walk_list!(visitor, visit_lifetime, &data.lifetimes);
|
||||
walk_list!(visitor, visit_lifetime, data.lifetimes());
|
||||
walk_list!(visitor, visit_ty, data.types());
|
||||
walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
|
||||
}
|
||||
PathParameters::Parenthesized(ref data) => {
|
||||
|
@ -13,6 +13,7 @@ use deriving::generic::*;
|
||||
use deriving::generic::ty::*;
|
||||
|
||||
use syntax::ast::{self, Expr, Generics, ItemKind, MetaItem, VariantData};
|
||||
use syntax::ast::GenericAngleBracketedParam;
|
||||
use syntax::attr;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
@ -123,7 +124,7 @@ fn cs_clone_shallow(name: &str,
|
||||
let span = span.with_ctxt(cx.backtrace());
|
||||
let assert_path = cx.path_all(span, true,
|
||||
cx.std_path(&["clone", helper_name]),
|
||||
vec![], vec![ty], vec![]);
|
||||
vec![GenericAngleBracketedParam::Type(ty)], vec![]);
|
||||
stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
|
||||
}
|
||||
fn process_variant(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>, variant: &VariantData) {
|
||||
|
@ -12,7 +12,7 @@ use deriving::path_std;
|
||||
use deriving::generic::*;
|
||||
use deriving::generic::ty::*;
|
||||
|
||||
use syntax::ast::{self, Expr, MetaItem};
|
||||
use syntax::ast::{self, Expr, MetaItem, GenericAngleBracketedParam};
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::ptr::P;
|
||||
@ -62,7 +62,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
|
||||
let span = span.with_ctxt(cx.backtrace());
|
||||
let assert_path = cx.path_all(span, true,
|
||||
cx.std_path(&["cmp", helper_name]),
|
||||
vec![], vec![ty], vec![]);
|
||||
vec![GenericAngleBracketedParam::Type(ty)], vec![]);
|
||||
stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
|
||||
}
|
||||
fn process_variant(cx: &mut ExtCtxt, stmts: &mut Vec<ast::Stmt>, variant: &ast::VariantData) {
|
||||
|
@ -192,10 +192,8 @@ use std::collections::HashSet;
|
||||
use std::vec;
|
||||
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::ast::{
|
||||
self, BinOpKind, EnumDef, Expr, GenericParam, Generics, Ident, PatKind, VariantData
|
||||
};
|
||||
|
||||
use syntax::ast::{self, BinOpKind, EnumDef, Expr, GenericParam, Generics, Ident, PatKind};
|
||||
use syntax::ast::{VariantData, GenericAngleBracketedParam};
|
||||
use syntax::attr;
|
||||
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
@ -667,7 +665,7 @@ impl<'a> TraitDef<'a> {
|
||||
let trait_ref = cx.trait_ref(trait_path);
|
||||
|
||||
// Create the type parameters on the `self` path.
|
||||
let self_ty_params = generics.params
|
||||
let self_ty_params: Vec<P<ast::Ty>> = generics.params
|
||||
.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParam::Type(ref ty_param)
|
||||
@ -684,12 +682,17 @@ impl<'a> TraitDef<'a> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let self_params = self_lifetimes.into_iter()
|
||||
.map(|lt| GenericAngleBracketedParam::Lifetime(lt))
|
||||
.chain(self_ty_params.into_iter().map(|ty|
|
||||
GenericAngleBracketedParam::Type(ty)))
|
||||
.collect();
|
||||
|
||||
// Create the type of `self`.
|
||||
let self_type = cx.ty_path(cx.path_all(self.span,
|
||||
false,
|
||||
vec![type_ident],
|
||||
self_lifetimes,
|
||||
self_ty_params,
|
||||
self_params,
|
||||
Vec::new()));
|
||||
|
||||
let attr = cx.attribute(self.span,
|
||||
|
@ -15,7 +15,7 @@ pub use self::PtrTy::*;
|
||||
pub use self::Ty::*;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Expr, GenericParam, Generics, Ident, SelfKind};
|
||||
use syntax::ast::{Expr, GenericParam, Generics, Ident, SelfKind, GenericAngleBracketedParam};
|
||||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::codemap::{respan, DUMMY_SP};
|
||||
@ -86,15 +86,20 @@ impl<'a> Path<'a> {
|
||||
-> ast::Path {
|
||||
let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
|
||||
let lt = mk_lifetimes(cx, span, &self.lifetime);
|
||||
let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
|
||||
let tys: Vec<P<ast::Ty>> =
|
||||
self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
|
||||
let params = lt.into_iter()
|
||||
.map(|lt| GenericAngleBracketedParam::Lifetime(lt))
|
||||
.chain(tys.into_iter().map(|ty| GenericAngleBracketedParam::Type(ty)))
|
||||
.collect();
|
||||
|
||||
match self.kind {
|
||||
PathKind::Global => cx.path_all(span, true, idents, lt, tys, Vec::new()),
|
||||
PathKind::Local => cx.path_all(span, false, idents, lt, tys, Vec::new()),
|
||||
PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
|
||||
PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
|
||||
PathKind::Std => {
|
||||
let def_site = DUMMY_SP.apply_mark(cx.current_expansion.mark);
|
||||
idents.insert(0, Ident::new(keywords::DollarCrate.name(), def_site));
|
||||
cx.path_all(span, false, idents, lt, tys, Vec::new())
|
||||
cx.path_all(span, false, idents, params, Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,7 +189,7 @@ impl<'a> Ty<'a> {
|
||||
-> ast::Path {
|
||||
match *self {
|
||||
Self_ => {
|
||||
let self_params = self_generics.params
|
||||
let ty_params: Vec<P<ast::Ty>> = self_generics.params
|
||||
.iter()
|
||||
.filter_map(|param| match *param {
|
||||
GenericParam::Type(ref ty_param) => Some(cx.ty_ident(span, ty_param.ident)),
|
||||
@ -200,11 +205,16 @@ impl<'a> Ty<'a> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let params = lifetimes.into_iter()
|
||||
.map(|lt| GenericAngleBracketedParam::Lifetime(lt))
|
||||
.chain(ty_params.into_iter().map(|ty|
|
||||
GenericAngleBracketedParam::Type(ty)))
|
||||
.collect();
|
||||
|
||||
cx.path_all(span,
|
||||
false,
|
||||
vec![self_ty],
|
||||
lifetimes,
|
||||
self_params,
|
||||
params,
|
||||
Vec::new())
|
||||
}
|
||||
Literal(ref p) => p.to_path(cx, span, self_ty, self_generics),
|
||||
|
@ -13,7 +13,7 @@
|
||||
// interface.
|
||||
//
|
||||
|
||||
use syntax::ast::{self, Ident};
|
||||
use syntax::ast::{self, Ident, GenericAngleBracketedParam};
|
||||
use syntax::ext::base::*;
|
||||
use syntax::ext::base;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
@ -39,8 +39,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
|
||||
cx.expr_path(cx.path_all(sp,
|
||||
true,
|
||||
cx.std_path(&["option", "Option", "None"]),
|
||||
Vec::new(),
|
||||
vec![cx.ty_rptr(sp,
|
||||
vec![GenericAngleBracketedParam::Type(cx.ty_rptr(sp,
|
||||
cx.ty_ident(sp, Ident::from_str("str")),
|
||||
Some(lt),
|
||||
ast::Mutability::Immutable)],
|
||||
|
Loading…
x
Reference in New Issue
Block a user