mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
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
This commit is contained in:
parent
79e5814f45
commit
e4e5db4e42
@ -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>,
|
||||
},
|
||||
|
@ -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]
|
||||
|
@ -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 })
|
||||
}
|
||||
};
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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]
|
||||
}
|
||||
});
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
})
|
||||
|
@ -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() {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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]
|
||||
}
|
||||
})
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!(),
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
15
src/test/ui/const-generics/defaults/const-default.rs
Normal file
15
src/test/ui/const-generics/defaults/const-default.rs
Normal file
@ -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();
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -1,4 +1,2 @@
|
||||
trait Foo<const KIND: bool = true> {}
|
||||
//~^ ERROR default values for const generic parameters are experimental
|
||||
|
||||
fn main() {}
|
||||
|
@ -0,0 +1,5 @@
|
||||
#![feature(min_const_generics)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
struct A<const N: usize = 3>;
|
||||
//~^ ERROR default values for
|
@ -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
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user