Remove all traces of lifetimes() and types() methods
This commit is contained in:
parent
10229fd9d5
commit
80b381e041
16 changed files with 419 additions and 346 deletions
|
@ -1731,7 +1731,11 @@ impl<'a> LoweringContext<'a> {
|
||||||
self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
|
self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !generic_args.parenthesized && generic_args.lifetimes().count() == 0 {
|
let has_lifetimes = generic_args.args.iter().any(|arg| match arg {
|
||||||
|
GenericArg::Lifetime(_) => true,
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
|
if !generic_args.parenthesized && !has_lifetimes {
|
||||||
generic_args.args =
|
generic_args.args =
|
||||||
self.elided_path_lifetimes(path_span, expected_lifetimes)
|
self.elided_path_lifetimes(path_span, expected_lifetimes)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -1763,7 +1767,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
|
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
|
||||||
parenthesized: false,
|
parenthesized: false,
|
||||||
},
|
},
|
||||||
has_types && param_mode == ParamMode::Optional)
|
!has_types && param_mode == ParamMode::Optional)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_parenthesized_parameter_data(
|
fn lower_parenthesized_parameter_data(
|
||||||
|
|
|
@ -400,34 +400,20 @@ impl GenericArgs {
|
||||||
|
|
||||||
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().next() {
|
for arg in &self.args {
|
||||||
if let TyTup(ref tys) = ty.node {
|
match arg {
|
||||||
return tys;
|
GenericArg::Lifetime(_) => {}
|
||||||
|
GenericArg::Type(ref ty) => {
|
||||||
|
if let TyTup(ref tys) = ty.node {
|
||||||
|
return tys;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
|
bug!("GenericArgs::inputs: not a `Fn(T) -> U`");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lifetimes(&self) -> impl DoubleEndedIterator<Item = &Lifetime> {
|
|
||||||
self.args.iter().filter_map(|p| {
|
|
||||||
if let GenericArg::Lifetime(lt) = p {
|
|
||||||
Some(lt)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn types(&self) -> impl DoubleEndedIterator<Item = &P<Ty>> {
|
|
||||||
self.args.iter().filter_map(|p| {
|
|
||||||
if let GenericArg::Type(ty) = p {
|
|
||||||
Some(ty)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The AST represents all type param bounds as types.
|
/// The AST represents all type param bounds as types.
|
||||||
|
|
|
@ -1731,20 +1731,31 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let elide_lifetimes = generic_args.lifetimes().all(|lt| lt.is_elided());
|
let mut types = vec![];
|
||||||
|
let mut elide_lifetimes = true;
|
||||||
|
for arg in &generic_args.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) => {
|
||||||
|
if !lt.is_elided() {
|
||||||
|
elide_lifetimes = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GenericArg::Type(ty) => {
|
||||||
|
types.push(ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if !elide_lifetimes {
|
if !elide_lifetimes {
|
||||||
start_or_comma(self)?;
|
start_or_comma(self)?;
|
||||||
self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
|
self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
|
||||||
match generic_arg {
|
match generic_arg {
|
||||||
GenericArg::Lifetime(lt) => s.print_lifetime(lt),
|
GenericArg::Lifetime(lt) => s.print_lifetime(lt),
|
||||||
GenericArg::Type(ty) => s.print_type(ty),
|
GenericArg::Type(ty) => s.print_type(ty),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
} else if generic_args.types().count() != 0 {
|
} else if !types.is_empty() {
|
||||||
start_or_comma(self)?;
|
start_or_comma(self)?;
|
||||||
self.commasep(Inconsistent,
|
self.commasep(Inconsistent, &types, |s, ty| s.print_type(&ty))?;
|
||||||
&generic_args.types().collect::<Vec<_>>(),
|
|
||||||
|s, 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.:
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
use hir::def::Def;
|
use hir::def::Def;
|
||||||
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||||
use hir::map::Map;
|
use hir::map::Map;
|
||||||
use hir::ItemLocalId;
|
use hir::{GenericArg, ItemLocalId, LifetimeName};
|
||||||
use hir::LifetimeName;
|
|
||||||
use ty::{self, TyCtxt, GenericParamDefKind};
|
use ty::{self, TyCtxt, GenericParamDefKind};
|
||||||
|
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
|
@ -533,15 +532,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let mut type_count = 0;
|
let mut type_count = 0;
|
||||||
let lifetimes = generics.params.iter().filter_map(|param| {
|
let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
Some(Region::early(&self.tcx.hir, &mut index, param))
|
||||||
Some(Region::early(&self.tcx.hir, &mut index, param))
|
}
|
||||||
}
|
GenericParamKind::Type { .. } => {
|
||||||
GenericParamKind::Type { .. } => {
|
type_count += 1;
|
||||||
type_count += 1;
|
None
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
|
@ -585,13 +582,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
lifetimes: c.generic_params
|
lifetimes: c.generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
Some(Region::late(&self.tcx.hir, param))
|
||||||
Some(Region::late(&self.tcx.hir, param))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
|
@ -777,15 +772,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
let mut type_count = 0;
|
let mut type_count = 0;
|
||||||
let lifetimes = generics.params
|
let lifetimes = generics.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
Some(Region::early(&self.tcx.hir, &mut index, param))
|
||||||
Some(Region::early(&self.tcx.hir, &mut index, param))
|
}
|
||||||
}
|
GenericParamKind::Type { .. } => {
|
||||||
GenericParamKind::Type { .. } => {
|
type_count += 1;
|
||||||
type_count += 1;
|
None
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -834,15 +827,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
debug!("visit_ty: index = {}", index);
|
debug!("visit_ty: index = {}", index);
|
||||||
let lifetimes = generics.params
|
let lifetimes = generics.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
Some(Region::early(&self.tcx.hir, &mut index, param))
|
||||||
Some(Region::early(&self.tcx.hir, &mut index, param))
|
}
|
||||||
}
|
GenericParamKind::Type { .. } => {
|
||||||
GenericParamKind::Type { .. } => {
|
next_early_index += 1;
|
||||||
next_early_index += 1;
|
None
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -899,11 +890,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
|
||||||
check_mixed_explicit_and_in_band_defs(
|
check_mixed_explicit_and_in_band_defs(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&generics.params.iter().filter_map(|param| {
|
&generics.params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => Some(param.clone()),
|
||||||
GenericParamKind::Lifetime { .. } => Some(param.clone()),
|
_ => None,
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}).collect::<Vec<_>>()
|
}).collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
for param in &generics.params {
|
for param in &generics.params {
|
||||||
|
@ -926,13 +915,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let lifetimes: FxHashMap<_, _> = bound_generic_params.iter()
|
let lifetimes: FxHashMap<_, _> = bound_generic_params.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
Some(Region::late(&self.tcx.hir, param))
|
||||||
Some(Region::late(&self.tcx.hir, param))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if !lifetimes.is_empty() {
|
if !lifetimes.is_empty() {
|
||||||
|
@ -990,11 +977,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
|| trait_ref
|
|| trait_ref
|
||||||
.bound_generic_params
|
.bound_generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.any(|param| {
|
.any(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => true,
|
||||||
GenericParamKind::Lifetime { .. } => true,
|
_ => false,
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
if self.trait_ref_hack {
|
if self.trait_ref_hack {
|
||||||
|
@ -1010,13 +995,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
lifetimes: trait_ref
|
lifetimes: trait_ref
|
||||||
.bound_generic_params
|
.bound_generic_params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
Some(Region::late(&self.tcx.hir, param))
|
||||||
Some(Region::late(&self.tcx.hir, param))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
|
@ -1087,11 +1070,9 @@ fn check_mixed_explicit_and_in_band_defs(
|
||||||
tcx: TyCtxt<'_, '_, '_>,
|
tcx: TyCtxt<'_, '_, '_>,
|
||||||
params: &[hir::GenericParam],
|
params: &[hir::GenericParam],
|
||||||
) {
|
) {
|
||||||
let in_bands: Vec<_> = params.iter().map(|param| {
|
let in_bands: Vec<_> = params.iter().map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span),
|
||||||
GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span),
|
_ => bug!("expected lifetime param"),
|
||||||
_ => bug!("expected lifetime param"),
|
|
||||||
}
|
|
||||||
}).collect();
|
}).collect();
|
||||||
let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band);
|
let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band);
|
||||||
let in_band = in_bands.iter().find(|(in_band, _)| *in_band);
|
let in_band = in_bands.iter().find(|(in_band, _)| *in_band);
|
||||||
|
@ -1262,18 +1243,16 @@ fn compute_object_lifetime_defaults(
|
||||||
Set1::One(Region::Static) => "'static".to_string(),
|
Set1::One(Region::Static) => "'static".to_string(),
|
||||||
Set1::One(Region::EarlyBound(i, _, _)) => {
|
Set1::One(Region::EarlyBound(i, _, _)) => {
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
generics.params.iter().find(|param| {
|
generics.params.iter().find(|param| match param.kind {
|
||||||
match param.kind {
|
|
||||||
GenericParamKind::Lifetime { .. } => {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
if i == j {
|
if i == j {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
j += 1;
|
j += 1;
|
||||||
|
false
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => false,
|
||||||
}
|
}).unwrap()
|
||||||
false
|
|
||||||
}).unwrap()
|
|
||||||
.name()
|
.name()
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
@ -1308,64 +1287,60 @@ fn object_lifetime_defaults_for_item(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generics.params.iter().filter_map(|param| {
|
generics.params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => None,
|
||||||
GenericParamKind::Lifetime { .. } => None,
|
GenericParamKind::Type { ref bounds, .. } => {
|
||||||
GenericParamKind::Type { ref bounds, .. } => {
|
let mut set = Set1::Empty;
|
||||||
let mut set = Set1::Empty;
|
|
||||||
|
|
||||||
add_bounds(&mut set, &bounds);
|
add_bounds(&mut set, &bounds);
|
||||||
|
|
||||||
let param_def_id = tcx.hir.local_def_id(param.id);
|
let param_def_id = tcx.hir.local_def_id(param.id);
|
||||||
for predicate in &generics.where_clause.predicates {
|
for predicate in &generics.where_clause.predicates {
|
||||||
// Look for `type: ...` where clauses.
|
// Look for `type: ...` where clauses.
|
||||||
let data = match *predicate {
|
let data = match *predicate {
|
||||||
hir::WherePredicate::BoundPredicate(ref data) => data,
|
hir::WherePredicate::BoundPredicate(ref data) => data,
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ignore `for<'a> type: ...` as they can change what
|
// Ignore `for<'a> type: ...` as they can change what
|
||||||
// lifetimes mean (although we could "just" handle it).
|
// lifetimes mean (although we could "just" handle it).
|
||||||
if !data.bound_generic_params.is_empty() {
|
if !data.bound_generic_params.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
let def = match data.bounded_ty.node {
|
|
||||||
hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def,
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
|
|
||||||
if def == Def::TyParam(param_def_id) {
|
|
||||||
add_bounds(&mut set, &data.bounds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(match set {
|
let def = match data.bounded_ty.node {
|
||||||
Set1::Empty => Set1::Empty,
|
hir::TyPath(hir::QPath::Resolved(None, ref path)) => path.def,
|
||||||
Set1::One(name) => {
|
_ => continue,
|
||||||
if name == hir::LifetimeName::Static {
|
};
|
||||||
Set1::One(Region::Static)
|
|
||||||
} else {
|
if def == Def::TyParam(param_def_id) {
|
||||||
generics.params.iter().filter_map(|param| {
|
add_bounds(&mut set, &data.bounds);
|
||||||
match param.kind {
|
}
|
||||||
GenericParamKind::Lifetime { name, in_band, .. } => {
|
|
||||||
Some((param.id, name, in_band))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.enumerate()
|
|
||||||
.find(|&(_, (_, lt_name, _))| lt_name == name)
|
|
||||||
.map_or(Set1::Many, |(i, (id, _, in_band))| {
|
|
||||||
let def_id = tcx.hir.local_def_id(id);
|
|
||||||
let origin = LifetimeDefOrigin::from_is_in_band(in_band);
|
|
||||||
Set1::One(Region::EarlyBound(i as u32, def_id, origin))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Set1::Many => Set1::Many,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(match set {
|
||||||
|
Set1::Empty => Set1::Empty,
|
||||||
|
Set1::One(name) => {
|
||||||
|
if name == hir::LifetimeName::Static {
|
||||||
|
Set1::One(Region::Static)
|
||||||
|
} else {
|
||||||
|
generics.params.iter().filter_map(|param| match param.kind {
|
||||||
|
GenericParamKind::Lifetime { name, in_band, .. } => {
|
||||||
|
Some((param.id, name, in_band))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.enumerate()
|
||||||
|
.find(|&(_, (_, lt_name, _))| lt_name == name)
|
||||||
|
.map_or(Set1::Many, |(i, (id, _, in_band))| {
|
||||||
|
let def_id = tcx.hir.local_def_id(id);
|
||||||
|
let origin = LifetimeDefOrigin::from_is_in_band(in_band);
|
||||||
|
Set1::One(Region::EarlyBound(i as u32, def_id, origin))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set1::Many => Set1::Many,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -1541,20 +1516,18 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut type_count = 0;
|
let mut type_count = 0;
|
||||||
let lifetimes = generics.params.iter().filter_map(|param| {
|
let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
if self.map.late_bound.contains(¶m.id) {
|
||||||
if self.map.late_bound.contains(¶m.id) {
|
Some(Region::late(&self.tcx.hir, param))
|
||||||
Some(Region::late(&self.tcx.hir, param))
|
} else {
|
||||||
} else {
|
Some(Region::early(&self.tcx.hir, &mut index, param))
|
||||||
Some(Region::early(&self.tcx.hir, &mut index, param))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GenericParamKind::Type { .. } => {
|
|
||||||
type_count += 1;
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GenericParamKind::Type { .. } => {
|
||||||
|
type_count += 1;
|
||||||
|
None
|
||||||
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
let next_early_index = index + type_count;
|
let next_early_index = index + type_count;
|
||||||
|
|
||||||
|
@ -1721,11 +1694,21 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if generic_args.lifetimes().all(|l| l.is_elided()) {
|
let mut elide_lifetimes = true;
|
||||||
self.resolve_elided_lifetimes(generic_args.lifetimes().collect(), true);
|
let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
|
||||||
|
hir::GenericArg::Lifetime(lt) => {
|
||||||
|
if !lt.is_elided() {
|
||||||
|
elide_lifetimes = false;
|
||||||
|
}
|
||||||
|
Some(lt)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}).collect();
|
||||||
|
if elide_lifetimes {
|
||||||
|
self.resolve_elided_lifetimes(lifetimes, true);
|
||||||
} else {
|
} else {
|
||||||
for l in generic_args.lifetimes() {
|
for lt in lifetimes {
|
||||||
self.visit_lifetime(l);
|
self.visit_lifetime(lt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1788,29 +1771,41 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
}).collect()
|
}).collect()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
unsubst
|
unsubst.iter()
|
||||||
.iter()
|
.map(|set| match *set {
|
||||||
.map(|set| match *set {
|
Set1::Empty => if in_body {
|
||||||
Set1::Empty => if in_body {
|
None
|
||||||
None
|
} else {
|
||||||
} else {
|
Some(Region::Static)
|
||||||
Some(Region::Static)
|
},
|
||||||
},
|
Set1::One(r) => {
|
||||||
Set1::One(r) => r.subst(generic_args.lifetimes(), map),
|
let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
|
||||||
Set1::Many => None,
|
GenericArg::Lifetime(lt) => Some(lt),
|
||||||
})
|
_ => None,
|
||||||
.collect()
|
});
|
||||||
|
r.subst(lifetimes, map)
|
||||||
|
}
|
||||||
|
Set1::Many => None,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
});
|
});
|
||||||
|
|
||||||
for (i, ty) in generic_args.types().enumerate() {
|
let mut i = 0;
|
||||||
if let Some(<) = object_lifetime_defaults.get(i) {
|
for arg in &generic_args.args {
|
||||||
let scope = Scope::ObjectLifetimeDefault {
|
match arg {
|
||||||
lifetime: lt,
|
GenericArg::Lifetime(_) => {}
|
||||||
s: self.scope,
|
GenericArg::Type(ty) => {
|
||||||
};
|
if let Some(<) = object_lifetime_defaults.get(i) {
|
||||||
self.with(scope, |_, this| this.visit_ty(ty));
|
let scope = Scope::ObjectLifetimeDefault {
|
||||||
} else {
|
lifetime: lt,
|
||||||
self.visit_ty(ty);
|
s: self.scope,
|
||||||
|
};
|
||||||
|
self.with(scope, |_, this| this.visit_ty(ty));
|
||||||
|
} else {
|
||||||
|
self.visit_ty(ty);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2269,11 +2264,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
|
fn check_lifetime_params(&mut self, old_scope: ScopeRef, params: &'tcx [hir::GenericParam]) {
|
||||||
let lifetimes: Vec<_> = params.iter().filter_map(|param| {
|
let lifetimes: Vec<_> = params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { name, .. } => Some((param, name)),
|
||||||
GenericParamKind::Lifetime { name, .. } => Some((param, name)),
|
_ => None,
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}).collect();
|
}).collect();
|
||||||
for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
|
for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
|
||||||
match lifetime_i_name {
|
match lifetime_i_name {
|
||||||
|
|
|
@ -224,11 +224,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||||
let names_map: FxHashSet<String> = generics
|
let names_map: FxHashSet<String> = generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
|
||||||
ty::GenericParamDefKind::Lifetime => Some(param.name.to_string()),
|
_ => None
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -336,13 +336,11 @@ impl PrintContext {
|
||||||
|
|
||||||
if !verbose {
|
if !verbose {
|
||||||
let mut type_params =
|
let mut type_params =
|
||||||
generics.params.iter().rev().filter_map(|param| {
|
generics.params.iter().rev().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamDefKind::Type { has_default, .. } => {
|
||||||
GenericParamDefKind::Type { has_default, .. } => {
|
Some((param.def_id, has_default))
|
||||||
Some((param.def_id, has_default))
|
|
||||||
}
|
|
||||||
GenericParamDefKind::Lifetime => None,
|
|
||||||
}
|
}
|
||||||
|
GenericParamDefKind::Lifetime => None,
|
||||||
}).peekable();
|
}).peekable();
|
||||||
let has_default = {
|
let has_default = {
|
||||||
let has_default = type_params.peek().map(|(_, has_default)| has_default);
|
let has_default = type_params.peek().map(|(_, has_default)| has_default);
|
||||||
|
|
|
@ -1236,12 +1236,10 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
|
hir::ItemConst(..) => self.encode_optimized_mir(def_id),
|
||||||
hir::ItemFn(_, _, constness, _, ref generics, _) => {
|
hir::ItemFn(_, _, constness, _, ref generics, _) => {
|
||||||
let has_types = generics.params.iter().find(|param| {
|
let has_types = generics.params.iter().any(|param| match param.kind {
|
||||||
match param.kind {
|
hir::GenericParamKind::Type { .. } => true,
|
||||||
hir::GenericParamKind::Type { .. } => true,
|
_ => false,
|
||||||
_ => false,
|
});
|
||||||
}
|
|
||||||
}).is_some();
|
|
||||||
let needs_inline =
|
let needs_inline =
|
||||||
(has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
|
(has_types || tcx.codegen_fn_attrs(def_id).requests_inline()) &&
|
||||||
!self.metadata_output_only();
|
!self.metadata_output_only();
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//! is parameterized by an instance of `AstConv`.
|
//! is parameterized by an instance of `AstConv`.
|
||||||
|
|
||||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||||
use hir;
|
use hir::{self, GenericArg};
|
||||||
use hir::def::Def;
|
use hir::def::Def;
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use middle::resolve_lifetime as rl;
|
use middle::resolve_lifetime as rl;
|
||||||
|
@ -213,10 +213,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
// If the type is parameterized by this region, then replace this
|
// If the type is parameterized by this region, then replace this
|
||||||
// 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 mut lt_provided = 0;
|
||||||
let ty_provided = generic_args.types().count();
|
let mut ty_provided = 0;
|
||||||
let lt_provided = generic_args.lifetimes().count();
|
for arg in &generic_args.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(_) => lt_provided += 1,
|
||||||
|
GenericArg::Type(_) => ty_provided += 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let decl_generics = tcx.generics_of(def_id);
|
||||||
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 };
|
||||||
for param in &decl_generics.params {
|
for param in &decl_generics.params {
|
||||||
|
@ -269,11 +275,19 @@ 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) = generic_args.lifetimes().nth(i) {
|
let mut j = 0;
|
||||||
self.ast_region_to_region(lifetime, Some(param)).into()
|
for arg in &generic_args.args {
|
||||||
} else {
|
match arg {
|
||||||
tcx.types.re_static.into()
|
GenericArg::Lifetime(lt) => {
|
||||||
|
if i == j {
|
||||||
|
return self.ast_region_to_region(lt, Some(param)).into();
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
tcx.types.re_static.into()
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Type { has_default, .. } => {
|
GenericParamDefKind::Type { has_default, .. } => {
|
||||||
let i = param.index as usize;
|
let i = param.index as usize;
|
||||||
|
@ -286,7 +300,19 @@ 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(&generic_args.types().nth(i).unwrap()).into()
|
let mut j = 0;
|
||||||
|
for arg in &generic_args.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Type(ty) => {
|
||||||
|
if i == j {
|
||||||
|
return self.ast_ty_to_ty(ty).into();
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bug!()
|
||||||
} 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) {
|
||||||
|
|
|
@ -728,11 +728,9 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let mut error_found = false;
|
let mut error_found = false;
|
||||||
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
||||||
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
||||||
let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| {
|
let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
|
||||||
GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
|
GenericParamDefKind::Lifetime => None,
|
||||||
GenericParamDefKind::Lifetime => None,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
|
let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
|
|
|
@ -12,6 +12,7 @@ use super::{probe, MethodCallee};
|
||||||
|
|
||||||
use astconv::AstConv;
|
use astconv::AstConv;
|
||||||
use check::{FnCtxt, PlaceOp, callee, Needs};
|
use check::{FnCtxt, PlaceOp, callee, Needs};
|
||||||
|
use hir::GenericArg;
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
|
@ -330,16 +331,40 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
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(|data| {
|
||||||
p.lifetimes().nth(i - parent_substs.len())
|
let mut j = 0;
|
||||||
|
for arg in &data.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) => {
|
||||||
|
if i - parent_substs.len() == j {
|
||||||
|
return Some(lt);
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}) {
|
}) {
|
||||||
return AstConv::ast_region_to_region(
|
return AstConv::ast_region_to_region(
|
||||||
self.fcx, lifetime, Some(param)).into();
|
self.fcx, lifetime, Some(param)).into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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(|data| {
|
||||||
p.types().nth(i - parent_substs.len() - own_counts.lifetimes)
|
let mut j = 0;
|
||||||
|
for arg in &data.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Type(ty) => {
|
||||||
|
if i - parent_substs.len() - own_counts.lifetimes == j {
|
||||||
|
return Some(ty);
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
}) {
|
}) {
|
||||||
return self.to_ty(ast_ty).into();
|
return self.to_ty(ast_ty).into();
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ use self::method::MethodCallee;
|
||||||
use self::TupleArgumentsFlag::*;
|
use self::TupleArgumentsFlag::*;
|
||||||
|
|
||||||
use astconv::AstConv;
|
use astconv::AstConv;
|
||||||
|
use hir::GenericArg;
|
||||||
use hir::def::Def;
|
use hir::def::Def;
|
||||||
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
@ -4834,7 +4835,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
let lifetimes = segment.map_or(vec![], |(s, _)| {
|
let lifetimes = segment.map_or(vec![], |(s, _)| {
|
||||||
s.args.as_ref().map_or(vec![], |arg| arg.lifetimes().collect())
|
s.args.as_ref().map_or(vec![], |data| {
|
||||||
|
data.args.iter().filter_map(|arg| match arg {
|
||||||
|
GenericArg::Lifetime(lt) => Some(lt),
|
||||||
|
_ => None,
|
||||||
|
}).collect()
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(lifetime) = lifetimes.get(i) {
|
if let Some(lifetime) = lifetimes.get(i) {
|
||||||
|
@ -4845,8 +4851,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Type {..} => {
|
GenericParamDefKind::Type {..} => {
|
||||||
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
|
let (types, infer_types) = segment.map_or((vec![], true), |(s, _)| {
|
||||||
(s.args.as_ref().map_or(vec![], |arg| {
|
(s.args.as_ref().map_or(vec![], |data| {
|
||||||
arg.types().collect()
|
data.args.iter().filter_map(|arg| match arg {
|
||||||
|
GenericArg::Type(ty) => Some(ty),
|
||||||
|
_ => None,
|
||||||
|
}).collect()
|
||||||
}), s.infer_types)
|
}), s.infer_types)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -4967,11 +4976,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
|(s, _)| {
|
|(s, _)| {
|
||||||
s.args.as_ref().map_or(
|
s.args.as_ref().map_or(
|
||||||
(vec![], vec![], s.infer_types, &[][..]),
|
(vec![], vec![], s.infer_types, &[][..]),
|
||||||
|arg| {
|
|data| {
|
||||||
(arg.lifetimes().collect(),
|
let mut lifetimes = vec![];
|
||||||
arg.types().collect(),
|
let mut types = vec![];
|
||||||
s.infer_types,
|
for arg in &data.args {
|
||||||
&arg.bindings[..])
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) => lifetimes.push(lt),
|
||||||
|
GenericArg::Type(ty) => types.push(ty),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(lifetimes, types, s.infer_types, &data.bindings[..])
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -5097,13 +5111,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
-> bool {
|
-> bool {
|
||||||
let segment = segment.map(|(path_segment, generics)| {
|
let segment = segment.map(|(path_segment, generics)| {
|
||||||
let explicit = !path_segment.infer_types;
|
let explicit = !path_segment.infer_types;
|
||||||
let impl_trait = generics.params.iter().any(|param| {
|
let impl_trait = generics.params.iter().any(|param| match param.kind {
|
||||||
match param.kind {
|
ty::GenericParamDefKind::Type {
|
||||||
ty::GenericParamDefKind::Type {
|
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
|
||||||
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
|
} => true,
|
||||||
} => true,
|
_ => false,
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if explicit && impl_trait {
|
if explicit && impl_trait {
|
||||||
|
@ -5187,11 +5199,9 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let types = generics.params.iter().filter(|param| {
|
let types = generics.params.iter().filter(|param| match param.kind {
|
||||||
match param.kind {
|
hir::GenericParamKind::Type { .. } => true,
|
||||||
hir::GenericParamKind::Type { .. } => true,
|
_ => false,
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
for (&used, param) in types_used.iter().zip(types) {
|
for (&used, param) in types_used.iter().zip(types) {
|
||||||
if !used {
|
if !used {
|
||||||
|
|
|
@ -662,11 +662,9 @@ fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
|
||||||
let parent = tcx.generics_of(generics.parent.unwrap());
|
let parent = tcx.generics_of(generics.parent.unwrap());
|
||||||
let impl_params: FxHashMap<_, _> =
|
let impl_params: FxHashMap<_, _> =
|
||||||
parent.params.iter()
|
parent.params.iter()
|
||||||
.flat_map(|param| {
|
.flat_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamDefKind::Lifetime => None,
|
||||||
GenericParamDefKind::Lifetime => None,
|
GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
|
||||||
GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -315,17 +315,14 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
let from_ty_params =
|
let from_ty_params =
|
||||||
ast_generics.params.iter()
|
ast_generics.params.iter()
|
||||||
.filter_map(|param| {
|
.filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Type { ref bounds, .. } => {
|
||||||
GenericParamKind::Type { ref bounds, .. } => {
|
if param.id == param_id {
|
||||||
if param.id == param_id {
|
return Some(bounds);
|
||||||
Some(bounds)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => None
|
None
|
||||||
}
|
}
|
||||||
|
_ => None
|
||||||
})
|
})
|
||||||
.flat_map(|bounds| bounds.iter())
|
.flat_map(|bounds| bounds.iter())
|
||||||
.flat_map(|b| predicates_from_bound(self, ty, b));
|
.flat_map(|b| predicates_from_bound(self, ty, b));
|
||||||
|
@ -921,42 +918,40 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
// Now create the real type parameters.
|
// Now create the real type parameters.
|
||||||
let type_start = own_start - has_self as u32 + params.len() as u32;
|
let type_start = own_start - has_self as u32 + params.len() as u32;
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
params.extend(ast_generics.params.iter().filter_map(|param| {
|
params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Type { ref default, synthetic, .. } => {
|
||||||
GenericParamKind::Type { ref default, synthetic, .. } => {
|
if param.name() == keywords::SelfType.name() {
|
||||||
if param.name() == keywords::SelfType.name() {
|
span_bug!(param.span,
|
||||||
span_bug!(param.span,
|
"`Self` should not be the name of a regular parameter");
|
||||||
"`Self` should not be the name of a regular parameter");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !allow_defaults && default.is_some() {
|
|
||||||
if !tcx.features().default_type_parameter_fallback {
|
|
||||||
tcx.lint_node(
|
|
||||||
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
|
|
||||||
param.id,
|
|
||||||
param.span,
|
|
||||||
&format!("defaults for type parameters are only allowed in \
|
|
||||||
`struct`, `enum`, `type`, or `trait` definitions."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ty_param = ty::GenericParamDef {
|
|
||||||
index: type_start + i as u32,
|
|
||||||
name: param.name().as_interned_str(),
|
|
||||||
def_id: tcx.hir.local_def_id(param.id),
|
|
||||||
pure_wrt_drop: param.pure_wrt_drop,
|
|
||||||
kind: ty::GenericParamDefKind::Type {
|
|
||||||
has_default: default.is_some(),
|
|
||||||
object_lifetime_default:
|
|
||||||
object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
|
|
||||||
synthetic,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
i += 1;
|
|
||||||
Some(ty_param)
|
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
|
if !allow_defaults && default.is_some() {
|
||||||
|
if !tcx.features().default_type_parameter_fallback {
|
||||||
|
tcx.lint_node(
|
||||||
|
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
|
||||||
|
param.id,
|
||||||
|
param.span,
|
||||||
|
&format!("defaults for type parameters are only allowed in \
|
||||||
|
`struct`, `enum`, `type`, or `trait` definitions."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ty_param = ty::GenericParamDef {
|
||||||
|
index: type_start + i as u32,
|
||||||
|
name: param.name().as_interned_str(),
|
||||||
|
def_id: tcx.hir.local_def_id(param.id),
|
||||||
|
pure_wrt_drop: param.pure_wrt_drop,
|
||||||
|
kind: ty::GenericParamDefKind::Type {
|
||||||
|
has_default: default.is_some(),
|
||||||
|
object_lifetime_default:
|
||||||
|
object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
|
||||||
|
synthetic,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
i += 1;
|
||||||
|
Some(ty_param)
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// provide junk type parameter defs - the only place that
|
// provide junk type parameter defs - the only place that
|
||||||
|
@ -1313,14 +1308,12 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
|
||||||
generics: &'a hir::Generics)
|
generics: &'a hir::Generics)
|
||||||
-> impl Iterator<Item=&'a hir::GenericParam> + Captures<'tcx>
|
-> impl Iterator<Item=&'a hir::GenericParam> + Captures<'tcx>
|
||||||
{
|
{
|
||||||
generics.params.iter().filter(move |param| {
|
generics.params.iter().filter(move |param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKind::Lifetime { .. } => {
|
||||||
GenericParamKind::Lifetime { .. } => {
|
let hir_id = tcx.hir.node_to_hir_id(param.id);
|
||||||
let hir_id = tcx.hir.node_to_hir_id(param.id);
|
!tcx.is_late_bound(hir_id)
|
||||||
!tcx.is_late_bound(hir_id)
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
|
_ => false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ use rustc::middle::resolve_lifetime as rl;
|
||||||
use rustc::ty::fold::TypeFolder;
|
use rustc::ty::fold::TypeFolder;
|
||||||
use rustc::middle::lang_items;
|
use rustc::middle::lang_items;
|
||||||
use rustc::mir::interpret::GlobalId;
|
use rustc::mir::interpret::GlobalId;
|
||||||
use rustc::hir::{self, HirVec};
|
use rustc::hir::{self, GenericArg, HirVec};
|
||||||
use rustc::hir::def::{self, Def, CtorKind};
|
use rustc::hir::def::{self, Def, CtorKind};
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use rustc::hir::def_id::DefIndexAddressSpace;
|
use rustc::hir::def_id::DefIndexAddressSpace;
|
||||||
|
@ -1979,16 +1979,14 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||||
// Bounds in the type_params and lifetimes fields are repeated in the
|
// Bounds in the type_params and lifetimes fields are repeated in the
|
||||||
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
||||||
// them.
|
// them.
|
||||||
let stripped_typarams = gens.params.iter().filter_map(|param| {
|
let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind {
|
||||||
if let ty::GenericParamDefKind::Type {..} = param.kind {
|
ty::GenericParamDefKind::Lifetime => None,
|
||||||
|
ty::GenericParamDefKind::Type { .. } => {
|
||||||
if param.name == keywords::SelfType.name().as_str() {
|
if param.name == keywords::SelfType.name().as_str() {
|
||||||
assert_eq!(param.index, 0);
|
assert_eq!(param.index, 0);
|
||||||
None
|
return None;
|
||||||
} else {
|
|
||||||
Some(param.clean(cx))
|
|
||||||
}
|
}
|
||||||
} else {
|
Some(param.clean(cx))
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}).collect::<Vec<TyParam>>();
|
}).collect::<Vec<TyParam>>();
|
||||||
|
|
||||||
|
@ -2034,12 +2032,11 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||||
Generics {
|
Generics {
|
||||||
params: gens.params
|
params: gens.params
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|param| {
|
.flat_map(|param| match param.kind {
|
||||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
ty::GenericParamDefKind::Lifetime => {
|
||||||
Some(GenericParamDef::Lifetime(param.clean(cx)))
|
Some(GenericParamDef::Lifetime(param.clean(cx)))
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
ty::GenericParamDefKind::Type { .. } => None,
|
||||||
}).chain(
|
}).chain(
|
||||||
simplify::ty_params(stripped_typarams)
|
simplify::ty_params(stripped_typarams)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -2870,8 +2867,20 @@ impl Clean<Type> for hir::Ty {
|
||||||
for param in generics.params.iter() {
|
for param in generics.params.iter() {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
hir::GenericParamKind::Lifetime { .. } => {
|
hir::GenericParamKind::Lifetime { .. } => {
|
||||||
if let Some(lt) = generic_args.lifetimes()
|
let mut j = 0;
|
||||||
.nth(indices.lifetimes).cloned() {
|
let lifetime = generic_args.args.iter().find_map(|arg| {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) => {
|
||||||
|
if indices.lifetimes == j {
|
||||||
|
return Some(lt);
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if let Some(lt) = lifetime.cloned() {
|
||||||
if !lt.is_elided() {
|
if !lt.is_elided() {
|
||||||
let lt_def_id =
|
let lt_def_id =
|
||||||
cx.tcx.hir.local_def_id(param.id);
|
cx.tcx.hir.local_def_id(param.id);
|
||||||
|
@ -2883,8 +2892,20 @@ impl Clean<Type> for hir::Ty {
|
||||||
hir::GenericParamKind::Type { ref default, .. } => {
|
hir::GenericParamKind::Type { ref default, .. } => {
|
||||||
let ty_param_def =
|
let ty_param_def =
|
||||||
Def::TyParam(cx.tcx.hir.local_def_id(param.id));
|
Def::TyParam(cx.tcx.hir.local_def_id(param.id));
|
||||||
if let Some(ty) = generic_args.types()
|
let mut j = 0;
|
||||||
.nth(indices.types).cloned() {
|
let type_ = generic_args.args.iter().find_map(|arg| {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Type(ty) => {
|
||||||
|
if indices.types == j {
|
||||||
|
return Some(ty);
|
||||||
|
}
|
||||||
|
j += 1;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if let Some(ty) = type_.cloned() {
|
||||||
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
|
ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
|
||||||
} else if let Some(default) = default.clone() {
|
} else if let Some(default) = default.clone() {
|
||||||
ty_substs.insert(ty_param_def,
|
ty_substs.insert(ty_param_def,
|
||||||
|
@ -3504,13 +3525,28 @@ impl Clean<GenericArgs> for hir::GenericArgs {
|
||||||
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
|
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut lifetimes = vec![];
|
||||||
|
let mut types = vec![];
|
||||||
|
let mut elided_lifetimes = true;
|
||||||
|
for arg in &self.args {
|
||||||
|
match arg {
|
||||||
|
GenericArg::Lifetime(lt) if elided_lifetimes => {
|
||||||
|
if lt.is_elided() {
|
||||||
|
elided_lifetimes = false;
|
||||||
|
lifetimes = vec![];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lifetimes.push(lt.clean(cx));
|
||||||
|
}
|
||||||
|
GenericArg::Lifetime(_) => {}
|
||||||
|
GenericArg::Type(ty) => {
|
||||||
|
types.push(ty.clean(cx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
GenericArgs::AngleBracketed {
|
GenericArgs::AngleBracketed {
|
||||||
lifetimes: if self.lifetimes().all(|lt| lt.is_elided()) {
|
lifetimes,
|
||||||
vec![]
|
types,
|
||||||
} else {
|
|
||||||
self.lifetimes().map(|lt| lt.clean(cx)).collect()
|
|
||||||
},
|
|
||||||
types: self.types().map(|ty| ty.clean(cx)).collect(),
|
|
||||||
bindings: self.bindings.clean(cx),
|
bindings: self.bindings.clean(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(fs_read_write)]
|
#![feature(fs_read_write)]
|
||||||
|
#![feature(iterator_find_map)]
|
||||||
#![feature(set_stdio)]
|
#![feature(set_stdio)]
|
||||||
#![feature(slice_sort_by_cached_key)]
|
#![feature(slice_sort_by_cached_key)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
|
@ -549,30 +549,28 @@ impl<'a> TraitDef<'a> {
|
||||||
.to_generics(cx, self.span, type_ident, generics);
|
.to_generics(cx, self.span, type_ident, generics);
|
||||||
|
|
||||||
// Create the generic parameters
|
// Create the generic parameters
|
||||||
params.extend(generics.params.iter().map(|param| {
|
params.extend(generics.params.iter().map(|param| match param.kind {
|
||||||
match param.kind {
|
GenericParamKindAST::Lifetime { .. } => param.clone(),
|
||||||
GenericParamKindAST::Lifetime { .. } => param.clone(),
|
GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => {
|
||||||
GenericParamKindAST::Type { bounds: ref ty_bounds, .. } => {
|
// I don't think this can be moved out of the loop, since
|
||||||
// I don't think this can be moved out of the loop, since
|
// a TyParamBound requires an ast id
|
||||||
// a TyParamBound requires an ast id
|
let mut bounds: Vec<_> =
|
||||||
let mut bounds: Vec<_> =
|
// extra restrictions on the generics parameters to the
|
||||||
// extra restrictions on the generics parameters to the
|
// type being derived upon
|
||||||
// type being derived upon
|
self.additional_bounds.iter().map(|p| {
|
||||||
self.additional_bounds.iter().map(|p| {
|
cx.typarambound(p.to_path(cx, self.span,
|
||||||
cx.typarambound(p.to_path(cx, self.span,
|
type_ident, generics))
|
||||||
type_ident, generics))
|
}).collect();
|
||||||
}).collect();
|
|
||||||
|
|
||||||
// require the current trait
|
// require the current trait
|
||||||
bounds.push(cx.typarambound(trait_path.clone()));
|
bounds.push(cx.typarambound(trait_path.clone()));
|
||||||
|
|
||||||
// also add in any bounds from the declaration
|
// also add in any bounds from the declaration
|
||||||
for declared_bound in ty_bounds {
|
for declared_bound in ty_bounds {
|
||||||
bounds.push((*declared_bound).clone());
|
bounds.push((*declared_bound).clone());
|
||||||
}
|
|
||||||
|
|
||||||
cx.typaram(self.span, param.ident, vec![], bounds, None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cx.typaram(self.span, param.ident, vec![], bounds, None)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue