Skip to content

Commit 9fe793a

Browse files
committed
Add query for const_param_default
1 parent 0e56a08 commit 9fe793a

File tree

17 files changed

+108
-27
lines changed

17 files changed

+108
-27
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,6 @@ pub enum GenericParamKind {
385385
ty: P<Ty>,
386386
/// Span of the `const` keyword.
387387
kw_span: Span,
388-
389388
/// Optional default value for the const generic param
390389
default: Option<AnonConst>,
391390
},

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.arena.alloc(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: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,15 +1877,12 @@ impl EncodeContext<'a, 'tcx> {
18771877
);
18781878
}
18791879
GenericParamKind::Const { ref default, .. } => {
1880-
self.encode_info_for_generic_param(
1881-
def_id.to_def_id(),
1882-
EntryKind::ConstParam,
1883-
true,
1884-
);
1880+
let def_id = def_id.to_def_id();
1881+
self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
18851882
if default.is_some() {
1886-
self.encode_stability(def_id.to_def_id());
1883+
self.encode_stability(def_id);
1884+
record!(self.tables.const_defaults[def_id] <- self.tcx.const_param_default(def_id))
18871885
}
1888-
// FIXME(const_generic_defaults)
18891886
}
18901887
}
18911888
}

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ define_tables! {
313313
// `DefPathTable` up front, since we may only ever use a few
314314
// definitions from any given crate.
315315
def_keys: Table<DefIndex, Lazy<DefKey>>,
316-
def_path_hashes: Table<DefIndex, Lazy<DefPathHash>>
316+
def_path_hashes: Table<DefIndex, Lazy<DefPathHash>>,
317+
const_defaults: Table<DefIndex, Lazy<rustc_middle::ty::Const<'tcx>>>,
317318
}
318319

319320
#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]

compiler/rustc_middle/src/query/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ rustc_queries! {
9393
desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
9494
}
9595

96+
/// Given the def_id of a const-generic parameter, computes the associated default const
97+
/// parameter. i.e. `fn example<const N: usize=3>` called on N would return 3.
98+
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
99+
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
100+
}
101+
96102
/// Records the type of every item.
97103
query type_of(key: DefId) -> Ty<'tcx> {
98104
desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ty::{self, Ty, TyCtxt};
55
use crate::ty::{ParamEnv, ParamEnvAnd};
66
use rustc_errors::ErrorReported;
77
use rustc_hir as hir;
8-
use rustc_hir::def_id::LocalDefId;
8+
use rustc_hir::def_id::{DefId, LocalDefId};
99
use rustc_macros::HashStable;
1010

1111
mod int;
@@ -44,11 +44,7 @@ impl<'tcx> Const<'tcx> {
4444
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
4545

4646
let body_id = match tcx.hir().get(hir_id) {
47-
hir::Node::AnonConst(ac)
48-
| hir::Node::GenericParam(hir::GenericParam {
49-
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },
50-
..
51-
}) => ac.body,
47+
hir::Node::AnonConst(ac) => ac.body,
5248
_ => span_bug!(
5349
tcx.def_span(def.did.to_def_id()),
5450
"from_anon_const can only process anonymous constants"
@@ -206,3 +202,19 @@ impl<'tcx> Const<'tcx> {
206202
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
207203
}
208204
}
205+
206+
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Const<'tcx> {
207+
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
208+
let default_def_id = match tcx.hir().get(hir_id) {
209+
hir::Node::AnonConst(ac)
210+
| hir::Node::GenericParam(hir::GenericParam {
211+
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },
212+
..
213+
}) => tcx.hir().local_def_id(ac.hir_id),
214+
_ => span_bug!(
215+
tcx.def_span(def_id),
216+
"const_param_defaults expected a generic parameter with a constant"
217+
),
218+
};
219+
Const::from_anon_const(tcx, default_def_id)
220+
}

compiler/rustc_middle/src/ty/generics.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ impl<'tcx> Generics {
120120
for param in &self.params {
121121
match param.kind {
122122
GenericParamDefKind::Lifetime => (),
123-
GenericParamDefKind::Type { has_default, .. } |
124-
GenericParamDefKind::Const { has_default } => {
123+
GenericParamDefKind::Type { has_default, .. }
124+
| GenericParamDefKind::Const { has_default } => {
125125
own_defaults.types += has_default as usize;
126126
}
127127
}
@@ -146,7 +146,9 @@ impl<'tcx> Generics {
146146
pub fn own_requires_monomorphization(&self) -> bool {
147147
for param in &self.params {
148148
match param.kind {
149-
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => return true,
149+
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
150+
return true;
151+
}
150152
GenericParamDefKind::Lifetime => {}
151153
}
152154
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
19491949
trait_impls_of: trait_def::trait_impls_of_provider,
19501950
all_local_trait_impls: trait_def::all_local_trait_impls,
19511951
type_uninhabited_from: inhabitedness::type_uninhabited_from,
1952+
const_param_default: consts::const_param_default,
19521953
..*providers
19531954
};
19541955
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,7 @@ pub trait Printer<'tcx>: Sized {
205205
ty::GenericParamDefKind::Const { has_default } => {
206206
has_default
207207
&& substs[param.index as usize]
208-
== GenericArg::from(crate::ty::Const::from_anon_const(
209-
self.tcx(),
210-
param.def_id.expect_local(),
211-
))
208+
== GenericArg::from(self.tcx().const_param_default(param.def_id))
212209
}
213210
})
214211
.count();

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
505505
}
506506
}
507507
GenericParamDefKind::Const { has_default } => {
508+
let ty = tcx.at(self.span).type_of(param.def_id);
508509
if !infer_args && has_default {
509-
ty::Const::from_anon_const(tcx, param.def_id.expect_local()).into()
510+
tcx.const_param_default(param.def_id).into()
510511
} else {
511-
let ty = tcx.at(self.span).type_of(param.def_id);
512512
if infer_args {
513513
self.astconv.ct_infer(ty, Some(param), self.span).into()
514514
} else {

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14451445
}
14461446
GenericParamDefKind::Const { has_default, .. } => {
14471447
if !infer_args && has_default {
1448-
ty::Const::from_anon_const(tcx, param.def_id.expect_local()).into()
1448+
tcx.const_param_default(param.def_id).into()
14491449
} else {
14501450
self.fcx.var_for_def(self.span, param)
14511451
}

compiler/rustc_typeck/src/check/wfcheck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ fn check_where_clauses<'tcx, 'fcx>(
774774
}
775775
GenericParamDefKind::Const { .. } => {
776776
if is_our_default(param) {
777-
let default_ct = ty::Const::from_anon_const(tcx, param.def_id.expect_local());
777+
let default_ct = tcx.const_param_default(param.def_id);
778778
// Const params have to currently be concrete.
779779
assert!(!default_ct.needs_subst());
780780
default_ct.into()

compiler/rustc_typeck/src/collect.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,11 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
257257
hir::GenericParamKind::Const { default, .. } => {
258258
let def_id = self.tcx.hir().local_def_id(param.hir_id);
259259
self.tcx.ensure().type_of(def_id);
260-
// FIXME(const_generics_defaults)
261260
if let Some(default) = default {
262261
let def_id = self.tcx.hir().local_def_id(default.hir_id);
262+
// need to store default and type of default
263263
self.tcx.ensure().type_of(def_id);
264+
self.tcx.ensure().const_param_default(def_id);
264265
}
265266
}
266267
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(const_generics)]
2+
#![feature(const_generics_defaults)]
3+
#![allow(incomplete_features)]
4+
5+
pub struct Defaulted<const N: usize=3>;
6+
impl Defaulted {
7+
pub fn new() -> Self {
8+
Defaulted
9+
}
10+
}
11+
impl<const N: usize> Defaulted<N> {
12+
pub fn value(&self) -> usize {
13+
N
14+
}
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// aux-build:const_defaulty.rs
2+
// check-pass
3+
#![feature(const_generics_defaults)]
4+
#![allow(incomplete_features)]
5+
6+
extern crate const_defaulty;
7+
use const_defaulty::Defaulted;
8+
9+
struct Local<const N: usize=4>;
10+
impl Local {
11+
fn new() -> Self {
12+
Local
13+
}
14+
}
15+
impl<const N: usize>Local<N> {
16+
fn value(&self) -> usize {
17+
N
18+
}
19+
}
20+
21+
fn main() {
22+
let v = Defaulted::new();
23+
assert_eq!(v.value(), 3);
24+
25+
let l = Local::new();
26+
assert_eq!(l.value(), 4);
27+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
#![crate_type = "lib"]
3+
#![feature(const_generics_defaults)]
4+
#![allow(incomplete_features)]
5+
6+
struct Both<T=u32, const N: usize=3> {
7+
arr: [T; N]
8+
}
9+
10+
trait BothTrait<T=u32, const N: usize=3> {}
11+
12+
enum BothEnum<T=u32, const N: usize=3> {
13+
Dummy([T; N])
14+
}

0 commit comments

Comments
 (0)