Take Const into account in HIR
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
This commit is contained in:
parent
ddf881110d
commit
7f3c6d7c04
@ -334,6 +334,7 @@ pub trait Visitor<'v> : Sized {
|
||||
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) {
|
||||
@ -752,6 +753,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
|
||||
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);
|
||||
}
|
||||
|
@ -398,6 +398,7 @@ impl<'hir> Map<'hir> {
|
||||
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)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -179,9 +179,15 @@ impl_stable_hash_for!(struct hir::PathSegment {
|
||||
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 {
|
||||
@ -231,6 +237,9 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
|
||||
default.hash_stable(hcx, hasher);
|
||||
synthetic.hash_stable(hcx, hasher);
|
||||
}
|
||||
hir::GenericParamKind::Const { ref ty } => {
|
||||
ty.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -704,7 +704,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||
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))
|
||||
}
|
||||
|
@ -527,23 +527,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
} 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,
|
||||
@ -708,7 +705,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
|
||||
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 { .. } => {
|
||||
@ -725,12 +722,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
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 {
|
||||
@ -788,23 +786,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
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,
|
||||
@ -842,24 +837,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
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,
|
||||
@ -874,19 +866,19 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
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,
|
||||
@ -950,6 +942,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||
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 {
|
||||
@ -1395,6 +1391,10 @@ fn object_lifetime_defaults_for_item(
|
||||
Set1::Many => Set1::Many,
|
||||
})
|
||||
}
|
||||
GenericParamKind::Const { .. } => {
|
||||
// Generic consts don't impose any constraints.
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@ -1703,25 +1703,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
GenericParamKind::Type { .. } => {
|
||||
type_count += 1;
|
||||
None
|
||||
}
|
||||
})
|
||||
.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,
|
||||
@ -2011,6 +2008,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
GenericArg::Const(ct) => {
|
||||
self.visit_anon_const(&ct.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2768,8 +2768,9 @@ fn insert_late_bound_lifetimes(
|
||||
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());
|
||||
|
@ -907,11 +907,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
|
||||
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",
|
||||
@ -1791,14 +1793,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements {
|
||||
|
||||
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
|
||||
|
@ -1331,6 +1331,29 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@ -1684,6 +1707,11 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, '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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1090,7 +1090,10 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
for param in &generics.params {
|
||||
match param.kind {
|
||||
hir::GenericParamKind::Lifetime { .. } => {}
|
||||
hir::GenericParamKind::Type { .. } => return,
|
||||
hir::GenericParamKind::Type { .. } |
|
||||
hir::GenericParamKind::Const { .. } => {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,19 +500,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
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) => {
|
||||
@ -524,12 +525,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
(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();
|
||||
}
|
||||
@ -1459,9 +1455,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
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;
|
||||
@ -1480,10 +1477,18 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -840,8 +840,9 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user