mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
progress, stuff compiles now
This commit is contained in:
parent
8ef81388e2
commit
b0feb5be2f
@ -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(
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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> },
|
||||
|
@ -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(
|
||||
|
@ -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()
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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() {}
|
||||
|
@ -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() {}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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() {}
|
||||
|
Loading…
Reference in New Issue
Block a user