progress, stuff compiles now

This commit is contained in:
lcnr 2021-03-01 12:50:09 +01:00 committed by kadmin
parent 8ef81388e2
commit b0feb5be2f
25 changed files with 108 additions and 76 deletions

View File

@ -1150,20 +1150,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
fn visit_generics(&mut self, generics: &'a Generics) {
let mut prev_ty_default = None;
let cg_defaults = self.session.features_untracked().const_generics_defaults;
let mut prev_param_default = None;
for param in &generics.params {
match param.kind {
GenericParamKind::Lifetime => (),
GenericParamKind::Type { default: Some(_), .. } => {
prev_ty_default = Some(param.ident.span);
GenericParamKind::Type { default: Some(_), .. }
| GenericParamKind::Const { default: Some(_), .. } => {
prev_param_default = Some(param.ident.span);
}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
if let Some(span) = prev_ty_default {
if let Some(span) = prev_param_default {
let mut err = self.err_handler().struct_span_err(
span,
"type parameters with a default must be trailing",
"generic parameters with a default must be trailing",
);
if matches!(param.kind, GenericParamKind::Const { .. }) {
if matches!(param.kind, GenericParamKind::Const { .. }) && !cg_defaults {
err.note(
"using type defaults and const parameters \
in the same parameter list is currently not permitted",
@ -1174,17 +1177,6 @@ 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.help("add `#![feature(const_generic_defaults)]` to the crate attributes to enable");
err.emit();
break;
}
}
}
validate_generic_param_order(

View File

@ -7,7 +7,7 @@ struct Foo<T = U, U = ()> {
field1: T,
field2: U,
}
// error: type parameters with a default cannot use forward declared
// error: generic parameters with a default cannot use forward declared
// identifiers
```

View File

@ -366,6 +366,9 @@ pub trait Visitor<'v>: Sized {
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) {
walk_generic_param(self, p)
}
fn visit_const_param_default(&mut self, _param: HirId, ct: &'v AnonConst) {
walk_const_param_default(self, ct)
}
fn visit_generics(&mut self, g: &'v Generics<'v>) {
walk_generics(self, g)
}
@ -869,13 +872,17 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
GenericParamKind::Const { ref ty, ref default } => {
visitor.visit_ty(ty);
if let Some(ref default) = default {
visitor.visit_anon_const(default);
visitor.visit_const_param_default(param.hir_id, default);
}
}
}
walk_list!(visitor, visit_param_bound, param.bounds);
}
pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v AnonConst) {
visitor.visit_anon_const(ct)
}
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) {
walk_list!(visitor, visit_generic_param, generics.params);
walk_list!(visitor, visit_where_predicate, generics.where_clause.predicates);

View File

@ -395,6 +395,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}
}
fn visit_const_param_default(&mut self, param: HirId, ct: &'hir AnonConst) {
self.with_parent(param, |this| intravisit::walk_const_param_default(this, ct))
}
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
self.with_dep_node_owner(ti.def_id, ti, |this, hash| {
this.insert_with_hash(ti.span, ti.hir_id(), Node::TraitItem(ti), hash);

View File

@ -44,7 +44,11 @@ impl<'tcx> Const<'tcx> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
let body_id = match tcx.hir().get(hir_id) {
hir::Node::AnonConst(ac) => ac.body,
hir::Node::AnonConst(ac)
| hir::Node::GenericParam(hir::GenericParam {
kind: hir::GenericParamKind::Const { ty: _, default: Some(ac) },
..
}) => ac.body,
_ => span_bug!(
tcx.def_span(def.did.to_def_id()),
"from_anon_const can only process anonymous constants"

View File

@ -228,7 +228,7 @@ enum ResolutionError<'a> {
),
/// Error E0530: `X` bindings cannot shadow `Y`s.
BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredTyParam, // FIXME(const_generics_defaults)
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
ParamInTyOfConstParam(Symbol),
@ -238,7 +238,7 @@ enum ResolutionError<'a> {
///
/// This error is only emitted when using `min_const_generics`.
ParamInNonTrivialAnonConst { name: Symbol, is_type: bool },
/// Error E0735: type parameters with a default cannot use `Self`
/// Error E0735: generic parameters with a default cannot use `Self`
SelfInTyParamDefault,
/// Error E0767: use of unreachable label
UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },

View File

@ -499,7 +499,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let expected_min = if infer_args {
0
} else {
param_counts.consts + named_type_param_count - default_counts.types
param_counts.consts + named_type_param_count
- default_counts.types
- default_counts.consts
};
check_generics(

View File

@ -505,34 +505,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
GenericParamDefKind::Const { has_default } => {
let ty = tcx.at(self.span).type_of(param.def_id);
if !infer_args && has_default {
let c = substs.unwrap()[param.index as usize].expect_const();
ty::subst::GenericArg::from(c)
} else if infer_args {
self.astconv.ct_infer(ty, Some(param), self.span).into()
ty::Const::from_anon_const(tcx, param.def_id.expect_local()).into()
} else {
// We've already errored above about the mismatch.
tcx.const_error(ty).into()
}
// FIXME(const_generic_defaults)
/*
if !infer_args && has_default {
/*
if default_needs_object_self(param) {
missing_type_params.push(param.name.to_string());
tcx.const_error(ty).into()
let ty = tcx.at(self.span).type_of(param.def_id);
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()
}
*/
} 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()
}
*/
}
}
}

View File

@ -1444,12 +1444,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
GenericParamDefKind::Const { has_default, .. } => {
if infer_args || !has_default {
return self.fcx.var_for_def(self.span, param);
if !infer_args && has_default {
ty::Const::from_anon_const(tcx, param.def_id.expect_local()).into()
} else {
self.fcx.var_for_def(self.span, param)
}
// FIXME(const_generic_defaults)
// No const parameters were provided, we have to infer them.
todo!()
}
}
}

View File

@ -759,7 +759,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);
@ -772,6 +772,16 @@ fn check_where_clauses<'tcx, 'fcx>(
fcx.tcx.mk_param_from_def(param)
}
GenericParamDefKind::Const { .. } => {
if is_our_default(param) {
let default_ct = ty::Const::from_anon_const(tcx, param.def_id.expect_local());
// Const params have to currently be concrete.
assert!(!default_ct.needs_subst());
default_ct.into()
} else {
fcx.tcx.mk_param_from_def(param)
}
}
}
});

View File

@ -1527,7 +1527,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|lint| {
lint.build(
"defaults for type parameters are only allowed in \
`struct`, `enum`, `type`, or `trait` definitions.",
`struct`, `enum`, `type`, or `trait` definitions",
)
.emit();
},
@ -1554,6 +1554,14 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
Some(param_def)
}
GenericParamKind::Const { default, .. } => {
if !allow_defaults && default.is_some() {
tcx.sess.span_err(
param.span,
"defaults for const parameters are only allowed in \
`struct`, `enum`, `type`, or `trait` definitions",
);
}
let param_def = ty::GenericParamDef {
index: type_start + i as u32,
name: param.name.ident().name,

View File

@ -436,6 +436,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
.discr_type()
.to_ty(tcx),
Node::GenericParam(&GenericParam {
hir_id: param_hir_id,
kind: GenericParamKind::Const { default: Some(ct), .. },
..
}) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)),
x => tcx.ty_error_with_message(
DUMMY_SP,
&format!("unexpected const parent in type_of_def_id(): {:?}", x),

View File

@ -1,12 +1,30 @@
// check-pass
// run-pass
#![feature(const_generics)]
#![feature(const_generic_defaults)]
#![feature(const_generics_defaults)]
#![allow(incomplete_features)]
pub struct ConstDefault<const N: usize = 3> {}
pub struct ConstDefault<const N: usize = 3>;
impl<const N: usize> ConstDefault<N> {
fn foo(self) -> usize {
N
}
}
impl ConstDefault {
fn new() -> Self {
ConstDefault
}
fn bar(self) {}
}
pub fn main() {
let s = ConstDefault::default();
let s = ConstDefault::new();
assert_eq!(s.foo(), 3);
let w = ConstDefault::<3>;
w.bar();
}

View File

@ -1,4 +1,4 @@
error: type parameters with a default must be trailing
error: generic parameters with a default must be trailing
--> $DIR/wrong-order.rs:4:10
|
LL | struct A<T = u32, const N: usize> {

View File

@ -1,4 +1,4 @@
error: type parameters with a default must be trailing
error: generic parameters with a default must be trailing
--> $DIR/wrong-order.rs:4:10
|
LL | struct A<T = u32, const N: usize> {

View File

@ -2,7 +2,7 @@
#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete
struct A<T = u32, const N: usize> {
//~^ ERROR type parameters with a default must be trailing
//~^ ERROR generic parameters with a default must be trailing
arg: T,
}

View File

@ -1,6 +1,6 @@
#![crate_type = "lib"]
#![feature(const_generics_defaults)]
#![feature(min_const_generics)]
#![allow(incomplete_features)]
fn foo<const SIZE: usize = 5usize>() {}
//~^ ERROR defaults for const parameters are

View File

@ -1,9 +1,8 @@
error[E0282]: type annotations needed
--> $DIR/default_function_param.rs:6:28
error: defaults for const parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/default_function_param.rs:5:14
|
LL | fn foo<const SIZE: usize = 5>() {}
| ^ cannot infer type for type `{integer}`
LL | fn foo<const SIZE: usize = 5usize>() {}
| ^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -1,4 +1,4 @@
error: type parameters with a default must be trailing
error: generic parameters with a default must be trailing
--> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:12
|
LL | struct Bar<T = [u8; N], const N: usize>(T);

View File

@ -1,4 +1,4 @@
error: type parameters with a default must be trailing
error: generic parameters with a default must be trailing
--> $DIR/params-in-ct-in-ty-param-lazy-norm.rs:11:12
|
LL | struct Bar<T = [u8; N], const N: usize>(T);

View File

@ -10,6 +10,6 @@ struct Foo<T, U = [u8; std::mem::size_of::<T>()]>(T, U);
// FIXME(const_generics_defaults): We still don't know how to deal with type defaults.
struct Bar<T = [u8; N], const N: usize>(T);
//~^ ERROR constant values inside of type parameter defaults
//~| ERROR type parameters with a default
//~| ERROR generic parameters with a default
fn main() {}

View File

@ -1,10 +1,10 @@
struct Heap;
struct Vec<A = Heap, T>(A, T);
//~^ ERROR type parameters with a default must be trailing
//~^ ERROR generic parameters with a default must be trailing
struct Foo<A, B = Vec<C>, C>(A, B, C);
//~^ ERROR type parameters with a default must be trailing
//~| ERROR type parameters with a default cannot use forward declared identifiers
//~^ ERROR generic parameters with a default must be trailing
//~| ERROR generic parameters with a default cannot use forward declared identifiers
fn main() {}

View File

@ -1,10 +1,10 @@
error: type parameters with a default must be trailing
error: generic parameters with a default must be trailing
--> $DIR/generic-non-trailing-defaults.rs:3:12
|
LL | struct Vec<A = Heap, T>(A, T);
| ^
error: type parameters with a default must be trailing
error: generic parameters with a default must be trailing
--> $DIR/generic-non-trailing-defaults.rs:6:15
|
LL | struct Foo<A, B = Vec<C>, C>(A, B, C);

View File

@ -1,6 +1,6 @@
// Ensure that we get an error and not an ICE for this problematic case.
struct Foo<T = Option<U>, U = bool>(T, U);
//~^ ERROR type parameters with a default cannot use forward declared identifiers
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
fn main() {
let x: Foo;
}

View File

@ -1,6 +1,6 @@
#![feature(default_type_parameter_fallback)]
fn avg<T=T::Item>(_: T) {}
//~^ ERROR type parameters with a default cannot use forward declared identifiers
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
fn main() {}