const_evaluatable_unchecked
to const eval
This commit is contained in:
parent
660ca48041
commit
116d35d401
12 changed files with 51 additions and 42 deletions
|
@ -55,6 +55,7 @@
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(intra_doc_pointers)]
|
#![feature(intra_doc_pointers)]
|
||||||
#![feature(yeet_expr)]
|
#![feature(yeet_expr)]
|
||||||
|
#![feature(result_option_inspect)]
|
||||||
#![feature(const_option)]
|
#![feature(const_option)]
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
|
|
@ -4,7 +4,9 @@ use crate::mir;
|
||||||
use crate::ty::subst::InternalSubsts;
|
use crate::ty::subst::InternalSubsts;
|
||||||
use crate::ty::visit::TypeVisitable;
|
use crate::ty::visit::TypeVisitable;
|
||||||
use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
|
use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_session::lint;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
@ -83,7 +85,29 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
|
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
|
||||||
Ok(Some(instance)) => {
|
Ok(Some(instance)) => {
|
||||||
let cid = GlobalId { instance, promoted: None };
|
let cid = GlobalId { instance, promoted: None };
|
||||||
self.const_eval_global_id_for_typeck(param_env, cid, span)
|
self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
|
||||||
|
// We are emitting the lint here instead of in `is_const_evaluatable`
|
||||||
|
// as we normalize obligations before checking them, and normalization
|
||||||
|
// uses this function to evaluate this constant.
|
||||||
|
//
|
||||||
|
// @lcnr believes that successfully evaluating even though there are
|
||||||
|
// used generic parameters is a bug of evaluation, so checking for it
|
||||||
|
// here does feel somewhat sensible.
|
||||||
|
if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
|
||||||
|
assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
|
||||||
|
let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
|
||||||
|
if mir_body.is_polymorphic {
|
||||||
|
let Some(local_def_id) = ct.def.did.as_local() else { return };
|
||||||
|
self.struct_span_lint_hir(
|
||||||
|
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||||
|
self.hir().local_def_id_to_hir_id(local_def_id),
|
||||||
|
self.def_span(ct.def.did),
|
||||||
|
"cannot use constants which depend on generic parameters in types",
|
||||||
|
|err| err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Ok(None) => Err(ErrorHandled::TooGeneric),
|
Ok(None) => Err(ErrorHandled::TooGeneric),
|
||||||
Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),
|
Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),
|
||||||
|
|
|
@ -9,14 +9,12 @@
|
||||||
//! `thir_abstract_const` which can then be checked for structural equality with other
|
//! `thir_abstract_const` which can then be checked for structural equality with other
|
||||||
//! generic constants mentioned in the `caller_bounds` of the current environment.
|
//! generic constants mentioned in the `caller_bounds` of the current environment.
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir::def::DefKind;
|
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::ty::abstract_const::{
|
use rustc_middle::ty::abstract_const::{
|
||||||
walk_abstract_const, AbstractConst, FailureKind, Node, NotConstEvaluatable,
|
walk_abstract_const, AbstractConst, FailureKind, Node, NotConstEvaluatable,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
|
||||||
use rustc_session::lint;
|
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
@ -262,25 +260,7 @@ pub fn is_const_evaluatable<'tcx>(
|
||||||
Err(NotConstEvaluatable::Error(reported))
|
Err(NotConstEvaluatable::Error(reported))
|
||||||
}
|
}
|
||||||
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
|
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
|
||||||
Ok(_) => {
|
Ok(_) => Ok(()),
|
||||||
if uv.substs.has_non_region_param() {
|
|
||||||
assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
|
|
||||||
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
|
|
||||||
|
|
||||||
if mir_body.is_polymorphic {
|
|
||||||
let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
|
|
||||||
tcx.struct_span_lint_hir(
|
|
||||||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
|
||||||
tcx.hir().local_def_id_to_hir_id(local_def_id),
|
|
||||||
span,
|
|
||||||
"cannot use constants which depend on generic parameters in types",
|
|
||||||
|err| err
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/dependence_lint.rs:13:32
|
--> $DIR/dependence_lint.rs:14:32
|
||||||
|
|
|
|
||||||
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
|
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
|
||||||
| ^ cannot perform const operation using `T`
|
| ^ cannot perform const operation using `T`
|
||||||
|
@ -8,7 +8,7 @@ LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/dependence_lint.rs:20:37
|
--> $DIR/dependence_lint.rs:21:37
|
||||||
|
|
|
|
||||||
LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
|
LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
|
||||||
| ^ cannot perform const operation using `T`
|
| ^ cannot perform const operation using `T`
|
||||||
|
@ -17,7 +17,7 @@ LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable,
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/dependence_lint.rs:9:9
|
--> $DIR/dependence_lint.rs:10:9
|
||||||
|
|
|
|
||||||
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
|
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -27,7 +27,7 @@ LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_
|
||||||
= note: `#[warn(const_evaluatable_unchecked)]` on by default
|
= note: `#[warn(const_evaluatable_unchecked)]` on by default
|
||||||
|
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/dependence_lint.rs:16:9
|
--> $DIR/dependence_lint.rs:17:9
|
||||||
|
|
|
|
||||||
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
|
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: overly complex generic constant
|
error: overly complex generic constant
|
||||||
--> $DIR/dependence_lint.rs:16:9
|
--> $DIR/dependence_lint.rs:17:9
|
||||||
|
|
|
|
||||||
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
|
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
|
||||||
|
@ -7,7 +7,7 @@ LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error w
|
||||||
= help: consider moving this anonymous constant into a `const` function
|
= help: consider moving this anonymous constant into a `const` function
|
||||||
|
|
||||||
error: overly complex generic constant
|
error: overly complex generic constant
|
||||||
--> $DIR/dependence_lint.rs:20:17
|
--> $DIR/dependence_lint.rs:21:17
|
||||||
|
|
|
|
||||||
LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
|
LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
|
||||||
|
@ -15,7 +15,7 @@ LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable,
|
||||||
= help: consider moving this anonymous constant into a `const` function
|
= help: consider moving this anonymous constant into a `const` function
|
||||||
|
|
||||||
error: unconstrained generic constant
|
error: unconstrained generic constant
|
||||||
--> $DIR/dependence_lint.rs:13:12
|
--> $DIR/dependence_lint.rs:14:12
|
||||||
|
|
|
|
||||||
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
|
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -23,7 +23,7 @@ LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
|
||||||
= help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
|
= help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
|
||||||
|
|
||||||
error: unconstrained generic constant
|
error: unconstrained generic constant
|
||||||
--> $DIR/dependence_lint.rs:9:9
|
--> $DIR/dependence_lint.rs:10:9
|
||||||
|
|
|
|
||||||
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
|
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// revisions: full gce
|
// revisions: full gce
|
||||||
|
// compile-flags: -Zdeduplicate-diagnostics=yes
|
||||||
|
|
||||||
#![cfg_attr(gce, feature(generic_const_exprs))]
|
#![cfg_attr(gce, feature(generic_const_exprs))]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
// compile-flags: -Zdeduplicate-diagnostics=yes
|
||||||
|
|
||||||
const fn foo<T>() -> usize {
|
const fn foo<T>() -> usize {
|
||||||
// We might instead branch on `std::mem::size_of::<*mut T>() < 8` here,
|
// We might instead branch on `std::mem::size_of::<*mut T>() < 8` here,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/function-call.rs:14:17
|
--> $DIR/function-call.rs:15:17
|
||||||
|
|
|
|
||||||
LL | let _ = [0; foo::<T>()];
|
LL | let _ = [0; foo::<T>()];
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// compile-flags: -Zdeduplicate-diagnostics=yes
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
|
||||||
fn test<const N: usize>() {}
|
fn test<const N: usize>() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:9:38
|
--> $DIR/complex-expression.rs:10:38
|
||||||
|
|
|
|
||||||
LL | struct Break0<const N: usize>([u8; { N + 1 }]);
|
LL | struct Break0<const N: usize>([u8; { N + 1 }]);
|
||||||
| ^ cannot perform const operation using `N`
|
| ^ cannot perform const operation using `N`
|
||||||
|
@ -8,7 +8,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]);
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:12:40
|
--> $DIR/complex-expression.rs:13:40
|
||||||
|
|
|
|
||||||
LL | struct Break1<const N: usize>([u8; { { N } }]);
|
LL | struct Break1<const N: usize>([u8; { { N } }]);
|
||||||
| ^ cannot perform const operation using `N`
|
| ^ cannot perform const operation using `N`
|
||||||
|
@ -17,7 +17,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]);
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:16:17
|
--> $DIR/complex-expression.rs:17:17
|
||||||
|
|
|
|
||||||
LL | let _: [u8; N + 1];
|
LL | let _: [u8; N + 1];
|
||||||
| ^ cannot perform const operation using `N`
|
| ^ cannot perform const operation using `N`
|
||||||
|
@ -26,7 +26,7 @@ LL | let _: [u8; N + 1];
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:21:17
|
--> $DIR/complex-expression.rs:22:17
|
||||||
|
|
|
|
||||||
LL | let _ = [0; N + 1];
|
LL | let _ = [0; N + 1];
|
||||||
| ^ cannot perform const operation using `N`
|
| ^ cannot perform const operation using `N`
|
||||||
|
@ -35,7 +35,7 @@ LL | let _ = [0; N + 1];
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:25:45
|
--> $DIR/complex-expression.rs:26:45
|
||||||
|
|
|
|
||||||
LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
|
LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
|
||||||
| ^ cannot perform const operation using `T`
|
| ^ cannot perform const operation using `T`
|
||||||
|
@ -44,7 +44,7 @@ LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:28:47
|
--> $DIR/complex-expression.rs:29:47
|
||||||
|
|
|
|
||||||
LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
|
LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
|
||||||
| ^ cannot perform const operation using `T`
|
| ^ cannot perform const operation using `T`
|
||||||
|
@ -53,7 +53,7 @@ LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
error: generic parameters may not be used in const operations
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/complex-expression.rs:32:32
|
--> $DIR/complex-expression.rs:33:32
|
||||||
|
|
|
|
||||||
LL | let _: [u8; size_of::<*mut T>() + 1];
|
LL | let _: [u8; size_of::<*mut T>() + 1];
|
||||||
| ^ cannot perform const operation using `T`
|
| ^ cannot perform const operation using `T`
|
||||||
|
@ -62,7 +62,7 @@ LL | let _: [u8; size_of::<*mut T>() + 1];
|
||||||
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
|
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/complex-expression.rs:37:17
|
--> $DIR/complex-expression.rs:38:17
|
||||||
|
|
|
|
||||||
LL | let _ = [0; size_of::<*mut T>() + 1];
|
LL | let _ = [0; size_of::<*mut T>() + 1];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
// compile-flags: -Zdeduplicate-diagnostics=yes
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
fn foo<T>() {
|
fn foo<T>() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/const-evaluatable-unchecked.rs:5:9
|
--> $DIR/const-evaluatable-unchecked.rs:6:9
|
||||||
|
|
|
|
||||||
LL | [0; std::mem::size_of::<*mut T>()];
|
LL | [0; std::mem::size_of::<*mut T>()];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -9,7 +9,7 @@ LL | [0; std::mem::size_of::<*mut T>()];
|
||||||
= note: `#[warn(const_evaluatable_unchecked)]` on by default
|
= note: `#[warn(const_evaluatable_unchecked)]` on by default
|
||||||
|
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/const-evaluatable-unchecked.rs:16:21
|
--> $DIR/const-evaluatable-unchecked.rs:17:21
|
||||||
|
|
|
|
||||||
LL | let _ = [0; Self::ASSOC];
|
LL | let _ = [0; Self::ASSOC];
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
@ -18,7 +18,7 @@ LL | let _ = [0; Self::ASSOC];
|
||||||
= note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
|
= note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
|
||||||
|
|
||||||
warning: cannot use constants which depend on generic parameters in types
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/const-evaluatable-unchecked.rs:28:21
|
--> $DIR/const-evaluatable-unchecked.rs:29:21
|
||||||
|
|
|
|
||||||
LL | let _ = [0; Self::ASSOC];
|
LL | let _ = [0; Self::ASSOC];
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue