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