Add query for const_param_default
This commit is contained in:
parent
0e56a086f7
commit
9fe793ae5d
@ -385,7 +385,6 @@ pub enum GenericParamKind {
|
|||||||
ty: P<Ty>,
|
ty: P<Ty>,
|
||||||
/// Span of the `const` keyword.
|
/// Span of the `const` keyword.
|
||||||
kw_span: Span,
|
kw_span: Span,
|
||||||
|
|
||||||
/// Optional default value for the const generic param
|
/// Optional default value for the const generic param
|
||||||
default: Option<AnonConst>,
|
default: Option<AnonConst>,
|
||||||
},
|
},
|
||||||
|
@ -953,6 +953,14 @@ fn get_expn_that_defined(&self, id: DefIndex, sess: &Session) -> ExpnId {
|
|||||||
self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess))
|
self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_const_param_default(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
id: DefIndex,
|
||||||
|
) -> rustc_middle::ty::Const<'tcx> {
|
||||||
|
self.root.tables.const_defaults.get(self, id).unwrap().decode((self, tcx))
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterates over all the stability attributes in the given crate.
|
/// Iterates over all the stability attributes in the given crate.
|
||||||
fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
|
fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
|
||||||
// FIXME: For a proc macro crate, not sure whether we should return the "host"
|
// FIXME: For a proc macro crate, not sure whether we should return the "host"
|
||||||
|
@ -122,6 +122,7 @@ fn into_args(self) -> (DefId, DefId) {
|
|||||||
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
|
||||||
mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) }
|
mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) }
|
||||||
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
|
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }
|
||||||
|
const_param_default => { tcx.arena.alloc(cdata.get_const_param_default(tcx, def_id.index)) }
|
||||||
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
|
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
|
||||||
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
|
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
|
||||||
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
|
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
|
||||||
|
@ -1877,15 +1877,12 @@ fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
GenericParamKind::Const { ref default, .. } => {
|
GenericParamKind::Const { ref default, .. } => {
|
||||||
self.encode_info_for_generic_param(
|
let def_id = def_id.to_def_id();
|
||||||
def_id.to_def_id(),
|
self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
|
||||||
EntryKind::ConstParam,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
if default.is_some() {
|
if default.is_some() {
|
||||||
self.encode_stability(def_id.to_def_id());
|
self.encode_stability(def_id);
|
||||||
|
record!(self.tables.const_defaults[def_id] <- self.tcx.const_param_default(def_id))
|
||||||
}
|
}
|
||||||
// FIXME(const_generic_defaults)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,8 @@ fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
|
|||||||
// `DefPathTable` up front, since we may only ever use a few
|
// `DefPathTable` up front, since we may only ever use a few
|
||||||
// definitions from any given crate.
|
// definitions from any given crate.
|
||||||
def_keys: Table<DefIndex, Lazy<DefKey>>,
|
def_keys: Table<DefIndex, Lazy<DefKey>>,
|
||||||
def_path_hashes: Table<DefIndex, Lazy<DefPathHash>>
|
def_path_hashes: Table<DefIndex, Lazy<DefPathHash>>,
|
||||||
|
const_defaults: Table<DefIndex, Lazy<rustc_middle::ty::Const<'tcx>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
|
#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
|
||||||
|
@ -93,6 +93,12 @@
|
|||||||
desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
|
desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given the def_id of a const-generic parameter, computes the associated default const
|
||||||
|
/// parameter. i.e. `fn example<const N: usize=3>` called on N would return 3.
|
||||||
|
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
|
||||||
|
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Records the type of every item.
|
/// Records the type of every item.
|
||||||
query type_of(key: DefId) -> Ty<'tcx> {
|
query type_of(key: DefId) -> Ty<'tcx> {
|
||||||
desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
|
desc { |tcx| "computing type of `{}`", tcx.def_path_str(key) }
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use crate::ty::{ParamEnv, ParamEnvAnd};
|
use crate::ty::{ParamEnv, ParamEnvAnd};
|
||||||
use rustc_errors::ErrorReported;
|
use rustc_errors::ErrorReported;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_macros::HashStable;
|
use rustc_macros::HashStable;
|
||||||
|
|
||||||
mod int;
|
mod int;
|
||||||
@ -44,11 +44,7 @@ pub fn from_opt_const_arg_anon_const(
|
|||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||||
|
|
||||||
let body_id = match tcx.hir().get(hir_id) {
|
let body_id = match tcx.hir().get(hir_id) {
|
||||||
hir::Node::AnonConst(ac)
|
hir::Node::AnonConst(ac) => ac.body,
|
||||||
| hir::Node::GenericParam(hir::GenericParam {
|
|
||||||
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },
|
|
||||||
..
|
|
||||||
}) => ac.body,
|
|
||||||
_ => span_bug!(
|
_ => span_bug!(
|
||||||
tcx.def_span(def.did.to_def_id()),
|
tcx.def_span(def.did.to_def_id()),
|
||||||
"from_anon_const can only process anonymous constants"
|
"from_anon_const can only process anonymous constants"
|
||||||
@ -206,3 +202,19 @@ pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
|
|||||||
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
|
.unwrap_or_else(|| bug!("expected usize, got {:#?}", self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Const<'tcx> {
|
||||||
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||||
|
let default_def_id = match tcx.hir().get(hir_id) {
|
||||||
|
hir::Node::AnonConst(ac)
|
||||||
|
| hir::Node::GenericParam(hir::GenericParam {
|
||||||
|
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },
|
||||||
|
..
|
||||||
|
}) => tcx.hir().local_def_id(ac.hir_id),
|
||||||
|
_ => span_bug!(
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
"const_param_defaults expected a generic parameter with a constant"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
Const::from_anon_const(tcx, default_def_id)
|
||||||
|
}
|
||||||
|
@ -120,8 +120,8 @@ pub fn own_defaults(&self) -> GenericParamCount {
|
|||||||
for param in &self.params {
|
for param in &self.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => (),
|
GenericParamDefKind::Lifetime => (),
|
||||||
GenericParamDefKind::Type { has_default, .. } |
|
GenericParamDefKind::Type { has_default, .. }
|
||||||
GenericParamDefKind::Const { has_default } => {
|
| GenericParamDefKind::Const { has_default } => {
|
||||||
own_defaults.types += has_default as usize;
|
own_defaults.types += has_default as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +146,9 @@ pub fn requires_monomorphization(&self, tcx: TyCtxt<'tcx>) -> bool {
|
|||||||
pub fn own_requires_monomorphization(&self) -> bool {
|
pub fn own_requires_monomorphization(&self) -> bool {
|
||||||
for param in &self.params {
|
for param in &self.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => return true,
|
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
GenericParamDefKind::Lifetime => {}
|
GenericParamDefKind::Lifetime => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1949,6 +1949,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
|||||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||||
all_local_trait_impls: trait_def::all_local_trait_impls,
|
all_local_trait_impls: trait_def::all_local_trait_impls,
|
||||||
type_uninhabited_from: inhabitedness::type_uninhabited_from,
|
type_uninhabited_from: inhabitedness::type_uninhabited_from,
|
||||||
|
const_param_default: consts::const_param_default,
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -205,10 +205,7 @@ fn generic_args_to_print(
|
|||||||
ty::GenericParamDefKind::Const { has_default } => {
|
ty::GenericParamDefKind::Const { has_default } => {
|
||||||
has_default
|
has_default
|
||||||
&& substs[param.index as usize]
|
&& substs[param.index as usize]
|
||||||
== GenericArg::from(crate::ty::Const::from_anon_const(
|
== GenericArg::from(self.tcx().const_param_default(param.def_id))
|
||||||
self.tcx(),
|
|
||||||
param.def_id.expect_local(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.count();
|
.count();
|
||||||
|
@ -505,10 +505,10 @@ fn inferred_kind(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Const { has_default } => {
|
GenericParamDefKind::Const { has_default } => {
|
||||||
|
let ty = tcx.at(self.span).type_of(param.def_id);
|
||||||
if !infer_args && has_default {
|
if !infer_args && has_default {
|
||||||
ty::Const::from_anon_const(tcx, param.def_id.expect_local()).into()
|
tcx.const_param_default(param.def_id).into()
|
||||||
} else {
|
} else {
|
||||||
let ty = tcx.at(self.span).type_of(param.def_id);
|
|
||||||
if infer_args {
|
if infer_args {
|
||||||
self.astconv.ct_infer(ty, Some(param), self.span).into()
|
self.astconv.ct_infer(ty, Some(param), self.span).into()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1445,7 +1445,7 @@ fn inferred_kind(
|
|||||||
}
|
}
|
||||||
GenericParamDefKind::Const { has_default, .. } => {
|
GenericParamDefKind::Const { has_default, .. } => {
|
||||||
if !infer_args && has_default {
|
if !infer_args && has_default {
|
||||||
ty::Const::from_anon_const(tcx, param.def_id.expect_local()).into()
|
tcx.const_param_default(param.def_id).into()
|
||||||
} else {
|
} else {
|
||||||
self.fcx.var_for_def(self.span, param)
|
self.fcx.var_for_def(self.span, param)
|
||||||
}
|
}
|
||||||
|
@ -774,7 +774,7 @@ fn check_where_clauses<'tcx, 'fcx>(
|
|||||||
}
|
}
|
||||||
GenericParamDefKind::Const { .. } => {
|
GenericParamDefKind::Const { .. } => {
|
||||||
if is_our_default(param) {
|
if is_our_default(param) {
|
||||||
let default_ct = ty::Const::from_anon_const(tcx, param.def_id.expect_local());
|
let default_ct = tcx.const_param_default(param.def_id);
|
||||||
// Const params have to currently be concrete.
|
// Const params have to currently be concrete.
|
||||||
assert!(!default_ct.needs_subst());
|
assert!(!default_ct.needs_subst());
|
||||||
default_ct.into()
|
default_ct.into()
|
||||||
|
@ -257,10 +257,11 @@ fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
|
|||||||
hir::GenericParamKind::Const { default, .. } => {
|
hir::GenericParamKind::Const { default, .. } => {
|
||||||
let def_id = self.tcx.hir().local_def_id(param.hir_id);
|
let def_id = self.tcx.hir().local_def_id(param.hir_id);
|
||||||
self.tcx.ensure().type_of(def_id);
|
self.tcx.ensure().type_of(def_id);
|
||||||
// FIXME(const_generics_defaults)
|
|
||||||
if let Some(default) = default {
|
if let Some(default) = default {
|
||||||
let def_id = self.tcx.hir().local_def_id(default.hir_id);
|
let def_id = self.tcx.hir().local_def_id(default.hir_id);
|
||||||
|
// need to store default and type of default
|
||||||
self.tcx.ensure().type_of(def_id);
|
self.tcx.ensure().type_of(def_id);
|
||||||
|
self.tcx.ensure().const_param_default(def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
#![feature(const_generics)]
|
||||||
|
#![feature(const_generics_defaults)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
pub struct Defaulted<const N: usize=3>;
|
||||||
|
impl Defaulted {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Defaulted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<const N: usize> Defaulted<N> {
|
||||||
|
pub fn value(&self) -> usize {
|
||||||
|
N
|
||||||
|
}
|
||||||
|
}
|
27
src/test/ui/const-generics/defaults/external.rs
Normal file
27
src/test/ui/const-generics/defaults/external.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// aux-build:const_defaulty.rs
|
||||||
|
// check-pass
|
||||||
|
#![feature(const_generics_defaults)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
extern crate const_defaulty;
|
||||||
|
use const_defaulty::Defaulted;
|
||||||
|
|
||||||
|
struct Local<const N: usize=4>;
|
||||||
|
impl Local {
|
||||||
|
fn new() -> Self {
|
||||||
|
Local
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<const N: usize>Local<N> {
|
||||||
|
fn value(&self) -> usize {
|
||||||
|
N
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = Defaulted::new();
|
||||||
|
assert_eq!(v.value(), 3);
|
||||||
|
|
||||||
|
let l = Local::new();
|
||||||
|
assert_eq!(l.value(), 4);
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
// check-pass
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(const_generics_defaults)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
struct Both<T=u32, const N: usize=3> {
|
||||||
|
arr: [T; N]
|
||||||
|
}
|
||||||
|
|
||||||
|
trait BothTrait<T=u32, const N: usize=3> {}
|
||||||
|
|
||||||
|
enum BothEnum<T=u32, const N: usize=3> {
|
||||||
|
Dummy([T; N])
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user