Skip to content

Commit 5b33de3

Browse files
committed
Auto merge of #75384 - JulianKnodt:cg_def, r=varkor,lcnr
implement `feature(const_generics_defaults)` Implements const generics defaults `struct Example<const N: usize=3>`, as well as a query for getting the default of a given const-parameter's def id. There are some remaining FIXME's but they were specified as not blocking for merging this PR. This also puts the defaults behind the unstable feature gate `#![feature(const_generics_defaults)]`. ~~This currently creates a field which is always false on `GenericParamDefKind` for future use when consts are permitted to have defaults. I'm not sure if this is exactly what is best for adding default parameters, but I mimicked the style of type defaults, so hopefully this is ok.~~ r? `@lcnr`
2 parents db492ec + 33370fd commit 5b33de3

File tree

73 files changed

+517
-191
lines changed

Some content is hidden

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

73 files changed

+517
-191
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2290,7 +2290,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22902290
this.lower_ty(&ty, ImplTraitContext::disallowed())
22912291
});
22922292
let default = default.as_ref().map(|def| self.lower_anon_const(def));
2293-
22942293
(hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty, default })
22952294
}
22962295
};

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,20 +1150,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11501150
}
11511151

11521152
fn visit_generics(&mut self, generics: &'a Generics) {
1153-
let mut prev_ty_default = None;
1153+
let cg_defaults = self.session.features_untracked().const_generics_defaults;
1154+
1155+
let mut prev_param_default = None;
11541156
for param in &generics.params {
11551157
match param.kind {
11561158
GenericParamKind::Lifetime => (),
1157-
GenericParamKind::Type { default: Some(_), .. } => {
1158-
prev_ty_default = Some(param.ident.span);
1159+
GenericParamKind::Type { default: Some(_), .. }
1160+
| GenericParamKind::Const { default: Some(_), .. } => {
1161+
prev_param_default = Some(param.ident.span);
11591162
}
11601163
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
1161-
if let Some(span) = prev_ty_default {
1164+
if let Some(span) = prev_param_default {
11621165
let mut err = self.err_handler().struct_span_err(
11631166
span,
1164-
"type parameters with a default must be trailing",
1167+
"generic parameters with a default must be trailing",
11651168
);
1166-
if matches!(param.kind, GenericParamKind::Const { .. }) {
1169+
if matches!(param.kind, GenericParamKind::Const { .. }) && !cg_defaults {
11671170
err.note(
11681171
"using type defaults and const parameters \
11691172
in the same parameter list is currently not permitted",

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2659,8 +2659,10 @@ impl<'a> State<'a> {
26592659
s.word_space(":");
26602660
s.print_type(ty);
26612661
s.print_type_bounds(":", &param.bounds);
2662-
if let Some(ref _default) = default {
2663-
// FIXME(const_generics_defaults): print the `default` value here
2662+
if let Some(ref default) = default {
2663+
s.s.space();
2664+
s.word_space("=");
2665+
s.print_expr(&default.value);
26642666
}
26652667
}
26662668
}

compiler/rustc_error_codes/src/error_codes/E0128.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct Foo<T = U, U = ()> {
77
field1: T,
88
field2: U,
99
}
10-
// error: type parameters with a default cannot use forward declared
10+
// error: generic parameters with a default cannot use forward declared
1111
// identifiers
1212
```
1313

compiler/rustc_hir/src/intravisit.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,9 @@ pub trait Visitor<'v>: Sized {
366366
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) {
367367
walk_generic_param(self, p)
368368
}
369+
fn visit_const_param_default(&mut self, _param: HirId, ct: &'v AnonConst) {
370+
walk_const_param_default(self, ct)
371+
}
369372
fn visit_generics(&mut self, g: &'v Generics<'v>) {
370373
walk_generics(self, g)
371374
}
@@ -869,13 +872,17 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
869872
GenericParamKind::Const { ref ty, ref default } => {
870873
visitor.visit_ty(ty);
871874
if let Some(ref default) = default {
872-
visitor.visit_anon_const(default);
875+
visitor.visit_const_param_default(param.hir_id, default);
873876
}
874877
}
875878
}
876879
walk_list!(visitor, visit_param_bound, param.bounds);
877880
}
878881

882+
pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v AnonConst) {
883+
visitor.visit_anon_const(ct)
884+
}
885+
879886
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) {
880887
walk_list!(visitor, visit_generic_param, generics.params);
881888
walk_list!(visitor, visit_where_predicate, generics.where_clause.predicates);

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,8 +2266,10 @@ impl<'a> State<'a> {
22662266
GenericParamKind::Const { ref ty, ref default } => {
22672267
self.word_space(":");
22682268
self.print_type(ty);
2269-
if let Some(ref _default) = default {
2270-
// FIXME(const_generics_defaults): print the `default` value here
2269+
if let Some(ref default) = default {
2270+
self.s.space();
2271+
self.word_space("=");
2272+
self.print_anon_const(&default)
22712273
}
22722274
}
22732275
}

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

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use rustc_hir::{Item, ItemKind, Node};
6767
use rustc_middle::ty::error::TypeError;
6868
use rustc_middle::ty::{
6969
self,
70-
subst::{Subst, SubstsRef},
70+
subst::{GenericArgKind, Subst, SubstsRef},
7171
Region, Ty, TyCtxt, TypeFoldable,
7272
};
7373
use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
@@ -957,33 +957,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
957957
) -> SubstsRef<'tcx> {
958958
let generics = self.tcx.generics_of(def_id);
959959
let mut num_supplied_defaults = 0;
960-
let mut type_params = generics
961-
.params
962-
.iter()
963-
.rev()
964-
.filter_map(|param| match param.kind {
965-
ty::GenericParamDefKind::Lifetime => None,
966-
ty::GenericParamDefKind::Type { has_default, .. } => {
967-
Some((param.def_id, has_default))
968-
}
969-
ty::GenericParamDefKind::Const => None, // FIXME(const_generics_defaults)
970-
})
971-
.peekable();
972-
let has_default = {
973-
let has_default = type_params.peek().map(|(_, has_default)| has_default);
974-
*has_default.unwrap_or(&false)
975-
};
976-
if has_default {
977-
let types = substs.types().rev();
978-
for ((def_id, has_default), actual) in type_params.zip(types) {
979-
if !has_default {
980-
break;
960+
961+
let default_params = generics.params.iter().rev().filter_map(|param| match param.kind {
962+
ty::GenericParamDefKind::Type { has_default: true, .. } => Some(param.def_id),
963+
ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id),
964+
_ => None,
965+
});
966+
for (def_id, actual) in default_params.zip(substs.iter().rev()) {
967+
match actual.unpack() {
968+
GenericArgKind::Const(c) => {
969+
if self.tcx.const_param_default(def_id).subst(self.tcx, substs) != c {
970+
break;
971+
}
981972
}
982-
if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual {
983-
break;
973+
GenericArgKind::Type(ty) => {
974+
if self.tcx.type_of(def_id).subst(self.tcx, substs) != ty {
975+
break;
976+
}
984977
}
985-
num_supplied_defaults += 1;
978+
_ => break,
986979
}
980+
num_supplied_defaults += 1;
987981
}
988982
let len = generics.params.len();
989983
let mut generics = generics.clone();

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
953953
self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess))
954954
}
955955

956+
fn get_const_param_default(
957+
&self,
958+
tcx: TyCtxt<'tcx>,
959+
id: DefIndex,
960+
) -> rustc_middle::ty::Const<'tcx> {
961+
self.root.tables.const_defaults.get(self, id).unwrap().decode((self, tcx))
962+
}
963+
956964
/// Iterates over all the stability attributes in the given crate.
957965
fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
958966
// FIXME: For a proc macro crate, not sure whether we should return the "host"

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
122122
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
123123
mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) }
124124
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
125+
const_param_default => { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) }
125126
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
126127
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
127128
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,13 +1876,12 @@ impl EncodeContext<'a, 'tcx> {
18761876
default.is_some(),
18771877
);
18781878
}
1879-
GenericParamKind::Const { .. } => {
1880-
self.encode_info_for_generic_param(
1881-
def_id.to_def_id(),
1882-
EntryKind::ConstParam,
1883-
true,
1884-
);
1885-
// FIXME(const_generics_defaults)
1879+
GenericParamKind::Const { ref default, .. } => {
1880+
let def_id = def_id.to_def_id();
1881+
self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
1882+
if default.is_some() {
1883+
record!(self.tables.const_defaults[def_id] <- self.tcx.const_param_default(def_id))
1884+
}
18861885
}
18871886
}
18881887
}

0 commit comments

Comments
 (0)