Skip to content

Commit 1b679fd

Browse files
JulianKnodtvarkor
authored andcommitted
Add has_default to GenericParamDefKind::Const
This currently creates a field which is always false on GenericParamDefKind for future use when consts are permitted to have defaults Update const_generics:default locations Previously just ignored them, now actually do something about them. Fix using type check instead of value Add parsing This adds all the necessary changes to lower const-generics defaults from parsing. Change P<Expr> to AnonConst This matches the arguments passed to instantiations of const generics, and makes it specific to just anonymous constants. Attempt to fix lowering bugs
1 parent d107a87 commit 1b679fd

File tree

48 files changed

+220
-92
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+220
-92
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ pub enum GenericParamKind {
368368
ty: P<Ty>,
369369
/// Span of the `const` keyword.
370370
kw_span: Span,
371+
default: Option<AnonConst>,
371372
},
372373
}
373374

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,8 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
790790
GenericParamKind::Type { default } => {
791791
visit_opt(default, |default| vis.visit_ty(default));
792792
}
793-
GenericParamKind::Const { ty, kw_span: _ } => {
793+
GenericParamKind::Const { ty, kw_span: _, default } => {
794+
visit_opt(default, |default| vis.visit_anon_const(default));
794795
vis.visit_ty(ty);
795796
}
796797
}

compiler/rustc_ast/src/visit.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,12 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Generi
578578
match param.kind {
579579
GenericParamKind::Lifetime => (),
580580
GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default),
581-
GenericParamKind::Const { ref ty, .. } => visitor.visit_ty(ty),
581+
GenericParamKind::Const { ref ty, ref default, .. } => {
582+
if let Some(default) = default {
583+
visitor.visit_anon_const(default);
584+
}
585+
visitor.visit_ty(ty);
586+
}
582587
}
583588
}
584589

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,13 +2242,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22422242

22432243
(hir::ParamName::Plain(param.ident), kind)
22442244
}
2245-
GenericParamKind::Const { ref ty, kw_span: _ } => {
2245+
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
22462246
let ty = self
22472247
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
22482248
this.lower_ty(&ty, ImplTraitContext::disallowed())
22492249
});
22502250

2251-
(hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty })
2251+
let default = default.as_ref().map(|def| self.lower_anon_const(def));
2252+
2253+
(hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty, default })
22522254
}
22532255
};
22542256

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11451145
}
11461146
}
11471147
}
1148+
if !self.session.features_untracked().const_generic_defaults {
1149+
if let GenericParamKind::Const { default: Some(ref default), .. } = param.kind {
1150+
let mut err = self.err_handler().struct_span_err(
1151+
default.value.span,
1152+
"default values for const generic parameters are unstable",
1153+
);
1154+
err.note("to enable them use #![feature(const_generic_defaults)]");
1155+
err.emit();
1156+
break;
1157+
}
1158+
}
11481159
}
11491160

11501161
validate_generic_param_order(
@@ -1155,7 +1166,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11551166
let (kind, ident) = match &param.kind {
11561167
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
11571168
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
1158-
GenericParamKind::Const { ref ty, kw_span: _ } => {
1169+
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
11591170
let ty = pprust::ty_to_string(ty);
11601171
let unordered = self.session.features_untracked().const_generics;
11611172
(

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,13 +2668,18 @@ impl<'a> State<'a> {
26682668
s.print_type(default)
26692669
}
26702670
}
2671-
ast::GenericParamKind::Const { ref ty, kw_span: _ } => {
2671+
ast::GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
26722672
s.word_space("const");
26732673
s.print_ident(param.ident);
26742674
s.s.space();
26752675
s.word_space(":");
26762676
s.print_type(ty);
2677-
s.print_type_bounds(":", &param.bounds)
2677+
s.print_type_bounds(":", &param.bounds);
2678+
if let Some(ref _default) = default {
2679+
s.s.space();
2680+
s.word_space("=");
2681+
// s.print_anon_const(&default);
2682+
}
26782683
}
26792684
}
26802685
});

compiler/rustc_builtin_macros/src/deriving/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ fn inject_impl_of_structural_trait(
145145
*default = None;
146146
ast::GenericArg::Type(cx.ty_ident(span, param.ident))
147147
}
148-
ast::GenericParamKind::Const { ty: _, kw_span: _ } => {
148+
ast::GenericParamKind::Const { ty: _, kw_span: _, default } => {
149+
*default = None;
149150
ast::GenericArg::Const(cx.const_ident(span, param.ident))
150151
}
151152
})

compiler/rustc_feature/src/active.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,9 @@ declare_features! (
620620
/// Allows arbitrary expressions in key-value attributes at parse time.
621621
(active, extended_key_value_attributes, "1.50.0", Some(78835), None),
622622

623+
/// Allows defaults const generics (e.g. `struct Foo<const N: usize = 3>(...);`).
624+
(active, const_generic_defaults, "1.51.0", Some(44580), None),
625+
623626
// -------------------------------------------------------------------------
624627
// feature-group-end: actual feature gates
625628
// -------------------------------------------------------------------------

compiler/rustc_hir/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ pub enum GenericParamKind<'hir> {
418418
},
419419
Const {
420420
ty: &'hir Ty<'hir>,
421+
default: Option<AnonConst>,
421422
},
422423
}
423424

compiler/rustc_hir/src/intravisit.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,12 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
877877
match param.kind {
878878
GenericParamKind::Lifetime { .. } => {}
879879
GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default),
880-
GenericParamKind::Const { ref ty } => visitor.visit_ty(ty),
880+
GenericParamKind::Const { ref ty, ref default } => {
881+
visitor.visit_ty(ty);
882+
if let Some(ref default) = default {
883+
visitor.visit_anon_const(default);
884+
}
885+
}
881886
}
882887
walk_list!(visitor, visit_param_bound, param.bounds);
883888
}

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,9 +2205,14 @@ impl<'a> State<'a> {
22052205
self.print_type(&default)
22062206
}
22072207
}
2208-
GenericParamKind::Const { ref ty } => {
2208+
GenericParamKind::Const { ref ty, ref default } => {
22092209
self.word_space(":");
2210-
self.print_type(ty)
2210+
self.print_type(ty);
2211+
if let Some(ref default) = default {
2212+
self.s.space();
2213+
self.word_space("=");
2214+
self.print_anon_const(&default)
2215+
}
22112216
}
22122217
}
22132218
}

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -947,10 +947,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
947947
.rev()
948948
.filter_map(|param| match param.kind {
949949
ty::GenericParamDefKind::Lifetime => None,
950-
ty::GenericParamDefKind::Type { has_default, .. } => {
950+
951+
ty::GenericParamDefKind::Type { has_default, .. }
952+
| ty::GenericParamDefKind::Const { has_default } => {
951953
Some((param.def_id, has_default))
952954
}
953-
ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
954955
})
955956
.peekable();
956957
let has_default = {

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2179,7 +2179,7 @@ impl<'tcx> TyCtxt<'tcx> {
21792179
let adt_def = self.adt_def(wrapper_def_id);
21802180
let substs =
21812181
InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {
2182-
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => bug!(),
2182+
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),
21832183
GenericParamDefKind::Type { has_default, .. } => {
21842184
if param.index == 0 {
21852185
ty_param.into()
@@ -2374,7 +2374,7 @@ impl<'tcx> TyCtxt<'tcx> {
23742374
self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
23752375
}
23762376
GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(),
2377-
GenericParamDefKind::Const => {
2377+
GenericParamDefKind::Const { .. } => {
23782378
self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into()
23792379
}
23802380
}

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ fn polymorphize<'tcx>(
592592
},
593593

594594
// Simple case: If parameter is a const or type parameter..
595-
ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if
595+
ty::GenericParamDefKind::Const { .. } | ty::GenericParamDefKind::Type { .. } if
596596
// ..and is within range and unused..
597597
unused.contains(param.index).unwrap_or(false) =>
598598
// ..then use the identity for this parameter.

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -790,15 +790,17 @@ pub enum GenericParamDefKind {
790790
object_lifetime_default: ObjectLifetimeDefault,
791791
synthetic: Option<hir::SyntheticTyParamKind>,
792792
},
793-
Const,
793+
Const {
794+
has_default: bool,
795+
},
794796
}
795797

796798
impl GenericParamDefKind {
797799
pub fn descr(&self) -> &'static str {
798800
match self {
799801
GenericParamDefKind::Lifetime => "lifetime",
800802
GenericParamDefKind::Type { .. } => "type",
801-
GenericParamDefKind::Const => "constant",
803+
GenericParamDefKind::Const { .. } => "constant",
802804
}
803805
}
804806
}
@@ -868,7 +870,7 @@ impl<'tcx> Generics {
868870
match param.kind {
869871
GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
870872
GenericParamDefKind::Type { .. } => own_counts.types += 1,
871-
GenericParamDefKind::Const => own_counts.consts += 1,
873+
GenericParamDefKind::Const { .. } => own_counts.consts += 1,
872874
};
873875
}
874876

@@ -891,7 +893,9 @@ impl<'tcx> Generics {
891893
pub fn own_requires_monomorphization(&self) -> bool {
892894
for param in &self.params {
893895
match param.kind {
894-
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
896+
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
897+
return true;
898+
}
895899
GenericParamDefKind::Lifetime => {}
896900
}
897901
}
@@ -934,7 +938,7 @@ impl<'tcx> Generics {
934938
pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef {
935939
let param = self.param_at(param.index as usize, tcx);
936940
match param.kind {
937-
GenericParamDefKind::Const => param,
941+
GenericParamDefKind::Const { .. } => param,
938942
_ => bug!("expected const parameter, but found another generic parameter"),
939943
}
940944
}

compiler/rustc_middle/src/ty/print/mod.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,17 +193,22 @@ pub trait Printer<'tcx>: Sized {
193193
.params
194194
.iter()
195195
.rev()
196-
.take_while(|param| {
197-
match param.kind {
198-
ty::GenericParamDefKind::Lifetime => false,
199-
ty::GenericParamDefKind::Type { has_default, .. } => {
200-
has_default
201-
&& substs[param.index as usize]
202-
== GenericArg::from(
203-
self.tcx().type_of(param.def_id).subst(self.tcx(), substs),
204-
)
205-
}
206-
ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults)
196+
.take_while(|param| match param.kind {
197+
ty::GenericParamDefKind::Lifetime => false,
198+
ty::GenericParamDefKind::Type { has_default, .. } => {
199+
has_default
200+
&& substs[param.index as usize]
201+
== GenericArg::from(
202+
self.tcx().type_of(param.def_id).subst(self.tcx(), substs),
203+
)
204+
}
205+
ty::GenericParamDefKind::Const { has_default } => {
206+
has_default
207+
&& substs[param.index as usize]
208+
== GenericArg::from(crate::ty::Const::from_anon_const(
209+
self.tcx(),
210+
param.def_id.expect_local(),
211+
))
207212
}
208213
})
209214
.count();

compiler/rustc_mir/src/monomorphize/collector.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,8 @@ fn create_mono_items_for_default_impls<'tcx>(
11801180
let substs =
11811181
InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind {
11821182
GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
1183-
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
1183+
GenericParamDefKind::Type { .. }
1184+
| GenericParamDefKind::Const { .. } => {
11841185
trait_ref.substs[param.index as usize]
11851186
}
11861187
});

compiler/rustc_parse/src/parser/generics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ impl<'a> Parser<'a> {
5656
self.expect(&token::Colon)?;
5757
let ty = self.parse_ty()?;
5858

59+
let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None };
60+
5961
Ok(GenericParam {
6062
ident,
6163
id: ast::DUMMY_NODE_ID,
6264
attrs: preceding_attrs.into(),
6365
bounds: Vec::new(),
64-
kind: GenericParamKind::Const { ty, kw_span: const_span },
66+
kind: GenericParamKind::Const { ty, kw_span: const_span, default },
6567
is_placeholder: false,
6668
})
6769
}

compiler/rustc_parse/src/parser/path.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -515,26 +515,32 @@ impl<'a> Parser<'a> {
515515
}
516516
}
517517

518+
/// Parse a const argument, e.g. `<3>`. It is assumed the angle brackets will be parsed by
519+
/// the caller.
520+
pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> {
521+
// Parse const argument.
522+
let value = if let token::OpenDelim(token::Brace) = self.token.kind {
523+
self.parse_block_expr(
524+
None,
525+
self.token.span,
526+
BlockCheckMode::Default,
527+
ast::AttrVec::new(),
528+
)?
529+
} else {
530+
self.handle_unambiguous_unbraced_const_arg()?
531+
};
532+
Ok(AnonConst { id: ast::DUMMY_NODE_ID, value })
533+
}
534+
518535
/// Parse a generic argument in a path segment.
519536
/// This does not include constraints, e.g., `Item = u8`, which is handled in `parse_angle_arg`.
520-
fn parse_generic_arg(&mut self) -> PResult<'a, Option<GenericArg>> {
537+
pub fn parse_generic_arg(&mut self) -> PResult<'a, Option<GenericArg>> {
521538
let start = self.token.span;
522539
let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
523540
// Parse lifetime argument.
524541
GenericArg::Lifetime(self.expect_lifetime())
525542
} else if self.check_const_arg() {
526-
// Parse const argument.
527-
let value = if let token::OpenDelim(token::Brace) = self.token.kind {
528-
self.parse_block_expr(
529-
None,
530-
self.token.span,
531-
BlockCheckMode::Default,
532-
ast::AttrVec::new(),
533-
)?
534-
} else {
535-
self.handle_unambiguous_unbraced_const_arg()?
536-
};
537-
GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })
543+
GenericArg::Const(self.parse_const_arg()?)
538544
} else if self.check_type() {
539545
// Parse type argument.
540546
match self.parse_ty() {

compiler/rustc_privacy/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -876,8 +876,13 @@ impl ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
876876
self.visit(self.ev.tcx.type_of(param.def_id));
877877
}
878878
}
879-
GenericParamDefKind::Const => {
879+
GenericParamDefKind::Const { has_default, .. } => {
880880
self.visit(self.ev.tcx.type_of(param.def_id));
881+
if has_default {
882+
// how should the error case be handled here?
883+
// let default_const = self.ev.tcx.const_eval_poly(param.def_id).unwrap();
884+
// self.visit(default_const);
885+
}
881886
}
882887
}
883888
}
@@ -1689,7 +1694,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> {
16891694
self.visit(self.tcx.type_of(param.def_id));
16901695
}
16911696
}
1692-
GenericParamDefKind::Const => {
1697+
GenericParamDefKind::Const { .. } => {
16931698
self.visit(self.tcx.type_of(param.def_id));
16941699
}
16951700
}

compiler/rustc_resolve/src/late.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
586586
// Allow all following defaults to refer to this type parameter.
587587
default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name));
588588
}
589-
GenericParamKind::Const { ref ty, kw_span: _ } => {
589+
GenericParamKind::Const { ref ty, kw_span: _, default: _ } => {
590590
for bound in &param.bounds {
591591
self.visit_param_bound(bound);
592592
}
@@ -595,6 +595,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
595595
self.visit_ty(ty);
596596
self.ribs[TypeNS].pop().unwrap();
597597
self.ribs[ValueNS].pop().unwrap();
598+
// FIXME(const_generics:default) do something with default here?
598599
}
599600
}
600601
}

0 commit comments

Comments
 (0)