1
Fork 0

Update with comments

This commit is contained in:
kadmin 2021-03-20 22:34:58 +00:00
parent ea2af70466
commit 7116bb5c33
9 changed files with 74 additions and 35 deletions

View file

@ -2659,7 +2659,6 @@ impl<'a> State<'a> {
s.word_space(":"); s.word_space(":");
s.print_type(ty); s.print_type(ty);
s.print_type_bounds(":", &param.bounds); s.print_type_bounds(":", &param.bounds);
// FIXME(const_generic_defaults)
if let Some(ref default) = default { if let Some(ref default) = default {
s.s.space(); s.s.space();
s.word_space("="); s.word_space("=");

View file

@ -957,35 +957,46 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
) -> SubstsRef<'tcx> { ) -> SubstsRef<'tcx> {
let generics = self.tcx.generics_of(def_id); let generics = self.tcx.generics_of(def_id);
let mut num_supplied_defaults = 0; let mut num_supplied_defaults = 0;
let mut type_params = generics
.params #[derive(PartialEq, Eq, Copy, Clone)]
.iter() enum Kind {
.rev() Const,
.filter_map(|param| match param.kind { Type,
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => {
Some((param.def_id, has_default))
} }
// FIXME(const_generics:defaults) let default_params = generics.params.iter().rev().filter_map(|param| match param.kind {
ty::GenericParamDefKind::Const { has_default: _has_default } => None, ty::GenericParamDefKind::Type { has_default: true, .. } => {
}) Some((param.def_id, Kind::Type))
.peekable(); }
let has_default = { ty::GenericParamDefKind::Const { has_default: true } => {
let has_default = type_params.peek().map(|(_, has_default)| has_default); Some((param.def_id, Kind::Const))
*has_default.unwrap_or(&false) }
}; _ => None,
if has_default { });
let types = substs.types().rev(); let mut types = substs.types().rev();
for ((def_id, has_default), actual) in type_params.zip(types) { let mut consts = substs.consts().rev();
if !has_default { 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; break;
} }
} else {
break;
}
}
Kind::Type => {
if let Some(actual) = types.next() {
if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual { if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual {
break; break;
} }
num_supplied_defaults += 1; } else {
break;
} }
} }
}
num_supplied_defaults += 1;
}
let len = generics.params.len(); let len = generics.params.len();
let mut generics = generics.clone(); let mut generics = generics.clone();
generics.params.truncate(len - num_supplied_defaults); generics.params.truncate(len - num_supplied_defaults);

View file

@ -1880,7 +1880,6 @@ impl EncodeContext<'a, 'tcx> {
let def_id = def_id.to_def_id(); let def_id = def_id.to_def_id();
self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true); self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
if default.is_some() { if default.is_some() {
self.encode_stability(def_id);
record!(self.tables.const_defaults[def_id] <- self.tcx.const_param_default(def_id)) record!(self.tables.const_defaults[def_id] <- self.tcx.const_param_default(def_id))
} }
} }

View file

@ -94,7 +94,7 @@ rustc_queries! {
} }
/// Given the def_id of a const-generic parameter, computes the associated default const /// 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. /// parameter. e.g. `fn example<const N: usize=3>` called on `N` would return `3`.
query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> { query const_param_default(param: DefId) -> &'tcx ty::Const<'tcx> {
desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) } desc { |tcx| "compute const default for a given parameter `{}`", tcx.def_path_str(param) }
} }

View file

@ -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), }) => tcx.hir().local_def_id(ac.hir_id),
_ => span_bug!( _ => span_bug!(
tcx.def_span(def_id), 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) Const::from_anon_const(tcx, default_def_id)

View file

@ -775,7 +775,7 @@ fn check_where_clauses<'tcx, 'fcx>(
GenericParamDefKind::Const { .. } => { GenericParamDefKind::Const { .. } => {
if is_our_default(param) { if is_our_default(param) {
let default_ct = tcx.const_param_default(param.def_id); 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()); assert!(!default_ct.needs_subst());
default_ct.into() default_ct.into()
} else { } else {

View file

@ -0,0 +1,9 @@
#![crate_type = "lib"]
#![feature(const_generics)]
#![feature(const_generics_defaults)]
#![allow(incomplete_features, dead_code)]
struct Both<const N: usize=3, T> {
//~^ ERROR: generic parameters with a default must be
v: T
}

View file

@ -0,0 +1,8 @@
error: generic parameters with a default must be trailing
--> $DIR/const_default_first.rs:6:19
|
LL | struct Both<const N: usize=3, T> {
| ^
error: aborting due to previous error

View file

@ -1,7 +1,7 @@
// check-pass // run-pass
#![crate_type = "lib"] #![feature(const_generics)]
#![feature(const_generics_defaults)] #![feature(const_generics_defaults)]
#![allow(incomplete_features)] #![allow(incomplete_features, dead_code)]
struct Both<T=u32, const N: usize=3> { struct Both<T=u32, const N: usize=3> {
arr: [T; N] arr: [T; N]
@ -12,3 +12,16 @@ trait BothTrait<T=u32, const N: usize=3> {}
enum BothEnum<T=u32, const N: usize=3> { enum BothEnum<T=u32, const N: usize=3> {
Dummy([T; N]) Dummy([T; N])
} }
struct OppOrder<const N: usize=3, T=u32> {
arr: [T; N]
}
fn main() {
let _ = OppOrder::<3, u32> {
arr: [0,0,0],
};
let _ = Both::<u8, 1> {
arr: [0],
};
}