match generic_arg {
GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
GenericArg::Type(ty) => self.visit_ty(ty),
+ GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
}
}
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default),
+ GenericParamKind::Const { ref ty } => visitor.visit_ty(ty),
}
walk_list!(visitor, visit_param_bound, ¶m.bounds);
}
Some(match param.kind {
GenericParamKind::Lifetime { .. } => Def::Local(param.id),
GenericParamKind::Type { .. } => Def::TyParam(self.local_def_id(param.id)),
+ GenericParamKind::Const { .. } => Def::ConstParam(self.local_def_id(param.id)),
})
}
}
args
});
+impl_stable_hash_for!(struct hir::ConstArg {
+ value,
+ span,
+});
+
impl_stable_hash_for!(enum hir::GenericArg {
Lifetime(lt),
- Type(ty)
+ Type(ty),
+ Const(ct),
});
impl_stable_hash_for!(struct hir::GenericArgs {
default.hash_stable(hcx, hasher);
synthetic.hash_stable(hcx, hasher);
}
+ hir::GenericParamKind::Const { ref ty } => {
+ ty.hash_stable(hcx, hasher);
+ }
}
}
}
hir_id, expr_ty, def);
match def {
- Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
+ Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) | Def::ConstParam(..) |
Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) | Def::SelfCtor(..) => {
Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
}
} else {
0
};
- let mut type_count = 0;
- let lifetimes = generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- type_count += 1;
- None
- }
- })
- .collect();
+ let mut non_lifetime_count = 0;
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir(), &mut index, param))
+ }
+ GenericParamKind::Type { .. } |
+ GenericParamKind::Const { .. } => {
+ non_lifetime_count += 1;
+ None
+ }
+ }).collect();
let scope = Scope::Binder {
lifetimes,
- next_early_index: index + type_count,
+ next_early_index: index + non_lifetime_count,
abstract_type_parent: true,
track_lifetime_uses,
s: ROOT_SCOPE,
let mut elision = None;
let mut lifetimes = FxHashMap::default();
- let mut type_count = 0;
+ let mut non_lifetime_count = 0;
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {
lifetimes.insert(name, reg);
}
}
- GenericParamKind::Type { .. } => {
- type_count += 1;
+ GenericParamKind::Type { .. } |
+ GenericParamKind::Const { .. } => {
+ non_lifetime_count += 1;
}
}
}
- let next_early_index = index + type_count;
+ let next_early_index = index + non_lifetime_count;
if let Some(elision_region) = elision {
let scope = Scope::Elision {
let generics = &trait_item.generics;
let mut index = self.next_early_index();
debug!("visit_ty: index = {}", index);
- let mut type_count = 0;
- let lifetimes = generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- type_count += 1;
- None
- }
- })
- .collect();
+ let mut non_lifetime_count = 0;
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir(), &mut index, param))
+ }
+ GenericParamKind::Type { .. } |
+ GenericParamKind::Const { .. } => {
+ non_lifetime_count += 1;
+ None
+ }
+ }).collect();
let scope = Scope::Binder {
lifetimes,
- next_early_index: index + type_count,
+ next_early_index: index + non_lifetime_count,
s: self.scope,
track_lifetime_uses: true,
abstract_type_parent: true,
Type(ref ty) => {
let generics = &impl_item.generics;
let mut index = self.next_early_index();
- let mut next_early_index = index;
+ let mut non_lifetime_count = 0;
debug!("visit_ty: index = {}", index);
- let lifetimes = generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- next_early_index += 1;
- None
- }
- })
- .collect();
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir(), &mut index, param))
+ }
+ GenericParamKind::Const { .. } |
+ GenericParamKind::Type { .. } => {
+ non_lifetime_count += 1;
+ None
+ }
+ }).collect();
let scope = Scope::Binder {
lifetimes,
- next_early_index,
+ next_early_index: index + non_lifetime_count,
s: self.scope,
track_lifetime_uses: true,
abstract_type_parent: true,
let mut index = self.next_early_index();
let mut next_early_index = index;
debug!("visit_ty: index = {}", index);
- let lifetimes = generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- Some(Region::early(&self.tcx.hir(), &mut index, param))
- }
- GenericParamKind::Type { .. } => {
- next_early_index += 1;
- None
- }
- })
- .collect();
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ Some(Region::early(&self.tcx.hir(), &mut index, param))
+ }
+ GenericParamKind::Type { .. } => {
+ next_early_index += 1;
+ None
+ }
+ GenericParamKind::Const { .. } => {
+ next_early_index += 1;
+ None
+ }
+ }).collect();
let scope = Scope::Binder {
lifetimes,
self.visit_ty(&ty);
}
}
+ GenericParamKind::Const { ref ty, .. } => {
+ walk_list!(self, visit_param_bound, ¶m.bounds);
+ self.visit_ty(&ty);
+ }
}
}
for predicate in &generics.where_clause.predicates {
Set1::Many => Set1::Many,
})
}
+ GenericParamKind::Const { .. } => {
+ // Generic consts don't impose any constraints.
+ None
+ }
})
.collect()
}
}
}
- let mut type_count = 0;
- let lifetimes = generics
- .params
- .iter()
- .filter_map(|param| match param.kind {
- GenericParamKind::Lifetime { .. } => {
- if self.map.late_bound.contains(¶m.id) {
- Some(Region::late(&self.tcx.hir(), param))
- } else {
- Some(Region::early(&self.tcx.hir(), &mut index, param))
- }
- }
- GenericParamKind::Type { .. } => {
- type_count += 1;
- None
+ let mut non_lifetime_count = 0;
+ let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+ GenericParamKind::Lifetime { .. } => {
+ if self.map.late_bound.contains(¶m.id) {
+ Some(Region::late(&self.tcx.hir(), param))
+ } else {
+ Some(Region::early(&self.tcx.hir(), &mut index, param))
}
- })
- .collect();
- let next_early_index = index + type_count;
+ }
+ GenericParamKind::Type { .. } |
+ GenericParamKind::Const { .. } => {
+ non_lifetime_count += 1;
+ None
+ }
+ }).collect();
+ let next_early_index = index + non_lifetime_count;
let scope = Scope::Binder {
lifetimes,
}
i += 1;
}
+ GenericArg::Const(ct) => {
+ self.visit_anon_const(&ct.value);
+ }
}
}
match param.kind {
hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
- // Types are not late-bound.
- hir::GenericParamKind::Type { .. } => continue,
+ // Neither types nor consts are late-bound.
+ hir::GenericParamKind::Type { .. }
+ | hir::GenericParamKind::Const { .. } => continue,
}
let lt_name = hir::LifetimeName::Param(param.name.modern());
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime { .. } => {}
- GenericParamKind::Type { .. } => {
- let mut err = cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS,
- it.span,
- "functions generic over \
- types must be mangled");
+ GenericParamKind::Type { .. } |
+ GenericParamKind::Const { .. } => {
+ let mut err = cx.struct_span_lint(
+ NO_MANGLE_GENERIC_ITEMS,
+ it.span,
+ "functions generic over types or consts must be mangled",
+ );
err.span_suggestion_short(
no_mangle_attr.span,
"remove this attribute",
for param in &generics.params {
let param_name = match param.kind {
- hir::GenericParamKind::Lifetime { .. } => { continue; },
+ hir::GenericParamKind::Lifetime { .. } => continue,
hir::GenericParamKind::Type { .. } => {
match param.name {
- hir::ParamName::Fresh(_) => { continue; },
- hir::ParamName::Error => { continue; },
- hir::ParamName::Plain(name) => name.to_string()
+ hir::ParamName::Fresh(_) => continue,
+ hir::ParamName::Error => continue,
+ hir::ParamName::Plain(name) => name.to_string(),
}
}
+ hir::GenericParamKind::Const { .. } => continue,
};
let bound_spans = self.collect_outlives_bound_spans(
cx, def_id, ¶m_name, ¶m.bounds, infer_static
}
}
+ fn encode_info_for_const_param(&mut self, def_id: DefId) -> Entry<'tcx> {
+ debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id);
+ let tcx = self.tcx;
+ Entry {
+ kind: EntryKind::Type,
+ visibility: self.lazy(&ty::Visibility::Public),
+ span: self.lazy(&tcx.def_span(def_id)),
+ attributes: LazySeq::empty(),
+ children: LazySeq::empty(),
+ stability: None,
+ deprecation: None,
+
+ ty: Some(self.encode_item_type(def_id)),
+ inherent_impls: LazySeq::empty(),
+ variances: LazySeq::empty(),
+ generics: None,
+ predicates: None,
+ predicates_defined_on: None,
+
+ mir: None,
+ }
+ }
+
fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id);
let tcx = self.tcx;
let encode_info = IsolatedEncoder::encode_info_for_ty_param;
self.record(def_id, encode_info, (def_id, has_default));
}
+ hir::GenericParamKind::Const { .. } => {
+ let def_id = self.tcx.hir().local_def_id(param.id);
+ let encode_info = IsolatedEncoder::encode_info_for_const_param;
+ self.record(def_id, encode_info, def_id);
+ }
}
}
}
for param in &generics.params {
match param.kind {
hir::GenericParamKind::Lifetime { .. } => {}
- hir::GenericParamKind::Type { .. } => return,
+ hir::GenericParamKind::Type { .. } |
+ hir::GenericParamKind::Const { .. } => {
+ return
+ }
}
}
args.next();
params.next();
}
- (GenericArg::Lifetime(_), GenericParamDefKind::Type { .. }) => {
- // We expected a type argument, but got a lifetime
- // argument. This is an error, but we need to handle it
- // gracefully so we can report sensible errors. In this
- // case, we're simply going to infer this argument.
- args.next();
- }
- (GenericArg::Type(_), GenericParamDefKind::Lifetime) => {
- // We expected a lifetime argument, but got a type
+ (GenericArg::Type(_), GenericParamDefKind::Lifetime)
+ | (GenericArg::Const(_), GenericParamDefKind::Lifetime) => {
+ // We expected a lifetime argument, but got a type or const
// argument. That means we're inferring the lifetimes.
substs.push(inferred_kind(None, param, infer_types));
params.next();
}
+ (_, _) => {
+ // We expected one kind of parameter, but the user provided
+ // another. This is an error, but we need to handle it
+ // gracefully so we can report sensible errors.
+ // In this case, we're simply going to infer this argument.
+ args.next();
+ }
}
}
(Some(_), None) => {
(None, Some(¶m)) => {
// If there are fewer arguments than parameters, it means
// we're inferring the remaining arguments.
- match param.kind {
- GenericParamDefKind::Lifetime | GenericParamDefKind::Type { .. } => {
- let kind = inferred_kind(Some(&substs), param, infer_types);
- substs.push(kind);
- }
- }
+ substs.push(inferred_kind(Some(&substs), param, infer_types));
args.next();
params.next();
}
let mut has_err = false;
for segment in segments {
segment.with_generic_args(|generic_args| {
- let (mut err_for_lt, mut err_for_ty) = (false, false);
+ let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in &generic_args.args {
let (mut span_err, span, kind) = match arg {
+ // FIXME(varkor): unify E0109, E0110 and E0111.
hir::GenericArg::Lifetime(lt) => {
if err_for_lt { continue }
err_for_lt = true;
ty.span,
"type")
}
+ hir::GenericArg::Const(ct) => {
+ if err_for_ct { continue }
+ err_for_ct = true;
+ (struct_span_err!(self.tcx().sess, ct.span, E0111,
+ "const parameters are not allowed on this type"),
+ ct.span,
+ "const")
+ }
};
span_err.span_label(span, format!("{} argument not allowed", kind))
.emit();
- if err_for_lt && err_for_ty {
+ if err_for_lt && err_for_ty && err_for_ct {
break;
}
}
let bounds = impl_m.generics.params.iter().find_map(|param| {
match param.kind {
GenericParamKind::Lifetime { .. } => None,
- GenericParamKind::Type { .. } => {
- if param.hir_id == impl_hir_id {
+ GenericParamKind::Type { .. } |
+ GenericParamKind::Const { .. } => {
+ if param.hir_id == impl_node_id {
Some(¶m.bounds)
} else {
None