Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add const generics to the HIR #58503

Merged
merged 13 commits into from
Feb 19, 2019
2 changes: 1 addition & 1 deletion src/librustc/hir/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ pub enum Def {
AssociatedExistential(DefId),
PrimTy(hir::PrimTy),
TyParam(DefId),
ConstParam(DefId),
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`

// Value namespace
Fn(DefId),
Const(DefId),
ConstParam(DefId),
Static(DefId, bool /* is_mutbl */),
StructCtor(DefId, CtorKind), // `DefId` refers to `NodeId` of the struct's constructor
VariantCtor(DefId, CtorKind), // `DefId` refers to the enum variant
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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, &param.bounds);
}
Expand Down
25 changes: 9 additions & 16 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use crate::hir::HirVec;
use crate::hir::map::{DefKey, DefPathData, Definitions};
use crate::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
use crate::hir::def::{Def, PathResolution, PerNS};
use crate::hir::GenericArg;
use crate::hir::{GenericArg, ConstArg};
use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
ELIDED_LIFETIMES_IN_PATHS};
use crate::middle::cstore::CrateStore;
Expand Down Expand Up @@ -1172,13 +1172,10 @@ impl<'a> LoweringContext<'a> {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)),
ast::GenericArg::Const(ct) => {
// FIXME(const_generics): const generics are not yet defined in the HIR.
self.sess.struct_span_err(
ct.value.span,
"const generics in any position are currently unsupported",
).emit();
self.sess.abort_if_errors();
bug!();
GenericArg::Const(ConstArg {
value: self.lower_anon_const(&ct),
span: ct.value.span,
})
}
}
}
Expand Down Expand Up @@ -2520,14 +2517,10 @@ impl<'a> LoweringContext<'a> {

(hir::ParamName::Plain(ident), kind)
}
GenericParamKind::Const { .. } => {
// FIXME(const_generics): const generics are not yet defined in the HIR.
self.sess.struct_span_err(
param.ident.span,
"const generics in any position are currently unsupported",
).emit();
self.sess.abort_if_errors();
bug!();
GenericParamKind::Const { ref ty } => {
(hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const {
ty: self.lower_ty(&ty, ImplTraitContext::disallowed()),
})
}
};

Expand Down
1 change: 1 addition & 0 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
})
}
}
Expand Down
18 changes: 17 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,24 +389,33 @@ impl PathSegment {
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct ConstArg {
pub value: AnonConst,
pub span: Span,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This span is identical to the span in body of AnonConst, is it viable to use it instead?
Other AnonConsts don't create extra spans during lowering as far as can I see.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(The whole ConstArg could be refactored away in that case.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, I see GenericArg::span wants to work in isolation without any contexts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we went through the same thought process when this was implemented. If you can see a way to refactor this, I'd be all ears.

}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum GenericArg {
Lifetime(Lifetime),
Type(Ty),
Const(ConstArg),
}

impl GenericArg {
pub fn span(&self) -> Span {
match self {
GenericArg::Lifetime(l) => l.span,
GenericArg::Type(t) => t.span,
GenericArg::Const(c) => c.span,
}
}

pub fn id(&self) -> NodeId {
match self {
GenericArg::Lifetime(l) => l.id,
GenericArg::Type(t) => t.id,
GenericArg::Const(c) => c.value.id,
}
}
}
Expand Down Expand Up @@ -448,6 +457,7 @@ impl GenericArgs {
}
break;
}
GenericArg::Const(_) => {}
}
}
}
Expand All @@ -464,6 +474,7 @@ impl GenericArgs {
match arg {
GenericArg::Lifetime(_) => own_counts.lifetimes += 1,
GenericArg::Type(_) => own_counts.types += 1,
GenericArg::Const(_) => own_counts.consts += 1,
};
}

Expand Down Expand Up @@ -528,6 +539,9 @@ pub enum GenericParamKind {
Type {
default: Option<P<Ty>>,
synthetic: Option<SyntheticTyParamKind>,
},
Const {
ty: P<Ty>,
}
}

Expand All @@ -548,6 +562,7 @@ pub struct GenericParam {
pub struct GenericParamCount {
pub lifetimes: usize,
pub types: usize,
pub consts: usize,
}

/// Represents lifetimes and type parameters attached to a declaration
Expand Down Expand Up @@ -582,6 +597,7 @@ impl Generics {
match param.kind {
GenericParamKind::Lifetime { .. } => own_counts.lifetimes += 1,
GenericParamKind::Type { .. } => own_counts.types += 1,
GenericParamKind::Const { .. } => own_counts.consts += 1,
};
}

Expand Down Expand Up @@ -1302,7 +1318,7 @@ impl BodyOwnerKind {
/// These are usually found nested inside types (e.g., array lengths)
/// or expressions (e.g., repeat counts), and also used to define
/// explicit discriminant values for enum variants.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
pub struct AnonConst {
pub id: NodeId,
pub hir_id: HirId,
Expand Down
13 changes: 0 additions & 13 deletions src/librustc/hir/pat_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,6 @@ impl hir::Pat {
}
}

pub fn is_const(&self) -> bool {
match self.node {
PatKind::Path(hir::QPath::TypeRelative(..)) => true,
PatKind::Path(hir::QPath::Resolved(_, ref path)) => {
match path.def {
Def::Const(..) | Def::AssociatedConst(..) => true,
_ => false
}
}
_ => false
}
}

/// Call `f` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn each_binding<F>(&self, mut f: F)
Expand Down
39 changes: 21 additions & 18 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1711,31 +1711,25 @@ impl<'a> State<'a> {
}
};

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);
}
let mut nonelided_generic_args: bool = false;
let elide_lifetimes = generic_args.args.iter().all(|arg| match arg {
GenericArg::Lifetime(lt) => lt.is_elided(),
_ => {
nonelided_generic_args = true;
true
}
}
if !elide_lifetimes {
});

if nonelided_generic_args {
start_or_comma(self)?;
self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
match generic_arg {
GenericArg::Lifetime(lt) => s.print_lifetime(lt),
GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
GenericArg::Lifetime(_) => Ok(()),
GenericArg::Type(ty) => s.print_type(ty),
GenericArg::Const(ct) => s.print_anon_const(&ct.value),
}
})?;
} else if !types.is_empty() {
start_or_comma(self)?;
self.commasep(Inconsistent, &types, |s, ty| s.print_type(&ty))?;
}

// FIXME(eddyb) This would leak into error messages, e.g.:
Expand Down Expand Up @@ -2106,7 +2100,12 @@ impl<'a> State<'a> {
}

pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> {
if let GenericParamKind::Const { .. } = param.kind {
self.word_space("const")?;
}

self.print_ident(param.name.ident())?;

match param.kind {
GenericParamKind::Lifetime { .. } => {
let mut sep = ":";
Expand All @@ -2133,6 +2132,10 @@ impl<'a> State<'a> {
_ => Ok(()),
}
}
GenericParamKind::Const { ref ty } => {
self.word_space(":")?;
self.print_type(ty)
}
}
}

Expand Down
11 changes: 10 additions & 1 deletion src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,11 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
Node::Ty(_) |
Node::MacroDef(_) => {}
_ => {
bug!("found unexpected thingy in worklist: {}",
self.tcx.hir().node_to_string(search_item))
bug!(
"found unexpected node kind in worklist: {} ({:?})",
self.tcx.hir().node_to_string(search_item),
node,
);
}
}
}
Expand Down
Loading