-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-const-genericsArea: const generics (parameters and arguments)Area: const generics (parameters and arguments)C-bugCategory: This is a bug.Category: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.F-adt_const_params`#![feature(adt_const_params)]``#![feature(adt_const_params)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.This issue requires a nightly compiler in some way.
Description
Const generics causes monomorphization to compare constants by identity instead of structurally. This means that two different references to equal data will compare as unequal.
The root problem is in
if !visited.lock_mut().insert(starting_point.clone()) { |
Instance
of a function into a FxHashSet
. Since the Instance
's subst
s contain constants, hashing these constants will cause structurally equal constants to have different hashes.For
HashStable
this has been solved by hashing the actual data and not things like pointers. For comparison we have TypeRelation
which does a more appropriate version of comparison.
I tried this code:
#![feature(const_generics)]
pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
BYTES
}
pub fn main() {
assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]);
assert_eq!(function_with_bytes::<{&[0x41, 0x41, 0x41, 0x41]}>(), b"AAAA");
}
I expected to see this happen: successful compilation just as if the type were &'static [u8]
Instead, this happened:
error: symbol `_ZN10playground19function_with_bytes17h85b0fd4613beba85E` is already defined
--> src/main.rs:3:1
|
3 | / pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
4 | | BYTES
5 | | }
| |_^
cc @varkor
cc @rust-lang/wg-const-eval It's a footgun that ConstKind
and especially ConstValue
can be compared for equality. Technically a ConstKind::Unevaluated
is value/structurally equal to any other ConstKind
. We may need that Eq
impl for query return value hashing though, not sure.
Metadata
Metadata
Assignees
Labels
A-const-genericsArea: const generics (parameters and arguments)Area: const generics (parameters and arguments)C-bugCategory: This is a bug.Category: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.F-adt_const_params`#![feature(adt_const_params)]``#![feature(adt_const_params)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.This issue requires a nightly compiler in some way.