diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index d6f2773cc47ce..aa9c255c6331c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2660,11 +2660,10 @@ impl<'a> State<'a> { s.print_type(ty); s.print_type_bounds(":", ¶m.bounds); // FIXME(const_generic_defaults) - if let Some(ref _default) = default { - // FIXME(const_generics_defaults): print the `default` value here + if let Some(ref default) = default { s.s.space(); s.word_space("="); - // s.print_anon_const(&default); + s.print_expr(&default.value); } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 7df80b2b5b9a4..f4717fc08c78d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -963,10 +963,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .rev() .filter_map(|param| match param.kind { ty::GenericParamDefKind::Lifetime => None, - ty::GenericParamDefKind::Const { has_default } - | ty::GenericParamDefKind::Type { has_default, .. } => { + ty::GenericParamDefKind::Type { has_default, .. } => { Some((param.def_id, has_default)) } + // FIXME(const_generics:defaults) + ty::GenericParamDefKind::Const { has_default: _has_default } => None, }) .peekable(); let has_default = { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 7f8f5ef442701..e10041a297142 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -122,7 +122,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, 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) } 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)) } + const_param_default => { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) } mir_const_qualif => { cdata.mir_const_qualif(def_id.index) } fn_sig => { cdata.fn_sig(def_id.index, tcx) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 94722ad2051bd..7cfb051e703c5 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -307,6 +307,7 @@ define_tables! { mir_for_ctfe: Table)>, promoted_mir: Table>)>, mir_abstract_consts: Table])>, + const_defaults: Table>>, unused_generic_params: Table>>, // `def_keys` and `def_path_hashes` represent a lazy version of a // `DefPathTable`. This allows us to avoid deserializing an entire @@ -314,7 +315,6 @@ define_tables! { // definitions from any given crate. def_keys: Table>, def_path_hashes: Table>, - const_defaults: Table>>, } #[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)] diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 6821efcdcc52b..343438e975e04 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -206,8 +206,7 @@ impl<'tcx> Const<'tcx> { 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 { + hir::Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) }, .. }) => tcx.hir().local_def_id(ac.hir_id), diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 78a9f2daeb3f7..d30a8693959f3 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -120,10 +120,12 @@ impl<'tcx> Generics { for param in &self.params { match param.kind { GenericParamDefKind::Lifetime => (), - GenericParamDefKind::Type { has_default, .. } - | GenericParamDefKind::Const { has_default } => { + GenericParamDefKind::Type { has_default, .. } => { own_defaults.types += has_default as usize; } + GenericParamDefKind::Const { has_default } => { + own_defaults.consts += has_default as usize; + } } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index d9789dda2ea9e..e092bb845ffac 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -931,10 +931,7 @@ impl ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { GenericParamDefKind::Const { has_default, .. } => { self.visit(self.ev.tcx.type_of(param.def_id)); if has_default { - // FIXME(const_generic_defaults) - // how should the error case be handled here? - // let default_const = self.ev.tcx.const_eval_poly(param.def_id).unwrap(); - // self.visit(default_const); + self.visit(self.ev.tcx.const_param_default(param.def_id)); } } } @@ -1747,6 +1744,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> { self.visit(self.tcx.type_of(param.def_id)); } } + // FIXME(const_evaluatable_checked): May want to look inside const here GenericParamDefKind::Const { .. } => { self.visit(self.tcx.type_of(param.def_id)); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 85c5128591a32..cb0eea1b7067c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -258,9 +258,9 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { let def_id = self.tcx.hir().local_def_id(param.hir_id); self.tcx.ensure().type_of(def_id); if let Some(default) = default { - let def_id = self.tcx.hir().local_def_id(default.hir_id); + let default_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(default_def_id); self.tcx.ensure().const_param_default(def_id); } } diff --git a/src/test/ui/const-generics/defaults/default-annotation.rs b/src/test/ui/const-generics/defaults/default-annotation.rs new file mode 100644 index 0000000000000..e6e8d732beef3 --- /dev/null +++ b/src/test/ui/const-generics/defaults/default-annotation.rs @@ -0,0 +1,20 @@ +// run-pass +#![feature(staged_api)] + +#![feature(const_generics)] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +#![stable(feature = "const_default_test", since="none")] + + +#[unstable(feature = "const_default_stable", issue="none")] +pub struct ConstDefaultUnstable; + +#[stable(feature = "const_default_unstable", since="none")] +pub struct ConstDefaultStable; + +fn main() {} diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.rs b/src/test/ui/const-generics/defaults/pretty-printing-ast.rs new file mode 100644 index 0000000000000..a25d4baca1a97 --- /dev/null +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.rs @@ -0,0 +1,13 @@ +// Test the AST pretty printer correctly handles default values for const generics +// check-pass +// compile-flags: -Z unpretty=expanded + +#![crate_type = "lib"] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] + +trait Foo {} + +fn foo() {} + +struct Range; diff --git a/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout new file mode 100644 index 0000000000000..f7a1d2ca4b2ef --- /dev/null +++ b/src/test/ui/const-generics/defaults/pretty-printing-ast.stdout @@ -0,0 +1,20 @@ +#![feature(prelude_import)] +#![no_std] +// Test the AST pretty printer correctly handles default values for const generics +// check-pass +// compile-flags: -Z unpretty=expanded + +#![crate_type = "lib"] +#![feature(const_generics_defaults)] +#![allow(incomplete_features)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +trait Foo { } + +fn foo() { } + +struct Range;