From 7116bb5c33c1b0d12a7dade3fa20c9b0e2e08218 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 20 Mar 2021 22:34:58 +0000 Subject: [PATCH] Update with comments --- compiler/rustc_ast_pretty/src/pprust/state.rs | 1 - .../src/infer/error_reporting/mod.rs | 61 +++++++++++-------- compiler/rustc_metadata/src/rmeta/encoder.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_typeck/src/check/wfcheck.rs | 2 +- .../min_const_generics/const_default_first.rs | 9 +++ .../const_default_first.stderr | 8 +++ .../type_and_const_defaults.rs | 19 +++++- 9 files changed, 72 insertions(+), 33 deletions(-) create mode 100644 src/test/ui/const-generics/min_const_generics/const_default_first.rs create mode 100644 src/test/ui/const-generics/min_const_generics/const_default_first.stderr diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index aa9c255c6331c..84f8ce5706ae6 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2659,7 +2659,6 @@ impl<'a> State<'a> { s.word_space(":"); s.print_type(ty); s.print_type_bounds(":", ¶m.bounds); - // FIXME(const_generic_defaults) if let Some(ref default) = default { s.s.space(); s.word_space("="); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index f4717fc08c78d..98904206b215c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -957,34 +957,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> SubstsRef<'tcx> { let generics = self.tcx.generics_of(def_id); let mut num_supplied_defaults = 0; - let mut type_params = generics - .params - .iter() - .rev() - .filter_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => None, - 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 = { - let has_default = type_params.peek().map(|(_, has_default)| has_default); - *has_default.unwrap_or(&false) - }; - if has_default { - let types = substs.types().rev(); - for ((def_id, has_default), actual) in type_params.zip(types) { - if !has_default { - break; + + #[derive(PartialEq, Eq, Copy, Clone)] + enum Kind { + Const, + Type, + } + let default_params = generics.params.iter().rev().filter_map(|param| match param.kind { + ty::GenericParamDefKind::Type { has_default: true, .. } => { + Some((param.def_id, Kind::Type)) + } + ty::GenericParamDefKind::Const { has_default: true } => { + Some((param.def_id, Kind::Const)) + } + _ => None, + }); + let mut types = substs.types().rev(); + let mut consts = substs.consts().rev(); + for (def_id, kind) in default_params { + match kind { + Kind::Const => { + if let Some(actual) = consts.next() { + if ty::Const::from_anon_const(self.tcx, def_id.expect_local()) != actual { + break; + } + } else { + break; + } } - if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual { - break; + Kind::Type => { + if let Some(actual) = types.next() { + if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual { + break; + } + } else { + break; + } } - num_supplied_defaults += 1; } + num_supplied_defaults += 1; } let len = generics.params.len(); let mut generics = generics.clone(); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index fea7ea44c674a..d055c275299a6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1880,7 +1880,6 @@ impl EncodeContext<'a, 'tcx> { let def_id = def_id.to_def_id(); self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true); if default.is_some() { - self.encode_stability(def_id); record!(self.tables.const_defaults[def_id] <- self.tcx.const_param_default(def_id)) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1666c6065b7de..36162cfe92452 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -94,7 +94,7 @@ rustc_queries! { } /// Given the def_id of a const-generic parameter, computes the associated default const - /// parameter. i.e. `fn example` called on N would return 3. + /// parameter. e.g. `fn example` 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) } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 343438e975e04..c78151271c171 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -212,7 +212,7 @@ pub fn const_param_default<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Cons }) => 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_param_default` expected a generic parameter with a constant" ), }; Const::from_anon_const(tcx, default_def_id) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 8ac24a969f8cb..5f302f7d0a94e 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -775,7 +775,7 @@ fn check_where_clauses<'tcx, 'fcx>( GenericParamDefKind::Const { .. } => { if is_our_default(param) { let default_ct = tcx.const_param_default(param.def_id); - // Const params have to currently be concrete. + // Const params currently have to be concrete. assert!(!default_ct.needs_subst()); default_ct.into() } else { diff --git a/src/test/ui/const-generics/min_const_generics/const_default_first.rs b/src/test/ui/const-generics/min_const_generics/const_default_first.rs new file mode 100644 index 0000000000000..ae82c85eb7e4b --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/const_default_first.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] +#![feature(const_generics)] +#![feature(const_generics_defaults)] +#![allow(incomplete_features, dead_code)] + +struct Both { +//~^ ERROR: generic parameters with a default must be + v: T +} diff --git a/src/test/ui/const-generics/min_const_generics/const_default_first.stderr b/src/test/ui/const-generics/min_const_generics/const_default_first.stderr new file mode 100644 index 0000000000000..f7a2e484fc61b --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/const_default_first.stderr @@ -0,0 +1,8 @@ +error: generic parameters with a default must be trailing + --> $DIR/const_default_first.rs:6:19 + | +LL | struct Both { + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs b/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs index 2ce874c8bf4d3..435a63a528345 100644 --- a/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs +++ b/src/test/ui/const-generics/min_const_generics/type_and_const_defaults.rs @@ -1,7 +1,7 @@ -// check-pass -#![crate_type = "lib"] +// run-pass +#![feature(const_generics)] #![feature(const_generics_defaults)] -#![allow(incomplete_features)] +#![allow(incomplete_features, dead_code)] struct Both { arr: [T; N] @@ -12,3 +12,16 @@ trait BothTrait {} enum BothEnum { Dummy([T; N]) } + +struct OppOrder { + arr: [T; N] +} + +fn main() { + let _ = OppOrder::<3, u32> { + arr: [0,0,0], + }; + let _ = Both:: { + arr: [0], + }; +}