-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
I've tested this with current nightly, beta and stable as well as nightlies all the way back to october (haven't tried anything before that).
Expected Output: a: false / t.a: false / both check for: (2 & 1) == 1
(Correct)
Actual Output: a: false / t.a: true / both check for: (2 & 1) == 1
(Incorrect)
Note: You can plug the code below into the https://github.com/rustwasm/rust-webpack-template for running it.
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[derive(Debug)]
struct Test {
a: bool,
b: bool
}
impl Test {
fn foo(byte: u8) -> String {
// 1. This must be infront of the struct initializer - It will evaluate correctly to "false"
let a = (byte & 1) == 1;
let t = Test {
a: (byte & 1) == 1, // 2. This must come before "b" - It will incorrectly evaluate to "true"
b: (byte & 2) == 2, // 3. This must be evaluated inside the initializer
};
// 4. This must be called inside the function
format!("a: {} / t.a: {} / both check for: (2 & 1) == 1", a, t.a)
}
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen]
pub fn run() {
log(&Test::foo(2));
}
For some reason the two different (byte & 1) == 1
expression generate different results.
Note: Inlining everything by replacing byte
with 2
produces the correct output.
Also Note: In my real program there are more strange things that happen after this like (for i in vector
not actually iterating over the contents of the vector) but I was unable to reduce those to a test case :(
For comparison, here's the same code (just without the WASM stuff) that produces the expected output a: false / t.a: false / both check for: (2 & 1) == 1
when invoked via a simple cargo run
:
#[derive(Debug)]
struct Test {
a: bool,
b: bool
}
impl Test {
fn foo(byte: u8) -> String {
// 1. This must be infront of the struct initializer - It will evaluate correctly to "false"
let a = (byte & 1) == 1;
let t = Test {
a: (byte & 1) == 1, // 2. This must come before "b" - It will incorrectly evaluate to "true"
b: (byte & 2) == 2, // 3. This must be evaluated inside the initializer
};
// 4. This must be called inside the function
format!("a: {} / t.a: {} / both check for: (2 & 1) == 1", a, t.a)
}
}
pub fn main() {
println!("{}", Test::foo(2));
}