diff options
| author | kadmin <julianknodt@gmail.com> | 2020-08-11 00:02:45 +0000 |
|---|---|---|
| committer | kadmin <julianknodt@gmail.com> | 2021-03-23 17:16:20 +0000 |
| commit | e4e5db4e4207e21c38c07640d44005dab022f1b8 (patch) | |
| tree | 32856def2da071e067f79505960bf18debd407e4 | |
| parent | 79e5814f4520f2c51b5307421db45cd82d134e76 (diff) | |
| download | rust-e4e5db4e4207e21c38c07640d44005dab022f1b8.tar.gz rust-e4e5db4e4207e21c38c07640d44005dab022f1b8.zip | |
Add has_default to GenericParamDefKind::Const
This currently creates a field which is always false on GenericParamDefKind for future use when consts are permitted to have defaults Update const_generics:default locations Previously just ignored them, now actually do something about them. Fix using type check instead of value Add parsing This adds all the necessary changes to lower const-generics defaults from parsing. Change P<Expr> to AnonConst This matches the arguments passed to instantiations of const generics, and makes it specific to just anonymous constants. Attempt to fix lowering bugs
39 files changed, 158 insertions, 77 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7e82d7ff77d..4b9bf273c70 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -385,6 +385,7 @@ pub enum GenericParamKind { ty: P<Ty>, /// Span of the `const` keyword. kw_span: Span, + /// Optional default value for the const generic param default: Option<AnonConst>, }, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index f426f2c7fec..c5378fb47bc 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -785,8 +785,8 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>( visit_opt(default, |default| vis.visit_ty(default)); } GenericParamKind::Const { ty, kw_span: _, default } => { - vis.visit_ty(ty); visit_opt(default, |default| vis.visit_anon_const(default)); + vis.visit_ty(ty); } } smallvec![param] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 8a051066c7d..5385c4d72e4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2290,7 +2290,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.lower_ty(&ty, ImplTraitContext::disallowed()) }); let default = default.as_ref().map(|def| self.lower_anon_const(def)); - (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty, default }) } }; diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 563bcda5190..235528d6b02 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1174,6 +1174,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } + if !self.session.features_untracked().const_generics_defaults { + if let GenericParamKind::Const { default: Some(ref default), .. } = param.kind { + let mut err = self.err_handler().struct_span_err( + default.value.span, + "default values for const generic parameters are unstable", + ); + err.note("to enable them use #![feature(const_generic_defaults)]"); + err.emit(); + break; + } + } } validate_generic_param_order( diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index cb6f567c551..3a7ec3a8df1 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -2661,6 +2661,9 @@ impl<'a> State<'a> { s.print_type_bounds(":", ¶m.bounds); if let Some(ref _default) = default { // FIXME(const_generics_defaults): print the `default` value here + s.s.space(); + s.word_space("="); + // s.print_anon_const(&default); } } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 76e5d30dc5e..7eeda6013ed 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2266,8 +2266,10 @@ impl<'a> State<'a> { GenericParamKind::Const { ref ty, ref default } => { self.word_space(":"); self.print_type(ty); - if let Some(ref _default) = default { - // FIXME(const_generics_defaults): print the `default` value here + if let Some(ref default) = default { + self.s.space(); + self.word_space("="); + self.print_anon_const(&default) } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index eeff48a6395..d614f186106 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::Type { has_default, .. } => { + + ty::GenericParamDefKind::Type { has_default, .. } + | ty::GenericParamDefKind::Const { has_default } => { Some((param.def_id, has_default)) } - ty::GenericParamDefKind::Const => None, // FIXME(const_generics_defaults) }) .peekable(); let has_default = { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 41a8bc10c8d..56c38baa2df 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2221,7 +2221,7 @@ impl<'tcx> TyCtxt<'tcx> { let adt_def = self.adt_def(wrapper_def_id); let substs = InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const => bug!(), + GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(), GenericParamDefKind::Type { has_default, .. } => { if param.index == 0 { ty_param.into() @@ -2416,7 +2416,7 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into() } GenericParamDefKind::Type { .. } => self.mk_ty_param(param.index, param.name).into(), - GenericParamDefKind::Const => { + GenericParamDefKind::Const { .. } => { self.mk_const_param(param.index, param.name, self.type_of(param.def_id)).into() } } diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 79cd26f5668..ef46a419964 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -18,7 +18,9 @@ pub enum GenericParamDefKind { object_lifetime_default: ObjectLifetimeDefault, synthetic: Option<hir::SyntheticTyParamKind>, }, - Const, + Const { + has_default: bool, + }, } impl GenericParamDefKind { @@ -26,14 +28,14 @@ impl GenericParamDefKind { match self { GenericParamDefKind::Lifetime => "lifetime", GenericParamDefKind::Type { .. } => "type", - GenericParamDefKind::Const => "constant", + GenericParamDefKind::Const { .. } => "constant", } } pub fn to_ord(&self, tcx: TyCtxt<'_>) -> ast::ParamKindOrd { match self { GenericParamDefKind::Lifetime => ast::ParamKindOrd::Lifetime, GenericParamDefKind::Type { .. } => ast::ParamKindOrd::Type, - GenericParamDefKind::Const => { + GenericParamDefKind::Const { .. } => { ast::ParamKindOrd::Const { unordered: tcx.features().const_generics } } } @@ -105,7 +107,7 @@ impl<'tcx> Generics { match param.kind { GenericParamDefKind::Lifetime => own_counts.lifetimes += 1, GenericParamDefKind::Type { .. } => own_counts.types += 1, - GenericParamDefKind::Const => own_counts.consts += 1, + GenericParamDefKind::Const { .. } => own_counts.consts += 1, } } @@ -118,12 +120,10 @@ impl<'tcx> Generics { for param in &self.params { match param.kind { GenericParamDefKind::Lifetime => (), - GenericParamDefKind::Type { has_default, .. } => { + GenericParamDefKind::Type { has_default, .. } | + GenericParamDefKind::Const { has_default } => { own_defaults.types += has_default as usize; } - GenericParamDefKind::Const => { - // FIXME(const_generics:defaults) - } } } @@ -146,7 +146,7 @@ impl<'tcx> Generics { pub fn own_requires_monomorphization(&self) -> bool { for param in &self.params { match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true, + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => return true, GenericParamDefKind::Lifetime => {} } } @@ -189,7 +189,7 @@ impl<'tcx> Generics { pub fn const_param(&'tcx self, param: &ParamConst, tcx: TyCtxt<'tcx>) -> &GenericParamDef { let param = self.param_at(param.index as usize, tcx); match param.kind { - GenericParamDefKind::Const => param, + GenericParamDefKind::Const { .. } => param, _ => bug!("expected const parameter, but found another generic parameter"), } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 23cedfd499e..f61b6946985 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -593,7 +593,7 @@ fn polymorphize<'tcx>( }, // Simple case: If parameter is a const or type parameter.. - ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if + ty::GenericParamDefKind::Const { .. } | ty::GenericParamDefKind::Type { .. } if // ..and is within range and unused.. unused.contains(param.index).unwrap_or(false) => // ..then use the identity for this parameter. diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 77f16688937..ad323df8a69 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -193,17 +193,22 @@ pub trait Printer<'tcx>: Sized { .params .iter() .rev() - .take_while(|param| { - match param.kind { - ty::GenericParamDefKind::Lifetime => false, - ty::GenericParamDefKind::Type { has_default, .. } => { - has_default - && substs[param.index as usize] - == GenericArg::from( - self.tcx().type_of(param.def_id).subst(self.tcx(), substs), - ) - } - ty::GenericParamDefKind::Const => false, // FIXME(const_generics_defaults) + .take_while(|param| match param.kind { + ty::GenericParamDefKind::Lifetime => false, + ty::GenericParamDefKind::Type { has_default, .. } => { + has_default + && substs[param.index as usize] + == GenericArg::from( + self.tcx().type_of(param.def_id).subst(self.tcx(), substs), + ) + } + ty::GenericParamDefKind::Const { has_default } => { + has_default + && substs[param.index as usize] + == GenericArg::from(crate::ty::Const::from_anon_const( + self.tcx(), + param.def_id.expect_local(), + )) } }) .count(); diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index e48640e1bb9..c5c701082e6 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -1175,7 +1175,8 @@ fn create_mono_items_for_default_impls<'tcx>( let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + GenericParamDefKind::Type { .. } + | GenericParamDefKind::Const { .. } => { trait_ref.substs[param.index as usize] } }); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index de264b5bb04..9ba9524ee1a 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -928,8 +928,13 @@ impl ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { self.visit(self.ev.tcx.type_of(param.def_id)); } } - GenericParamDefKind::Const => { + GenericParamDefKind::Const { has_default, .. } => { self.visit(self.ev.tcx.type_of(param.def_id)); + if has_default { + // 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); + } } } } @@ -1741,7 +1746,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'tcx> { self.visit(self.tcx.type_of(param.def_id)); } } - GenericParamDefKind::Const => { + GenericParamDefKind::Const { .. } => { self.visit(self.tcx.type_of(param.def_id)); } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index af241ef8afc..85faa961b14 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -616,6 +616,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { self.visit_ty(ty); self.ribs[TypeNS].pop().unwrap(); self.ribs[ValueNS].pop().unwrap(); + // FIXME(const_generics:default) do something with default here? } } } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 2c61c0963ae..744945c5b0f 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2004,7 +2004,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { GenericParamDefKind::Type { object_lifetime_default, .. } => { Some(object_lifetime_default) } - GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None, + GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => { + None + } }) .collect() }) diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs index 53150a92664..c3bc1c191ff 100644 --- a/compiler/rustc_save_analysis/src/sig.rs +++ b/compiler/rustc_save_analysis/src/sig.rs @@ -614,11 +614,12 @@ impl<'hir> Sig for hir::Generics<'hir> { start: offset + text.len(), end: offset + text.len() + param_text.as_str().len(), }); - if let hir::GenericParamKind::Const { ref ty, ref default } = param.kind { + if let hir::GenericParamKind::Const { ref ty, default } = param.kind { param_text.push_str(": "); param_text.push_str(&ty_to_string(&ty)); - if let Some(ref _default) = default { - // FIXME(const_generics_defaults): push the `default` value here + if let Some(default) = default { + param_text.push_str(" = "); + param_text.push_str(&id_to_string(&scx.tcx.hir(), default.hir_id)); } } if !param.bounds.is_empty() { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 42e01f1b8d1..116519855d7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -384,6 +384,7 @@ symbols! { const_fn_fn_ptr_basics, const_fn_transmute, const_fn_union, + const_generic_defaults, const_generics, const_generics_defaults, const_if_match, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index e6a1cf58fe3..cecdcc97896 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -176,7 +176,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { for param in generics.params.iter() { let value = match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { trait_ref.substs[param.index as usize].to_string() } GenericParamDefKind::Lifetime => continue, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 5a8c53a0c4b..f26eb159105 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -483,7 +483,7 @@ fn vtable_methods<'tcx>( let substs = trait_ref.map_bound(|trait_ref| { InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { trait_ref.substs[param.index as usize] } }) diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 75822eadb2a..209fd83b3ab 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -337,7 +337,7 @@ impl<'tcx> OnUnimplementedFormatString { .iter() .filter_map(|param| { let value = match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { trait_ref.substs[param.index as usize].to_string() } GenericParamDefKind::Lifetime => return None, diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 916186f4204..5c0cb2fb835 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -739,7 +739,7 @@ fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { tcx.mk_region(ty::RegionKind::ReLateBound(ty::INNERMOST, br)).into() } - ty::GenericParamDefKind::Const => tcx + ty::GenericParamDefKind::Const { .. } => tcx .mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), ty: tcx.type_of(param.def_id), diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 0ea0ccaceab..604611406af 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -64,7 +64,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { kind: hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)), .. }), - GenericParamDefKind::Const, + GenericParamDefKind::Const { .. }, ) => match path.res { Res::Err => { add_braces_suggestion(arg, &mut err); @@ -93,7 +93,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }, ( GenericArg::Type(hir::Ty { kind: hir::TyKind::Path(_), .. }), - GenericParamDefKind::Const, + GenericParamDefKind::Const { .. }, ) => add_braces_suggestion(arg, &mut err), ( GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }), @@ -236,7 +236,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { match (arg, ¶m.kind, arg_count.explicit_late_bound) { (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _) | (GenericArg::Type(_), GenericParamDefKind::Type { .. }, _) - | (GenericArg::Const(_), GenericParamDefKind::Const, _) => { + | (GenericArg::Const(_), GenericParamDefKind::Const { .. }, _) => { substs.push(ctx.provided_kind(param, arg)); args.next(); params.next(); @@ -282,7 +282,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericParamDefKind::Type { .. } => { ParamKindOrd::Type } - GenericParamDefKind::Const => { + GenericParamDefKind::Const { .. } => { ParamKindOrd::Const { unordered: tcx .features() diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 7c5398003f3..34e5ab90733 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -443,7 +443,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.astconv.ast_ty_to_ty(&ty).into() } } - (GenericParamDefKind::Const, GenericArg::Const(ct)) => { + (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { ty::Const::from_opt_const_arg_anon_const( tcx, ty::WithOptConstParam { @@ -504,16 +504,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.ty_error().into() } } - GenericParamDefKind::Const => { + GenericParamDefKind::Const { has_default } => { let ty = tcx.at(self.span).type_of(param.def_id); - // FIXME(const_generics_defaults) - if infer_args { + if !infer_args && has_default { + let c = ty::Const::from_anon_const(tcx, param.def_id.expect_local()); + ty::subst::GenericArg::from(c) + } else if infer_args { + self.astconv.ct_infer(ty, Some(param), self.span).into() + } else { + // We've already errored above about the mismatch. + tcx.const_error(ty).into() + } + /* + if !infer_args && has_default { + /* + if default_needs_object_self(param) { + missing_type_params.push(param.name.to_string()); + tcx.const_error(ty).into() + } else { + } + */ + } else if infer_args { // No const parameters were provided, we can infer all. self.astconv.ct_infer(ty, Some(param), self.span).into() } else { // We've already errored above about the mismatch. tcx.const_error(ty).into() } + */ } } } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index a30a8107933..ddb11b9f3b1 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -792,11 +792,11 @@ fn compare_synthetic_generics<'tcx>( let trait_m_generics = tcx.generics_of(trait_m.def_id); let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind { GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)), - GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None, + GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None, }); let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| match param.kind { GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)), - GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None, + GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => None, }); for ((impl_def_id, impl_synthetic), (trait_def_id, trait_synthetic)) in impl_m_type_params.zip(trait_m_type_params) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index dc8a804bfea..a5733c9637d 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1405,7 +1405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { self.fcx.to_ty(ty).into() } - (GenericParamDefKind::Const, GenericArg::Const(ct)) => { + (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { self.fcx.const_arg_to_const(&ct.value, param.def_id).into() } _ => unreachable!(), @@ -1443,10 +1443,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.fcx.var_for_def(self.span, param) } } - GenericParamDefKind::Const => { - // FIXME(const_generics_defaults) + GenericParamDefKind::Const { has_default, .. } => { + if infer_args || !has_default { + return self.fcx.var_for_def(self.span, param); + } + // FIXME(const_generics:defaults) // No const parameters were provided, we have to infer them. - self.fcx.var_for_def(self.span, param) + todo!() } } } diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 4a2dd6faf0c..731a72ff024 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -358,7 +358,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => { self.cfcx.to_ty(ty).into() } - (GenericParamDefKind::Const, GenericArg::Const(ct)) => { + (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { self.cfcx.const_arg_to_const(&ct.value, param.def_id).into() } _ => unreachable!(), diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 9a3d1e42b73..d6fa6bf0067 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -308,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Construct a trait-reference `self_ty : Trait<input_tys>` let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| { match param.kind { - GenericParamDefKind::Lifetime | GenericParamDefKind::Const => {} + GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {} GenericParamDefKind::Type { .. } => { if param.index == 0 { return self_ty.into(); diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 3006cabc632..0742549f890 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1700,7 +1700,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // In general, during probe we erase regions. self.tcx.lifetimes.re_erased.into() } - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { self.var_for_def(self.span, param) } } diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 00c6550835b..d257ea22dc1 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -758,7 +758,7 @@ fn check_where_clauses<'tcx, 'fcx>( fcx.tcx.mk_param_from_def(param) } - GenericParamDefKind::Type { .. } => { + GenericParamDefKind::Const { .. } | GenericParamDefKind::Type { .. } => { // If the param has a default, ... if is_our_default(param) { let default_ty = fcx.tcx.type_of(param.def_id); @@ -771,11 +771,6 @@ fn check_where_clauses<'tcx, 'fcx>( fcx.tcx.mk_param_from_def(param) } - - GenericParamDefKind::Const => { - // FIXME(const_generics_defaults) - fcx.tcx.mk_param_from_def(param) - } } }); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 162fccc6020..424e5ab900d 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1549,13 +1549,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { i += 1; Some(param_def) } - GenericParamKind::Const { .. } => { + GenericParamKind::Const { default, .. } => { let param_def = ty::GenericParamDef { index: type_start + i as u32, name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), pure_wrt_drop: param.pure_wrt_drop, - kind: ty::GenericParamDefKind::Const, + kind: ty::GenericParamDefKind::Const { has_default: default.is_some() }, }; i += 1; Some(param_def) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 3f2f244e44f..b7f7b8355ff 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -83,7 +83,8 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< return generics .params .iter() - .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const)) + .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const { .. + })) .nth(arg_index) .map(|param| param.def_id); } @@ -121,7 +122,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< tcx.generics_of(type_dependent_def) .params .iter() - .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const)) + .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const { .. })) .nth(idx) .map(|param| param.def_id) } @@ -211,7 +212,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< generics .params .iter() - .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const)) + .filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const { .. })) .nth(arg_index) .map(|param| param.def_id) } diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index 7713381e62e..12409468605 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -173,7 +173,7 @@ fn enforce_impl_params_are_constrained( ); } } - ty::GenericParamDefKind::Const => { + ty::GenericParamDefKind::Const { .. } => { let param_ct = ty::ParamConst::for_def(param); if !input_parameters.contains(&cgp::Parameter::from(param_ct)) { report_unused_parameter( diff --git a/compiler/rustc_typeck/src/variance/solve.rs b/compiler/rustc_typeck/src/variance/solve.rs index 2d3369cba7a..1a4d88ced0e 100644 --- a/compiler/rustc_typeck/src/variance/solve.rs +++ b/compiler/rustc_typeck/src/variance/solve.rs @@ -78,7 +78,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { // Make all const parameters invariant. for param in generics.params.iter() { - if let ty::GenericParamDefKind::Const = param.kind { + if let ty::GenericParamDefKind::Const { .. } = param.kind { variances[param.index as usize] = ty::Invariant; } } diff --git a/src/test/ui/const-generics/defaults/const-default.rs b/src/test/ui/const-generics/defaults/const-default.rs new file mode 100644 index 00000000000..b2286e7d5bd --- /dev/null +++ b/src/test/ui/const-generics/defaults/const-default.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(const_generics)] +#![feature(const_generic_defaults)] +#![allow(incomplete_features)] + + +#[derive(Default)] +pub struct ConstDefault<const N: usize = 3> { + items: [u32; N] +} + +pub fn main() { + let s = ConstDefault::default(); +} diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.rs b/src/test/ui/const-generics/min_const_generics/default_function_param.rs index 5b0a42a4556..e4044eaaa7c 100644 --- a/src/test/ui/const-generics/min_const_generics/default_function_param.rs +++ b/src/test/ui/const-generics/min_const_generics/default_function_param.rs @@ -1,3 +1,6 @@ +#![feature(const_generic_defaults)] +#![feature(min_const_generics)] + fn foo<const SIZE: usize = 5>() {} //~^ ERROR default values for const generic parameters are experimental diff --git a/src/test/ui/const-generics/min_const_generics/default_trait_param.rs b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs index 14bac473ed9..c3581aca1cf 100644 --- a/src/test/ui/const-generics/min_const_generics/default_trait_param.rs +++ b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs @@ -1,4 +1,2 @@ trait Foo<const KIND: bool = true> {} //~^ ERROR default values for const generic parameters are experimental - -fn main() {} diff --git a/src/test/ui/feature-gate/feature-gate-const_generic_defaults.rs b/src/test/ui/feature-gate/feature-gate-const_generic_defaults.rs new file mode 100644 index 00000000000..6ba314666e2 --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-const_generic_defaults.rs @@ -0,0 +1,5 @@ +#![feature(min_const_generics)] +#![crate_type="lib"] + +struct A<const N: usize = 3>; +//~^ ERROR default values for diff --git a/src/test/ui/feature-gate/feature-gate-const_generic_defaults.stderr b/src/test/ui/feature-gate/feature-gate-const_generic_defaults.stderr new file mode 100644 index 00000000000..0b7140c0c0f --- /dev/null +++ b/src/test/ui/feature-gate/feature-gate-const_generic_defaults.stderr @@ -0,0 +1,10 @@ +error: default values for const generic parameters are unstable + --> $DIR/feature-gate-const_generic_defaults.rs:4:27 + | +LL | struct A<const N: usize = 3>; + | ^ + | + = note: to enable them use #![feature(const_generic_defaults)] + +error: aborting due to previous error + diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index ea9a910d1b9..e202b5061a6 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -408,6 +408,10 @@ pub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool { eq_path(&l.prefix, &r.prefix) && eq_use_tree_kind(&l.kind, &r.kind) } +pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool { + eq_expr(&l.value, &r.value) +} + pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool { use UseTreeKind::*; match (l, r) { @@ -418,10 +422,6 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool { } } -pub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool { - eq_expr(&l.value, &r.value) -} - pub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool { matches!( (l, r), |
