ernie-research/MEnvData-SWE huggingface dataset:
Repository: not-fl3/nanoserde (Rust)

Issue:
Empty map serialize panics
```
let m = HashMap::new();
println!(m.serialize_json());
```

panics here due to assumption that map is always at least len > 0:

https://github.com/not-fl3/nanoserde/blob/master/src/serde_json.rs#L976


Discussion:

Patch:
diff --git a/src/serde_json.rs b/src/serde_json.rs
index e683cf0..1618ebe 100644
--- a/src/serde_json.rs
+++ b/src/serde_json.rs
@@ -973,14 +973,14 @@ where
 {
     fn ser_json(&self, d: usize, s: &mut SerJsonState) {
         s.out.push('{');
-        let last = self.len() - 1;
+        let len = self.len();
         let mut index = 0;
         for (k, v) in self {
             s.indent(d + 1);
             k.ser_json(d + 1, s);
             s.out.push(':');
             v.ser_json(d + 1, s);
-            if index != last {
+            if (index + 1) < len {
                 s.conl();
             }
             index += 1;


Test patch:
diff --git a/tests/json.rs b/tests/json.rs
index d104185..6955bcb 100644
--- a/tests/json.rs
+++ b/tests/json.rs
@@ -183,10 +183,10 @@ fn empty() {
 fn one_field() {
     #[derive(DeJson, SerJson, PartialEq)]
     pub struct OneField {
-        field: f32,
+        field: std::collections::HashMap<String, f32>,
     }
 
-    let test = OneField { field: 23. };
+    let test = OneField { field: std::collections::HashMap::new() };
     let bytes = SerJson::serialize_json(&test);
     let test_deserialized = DeJson::deserialize_json(&bytes).unwrap();
     assert!(test == test_deserialized);
Repository: Lokathor/tinyvec (Rust)

Issue:
Pretty-print Debug format option
`tinyvec::TinyVec` has a different `Debug` pretty-print format to `std::vec::Vec` (and to the slice pretty-print format).

Example code:

```rust
use tinyvec::{tiny_vec, TinyVec};

fn main() {
    let xs: Vec<i32> = vec![1, 2, 3];
    println!("Vec: {:#?}", xs);

    let xs: TinyVec<[i32; 6]> = tiny_vec![1, 2, 3];
    println!("TinyVec: {:#?}", xs);
}
```
Output:
```
Vec: [
    1,
    2,
    3,
]
TinyVec: [1, 2, 3]
```
Expected output:
```
Vec: [
    1,
    2,
    3,
]
TinyVec: [
    1,
    2,
    3,
]
```
[Playground link.](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5e6020aaf95e673d253caf9381977309)

This is also the format used by the `dbg!` macro, which is where I originally noticed the difference.


Discussion:
[It looks like tinyvec has its own Debug impl](https://github.com/Lokathor/tinyvec/blob/main/src/tinyvec.rs#L1322)
If you use `as_slice()` then the debug pretty-print looks as expected
A pr to make the tinyvec types use the alternate format flag would be acceptable.
I'm working on it now



Patch:
diff --git a/src/arrayvec.rs b/src/arrayvec.rs
index 7fa4263..1ab2f2c 100644
--- a/src/arrayvec.rs
+++ b/src/arrayvec.rs
@@ -1469,14 +1469,7 @@ where
 {
   #[allow(clippy::missing_inline_in_public_items)]
   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
-    write!(f, "[")?;
-    for (i, elem) in self.iter().enumerate() {
-      if i > 0 {
-        write!(f, ", ")?;
-      }
-      Debug::fmt(elem, f)?;
-    }
-    write!(f, "]")
+    core::fmt::Debug::fmt(self.as_slice(), f)
   }
 }
 
diff --git a/src/tinyvec.rs b/src/tinyvec.rs
index 82af1ce..b333a68 100644
--- a/src/tinyvec.rs
+++ b/src/tinyvec.rs
@@ -1325,14 +1325,7 @@ where
 {
   #[allow(clippy::missing_inline_in_public_items)]
   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
-    write!(f, "[")?;
-    for (i, elem) in self.iter().enumerate() {
-      if i > 0 {
-        write!(f, ", ")?;
-      }
-      Debug::fmt(elem, f)?;
-    }
-    write!(f, "]")
+    core::fmt::Debug::fmt(self.as_slice(), f)
   }
 }
 


Test patch:
diff --git a/tests/arrayvec.rs b/tests/arrayvec.rs
index 5181b60..cdf8c88 100644
--- a/tests/arrayvec.rs
+++ b/tests/arrayvec.rs
@@ -463,3 +463,14 @@ fn ArrayVec_try_from_slice() {
   let doesnt_fit: Result<ArrayVec<[i32; 2]>, _> = ArrayVec::try_from(&nums[..4]);
   assert!(doesnt_fit.is_err());
 }
+
+#[test]
+fn ArrayVec_pretty_debug() {
+  let arr: [i32; 3] = [1, 2, 3];
+  let expect = format!("{:#?}", arr);
+
+  let arr: ArrayVec<[i32; 3]> = array_vec![1, 2, 3];
+  let got = format!("{:#?}", arr);
+
+  assert_eq!(got, expect);
+}
diff --git a/tests/tinyvec.rs b/tests/tinyvec.rs
index 4c2bed1..1f26be4 100644
--- a/tests/tinyvec.rs
+++ b/tests/tinyvec.rs
@@ -385,3 +385,12 @@ fn TinyVec_ser_de_heap() {
     ],
   );
 }
+
+#[test]
+fn TinyVec_pretty_debug() {
+  let tv: TinyVec<[i32; 6]> = tiny_vec![1, 2, 3];
+  let s = format!("{:#?}", tv);
+  let expected = format!("{:#?}", tv.as_slice());
+
+  assert_eq!(s, expected);
+}
Repository: veryl-lang/veryl (Rust)

Issue:
Mangled enum members can be used unexpectedly
Checking the following code is success, but it causes emitter panic.
This is because `EnumA_X` is added to symbol table to detect conflict between mangled names and user defined identifiers.
This case should be reported as error.

```systemverilog
enum EnumA {
    X,
}

let a: logic = EnumA_X;
```


Discussion:

Patch:
diff --git a/crates/analyzer/src/handlers/check_type.rs b/crates/analyzer/src/handlers/check_type.rs
index 38f8790d4..136d3366b 100644
--- a/crates/analyzer/src/handlers/check_type.rs
+++ b/crates/analyzer/src/handlers/check_type.rs
@@ -174,6 +174,14 @@ impl VerylGrammarTrait for CheckType {
                     }
                 }
 
+                // Mangled enum member can't be used directly
+                if matches!(symbol.found.kind, SymbolKind::EnumMemberMangled) {
+                    self.errors.push(AnalyzerError::undefined_identifier(
+                        &symbol.found.token.to_string(),
+                        &symbol.found.token.into(),
+                    ));
+                }
+
                 // Check variable type
                 if !self.in_user_defined_type.is_empty() && self.in_generic_argument.is_empty() {
                     if self.in_modport {


Test patch:
diff --git a/crates/analyzer/src/tests.rs b/crates/analyzer/src/tests.rs
index 394c7ce0f..576600771 100644
--- a/crates/analyzer/src/tests.rs
+++ b/crates/analyzer/src/tests.rs
@@ -1948,6 +1948,23 @@ fn undefined_identifier() {
         AnalyzerError::UndefinedIdentifier { .. }
     ));
 
+    let code = r#"
+    module ModuleA {
+        enum EnumA {
+            X,
+        }
+
+        // Mangled enum member can't be used directly
+        let _a: logic = EnumA_X;
+    }
+    "#;
+
+    let errors = analyze(code);
+    assert!(matches!(
+        errors[0],
+        AnalyzerError::UndefinedIdentifier { .. }
+    ));
+
     //let code = r#"
     //package Pkg::<AW: const, DW: const> {
     //    type address_t = logic<AW>;
Repository: ParkMyCar/compact_str (Rust)

Issue:
impl PartialEq<CompactStr> for &str
Example that works:
```rust
use compact_str::CompactStr;
fn main() {
    dbg!(CompactStr::from("hello") == "hello");
}
```

Example that don't work:
```rust
use compact_str::CompactStr;
fn main() {
    dbg!("hello" == CompactStr::from("hello"));  
}
```

Error:
```
error[E0277]: can't compare `&str` with `CompactStr`
 --> src/main.rs:4:18
  |
4 |     dbg!("hello" == CompactStr::from("hello"));
  |                  ^^ no implementation for `&str == CompactStr`
  |
  = help: the trait `PartialEq<CompactStr>` is not implemented for `&str`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `test01` due to previous error
```

I think it shouldn't make any differences whether you want to compare `&str` with `CompactStr`, `&str` with `&CompactStr`, `CompactStr` with `&str` or `&CompactStr` with `&str`.


Discussion:
Thanks for submitting the issue! I figured there would be a couple missing impls like this, I'll try and get this fixed soon. If someone else would like to submit a PR though, feel free 🙂



Patch:
diff --git a/compact_str/src/lib.rs b/compact_str/src/lib.rs
index 52e7f527..ed5785f7 100644
--- a/compact_str/src/lib.rs
+++ b/compact_str/src/lib.rs
@@ -139,6 +139,12 @@ impl PartialEq<CompactStr> for String {
     }
 }
 
+impl PartialEq<CompactStr> for &str {
+    fn eq(&self, other: &CompactStr) -> bool {
+        *self == other.as_str()
+    }
+}
+
 impl Ord for CompactStr {
     fn cmp(&self, other: &Self) -> Ordering {
         self.as_str().cmp(other.as_str())


Test patch:
diff --git a/compact_str/src/tests.rs b/compact_str/src/tests.rs
index ec03277b..23031e6d 100644
--- a/compact_str/src/tests.rs
+++ b/compact_str/src/tests.rs
@@ -60,6 +60,7 @@ fn test_short_ascii() {
     for s in strs {
         let compact = CompactStr::new(s);
         assert_eq!(compact, s);
+        assert_eq!(s, compact);
         assert_eq!(compact.is_heap_allocated(), false);
     }
 }
@@ -79,6 +80,7 @@ fn test_short_unicode() {
     for (s, is_heap) in strs {
         let compact = CompactStr::new(s);
         assert_eq!(compact, s);
+        assert_eq!(s, compact);
         assert_eq!(compact.is_heap_allocated(), is_heap);
     }
 }
@@ -95,6 +97,7 @@ fn test_medium_ascii() {
     for s in strs {
         let compact = CompactStr::new(s);
         assert_eq!(compact, s);
+        assert_eq!(s, compact);
 
         #[cfg(target_pointer_width = "64")]
         let is_heap = false;
@@ -116,6 +119,7 @@ fn test_medium_unicode() {
     for (s, is_heap) in strs {
         let compact = CompactStr::new(s);
         assert_eq!(compact, s);
+        assert_eq!(s, compact);
 
         #[cfg(target_pointer_width = "64")]
         let is_heap = is_heap;
Repository: holmgr/cargo-sweep (Rust)

Issue:
Panic when the `--file` file is not found
```
$ cargo run -- sweep --file
```

```
thread 'main' panicked at src/main.rs:237:18:
Failed to load timestamp file: failed to read stamp file /home/marcospb19/cargo-sweep/sweep.timestamp

Caused by:
    No such file or directory (os error 2)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```


Discussion:

Patch:
diff --git a/src/main.rs b/src/main.rs
index bfaf99b..ef5c76e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -234,8 +234,7 @@ fn main() -> anyhow::Result<()> {
         }
     } else {
         let keep_duration = if let Criterion::File = criterion {
-            let ts = Timestamp::load(paths[0].as_path(), dry_run)
-                .expect("Failed to load timestamp file");
+            let ts = Timestamp::load(paths[0].as_path(), dry_run)?;
             Duration::from(ts)
         } else if let Criterion::Time(days_to_keep) = criterion {
             Duration::from_secs(days_to_keep * 24 * 3600)


Test patch:
diff --git a/tests/integration.rs b/tests/integration.rs
index 8b92c0a..a83852b 100644
--- a/tests/integration.rs
+++ b/tests/integration.rs
@@ -323,6 +323,17 @@ fn error_status() -> TestResult {
     Ok(())
 }
 
+/// This scenario used to panic: https://github.com/holmgr/cargo-sweep/issues/117
+#[test]
+fn stamp_file_not_found() -> TestResult {
+    sweep(&["--file"])
+        .current_dir(test_dir().join("sample-project"))
+        .assert()
+        .failure()
+        .stderr(contains("failed to read stamp file").and(contains("panicked").not()));
+    Ok(())
+}
+
 #[test]
 fn path() -> TestResult {
     let (_, target) = build("sample-project")?;
Repository: z-galaxy/zbus (Rust)

Issue:
breakage in `zvariant_derive` with `ashpd`
After the latest patch release, `ashpd` no longer compiles. Setting `zvariant_derive = "=5.5.1"` resolves the issue.

Steps to reproduce:
1. `cargo init tmp`
2. `cargo add ashpd`
3. `cargo check`

![Image](https://github.com/user-attachments/assets/98746451-536f-480b-a5a9-caeed11f24df)


Discussion:
Ouch. Thank you for reporting. I was suspecting [it might break something](https://toot.cat/@zbus/114500496051793290). 😞 I also made the mistake of publishing this the last two releases as micro (they should have been minor). 🤦‍♂️

I'm travelling at the moment but I'll have a look into it soon...



Patch:
diff --git a/zvariant_derive/src/dict.rs b/zvariant_derive/src/dict.rs
index 60522014a..6c160f0a5 100644
--- a/zvariant_derive/src/dict.rs
+++ b/zvariant_derive/src/dict.rs
@@ -69,10 +69,13 @@ pub fn expand_serialize_derive(input: DeriveInput) -> Result<TokenStream, Error>
                 #[derive(Serialize)]
                 #[serde(rename_all = #rename_all_str)]
                 struct #helper<'a> {
+                    #[serde(skip)]
+                    phantom: ::std::marker::PhantomData<&'a ()>,
                     #(#field_defs,)*
                 }
 
                 let helper = #helper {
+                    phantom: ::std::marker::PhantomData,
                     #(#field_inits,)*
                 };
 


Test patch:
diff --git a/zvariant/tests/dict_value.rs b/zvariant/tests/dict_value.rs
index b10950378..ccecaffb3 100644
--- a/zvariant/tests/dict_value.rs
+++ b/zvariant/tests/dict_value.rs
@@ -231,4 +231,8 @@ fn dict_value() {
         let decoded = encoded.deserialize::<TestDenyUnknown>();
         assert!(decoded.is_err());
     }
+
+    #[derive(Default, Debug, SerializeDict, DeserializeDict, Type)]
+    #[zvariant(signature = "dict")]
+    struct TestEmpty {}
 }
Repository: veryl-lang/veryl (Rust)

Issue:
Recursion
Currently, recursive functions seem to be rejected by the type checker.

```
function sum (
    operand: input u32,
) -> u32 {
    if operand >: 0 {
        return operand + sum(operand - 1);
    } else {
        return 0;
    }
}
```

results in
 
```
Error: cyclice_type_dependency
```

Whether recursion is allowed or not is another question (guaranteeing synthesizability relies on bounding the recursion depth), but for now i think the error is not completely accurate (it shouldn't be a type checking thing).


Discussion:
There is already a recursion limit checker for recursively defined modules, but those are monomorphic.  The fixed depth of the recursion is known at synthesis time.

The recursive depth of your function, if synthesized, would need to be over four billion.  I think functions which recurse on operands should be avoided.



Patch:
diff --git a/crates/analyzer/src/analyzer_error.rs b/crates/analyzer/src/analyzer_error.rs
index 44b116181..b2e785f1e 100644
--- a/crates/analyzer/src/analyzer_error.rs
+++ b/crates/analyzer/src/analyzer_error.rs
@@ -37,7 +37,7 @@ pub enum AnalyzerError {
 
     #[diagnostic(
         severity(Error),
-        code(cyclice_type_dependency),
+        code(cyclic_type_dependency),
         help(""),
         url(
             "https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#cyclic_type_dependency"
diff --git a/crates/analyzer/src/type_dag.rs b/crates/analyzer/src/type_dag.rs
index 90e260bf2..6e9592b61 100644
--- a/crates/analyzer/src/type_dag.rs
+++ b/crates/analyzer/src/type_dag.rs
@@ -93,9 +93,12 @@ impl TypeDag {
         match self.dag.add_edge(start.into(), end.into(), edge) {
             Ok(_) => Ok(()),
             Err(_) => {
-                // Direct recursion of module/interface is allowed
-                let is_direct_recursion = start == end;
-                if matches!(edge, Context::Module | Context::Interface) && is_direct_recursion {
+                // Direct recursion of module/interface/function is allowed
+                let is_allowed_direct_recursion = matches!(
+                    edge,
+                    Context::Module | Context::Interface | Context::Function
+                ) && start == end;
+                if is_allowed_direct_recursion {
                     Ok(())
                 } else {
                     let ssym = self.get_symbol(start);


Test patch:
diff --git a/crates/analyzer/src/tests.rs b/crates/analyzer/src/tests.rs
index 13b4012a6..6898c1338 100644
--- a/crates/analyzer/src/tests.rs
+++ b/crates/analyzer/src/tests.rs
@@ -510,6 +510,23 @@ fn cyclic_type_dependency() {
         errors[0],
         AnalyzerError::CyclicTypeDependency { .. }
     ));
+
+    let code = r#"
+    module ModuleA {
+        function sum(
+            operand: input u32
+        ) -> u32 {
+            if operand >: 0 {
+                return operand + sum(operand - 1);
+            } else {
+                return 0;
+            }
+        }
+    }
+    "#;
+
+    let errors = analyze(code);
+    assert!(errors.is_empty());
 }
 
 #[test]
Repository: z-galaxy/zbus (Rust)

Issue:
`DeserializeDict` fails if struct field is named 'key'
The following fails

```Rust
#[derive(DeserializeDict, Type)]
#[zvariant(signature = "a{sv}")]
pub struct OwnedProperties {
    key: String,
    val: OwnedValue,
}
```

like so: 
```Term
error[E0308]: mismatched types
 --> src/main.rs:7:10
  |
7 | #[derive(DeserializeDict, Type)]
  |          ^^^^^^^^^^^^^^^
  |          |
  |          expected `&str`, found `Option<_>`
  |          expected due to the type of this binding
  |
  = note: expected reference `&str`
                  found enum `std::option::Option<_>`
  = note: this error originates in the derive macro `DeserializeDict` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using `Option::expect` to unwrap the `std::option::Option<_>` value, panicking if the value is an `Option::None`
  |
7 | #[derive(DeserializeDict.expect("REASON"), Type)]
  |  
```

Problem goes away as soon as the field 'key' is renamed to something else.


Discussion:

Patch:
diff --git a/zvariant_derive/src/dict.rs b/zvariant_derive/src/dict.rs
index 17de0100f..47b599728 100644
--- a/zvariant_derive/src/dict.rs
+++ b/zvariant_derive/src/dict.rs
@@ -196,8 +196,8 @@ pub fn expand_deserialize_derive(input: DeriveInput) -> Result<TokenStream, Erro
                         #( let mut #fields = ::std::default::Default::default(); )*
 
                         // does not check duplicated fields, since those shouldn't exist in stream
-                        while let ::std::option::Option::Some(key) = access.next_key::<&str>()? {
-                            match key {
+                        while let ::std::option::Option::Some(__key) = access.next_key::<&str>()? {
+                            match __key {
                                 #(#entries)*
                             }
                         }


Test patch:
diff --git a/zvariant_derive/tests/tests.rs b/zvariant_derive/tests/tests.rs
index 33a96555d..cc81ae4f0 100644
--- a/zvariant_derive/tests/tests.rs
+++ b/zvariant_derive/tests/tests.rs
@@ -99,3 +99,16 @@ fn issues_311() {
         pub sinr: Option<i32>,
     }
 }
+
+#[test]
+#[ignore]
+fn issues_1252() {
+    // Issue 1252: Naming a field `key` in a dict struct causes a conflict with variables created by
+    // `DeserializeDict` macro, ending up with a strange error.
+    #[derive(DeserializeDict, Type)]
+    #[zvariant(signature = "a{sv}")]
+    pub struct OwnedProperties {
+        key: String,
+        val: OwnedValue,
+    }
+}
Repository: rust-num/num-bigint (Rust)

Issue:
from_radix with empty buffer
Calling `from_radix_le` panics when called with an empty buffer (same for `from_radix_be`).
This should simply return the value zero, isimilar to how `from_bytes_le` (and `from_bytes_be`) return zero.

https://docs.rs/num/0.3.1/num/bigint/struct.BigUint.html#method.from_radix_le


Discussion:
Yes, I agree those should return zero. Would you like to make that change?



Patch:
diff --git a/src/biguint.rs b/src/biguint.rs
index 432ff849..71778cb5 100644
--- a/src/biguint.rs
+++ b/src/biguint.rs
@@ -2423,6 +2423,10 @@ impl BigUint {
             "The radix must be within 2...256"
         );
 
+        if buf.is_empty() {
+            return Some(Zero::zero());
+        }
+
         if radix != 256 && buf.iter().any(|&b| b >= radix as u8) {
             return None;
         }
@@ -2466,6 +2470,10 @@ impl BigUint {
             "The radix must be within 2...256"
         );
 
+        if buf.is_empty() {
+            return Some(Zero::zero());
+        }
+
         if radix != 256 && buf.iter().any(|&b| b >= radix as u8) {
             return None;
         }


Test patch:
diff --git a/tests/biguint.rs b/tests/biguint.rs
index cc274954..3752c61d 100644
--- a/tests/biguint.rs
+++ b/tests/biguint.rs
@@ -1551,6 +1551,8 @@ fn test_from_and_to_radix() {
     }
 
     assert!(BigUint::from_radix_le(&[10, 100, 10], 50).is_none());
+    assert_eq!(BigUint::from_radix_le(&[], 2), Some(BigUint::zero()));
+    assert_eq!(BigUint::from_radix_be(&[], 2), Some(BigUint::zero()));
 }
 
 #[test]
Repository: printfn/fend (Rust)

Issue:
Support power notation: 200²
Thank you! I like your project!

This could look like this:
200²
you can type this (on a german layout) with: "Alt Gr" + "2" -> ²
could also create: 2¹²



Discussion:
Thanks for the suggestion! I agree, this would be a good feature to have :)



Patch:
diff --git a/core/src/lexer.rs b/core/src/lexer.rs
index a850549e..b2cef15e 100644
--- a/core/src/lexer.rs
+++ b/core/src/lexer.rs
@@ -371,9 +371,52 @@ fn parse_basic_number<'a, I: Interrupt>(
 		}
 	}
 
+	// parse exponentiation via unicode superscript digits
+	if base.base_as_u8() <= 10
+		&& input
+			.chars()
+			.next()
+			.is_some_and(|c| SUPERSCRIPT_DIGITS.contains(&c))
+	{
+		if let Ok((mut power_digits, remaining)) = parse_power_number(input) {
+			let mut exponent = Number::zero_with_base(base);
+
+			power_digits.reverse();
+
+			for (i, digit) in power_digits.into_iter().enumerate() {
+				let num = digit * 10u64.pow(u32::try_from(i).unwrap());
+				exponent = exponent.add(num.into(), int)?;
+			}
+
+			res = res.pow(exponent, int)?;
+			input = remaining;
+		}
+	}
+
 	Ok((res, input))
 }
 
+const SUPERSCRIPT_DIGITS: [char; 10] = ['⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹'];
+
+fn parse_power_number(input: &str) -> FResult<(Vec<u64>, &str)> {
+	let mut digits: Vec<u64> = Vec::new();
+
+	let (mut ch, mut input) = parse_char(input)?;
+	while let Some((idx, _)) = SUPERSCRIPT_DIGITS
+		.iter()
+		.enumerate()
+		.find(|(_, x)| **x == ch)
+	{
+		digits.push(idx as u64);
+		if input.is_empty() {
+			break;
+		}
+		(ch, input) = parse_char(input)?;
+	}
+
+	Ok((digits, input))
+}
+
 fn parse_number<'a, I: Interrupt>(input: &'a str, int: &I) -> FResult<(Number, &'a str)> {
 	let (base, input) = parse_base_prefix(input).unwrap_or((Base::default(), input));
 	let (res, input) = parse_basic_number(input, base, int)?;


Test patch:
diff --git a/core/tests/integration_tests.rs b/core/tests/integration_tests.rs
index e0d3f1e3..0059b6cb 100644
--- a/core/tests/integration_tests.rs
+++ b/core/tests/integration_tests.rs
@@ -5832,3 +5832,9 @@ fn alias_sqrt() {
 		"approx. 3527.6684147527 s",
 	);
 }
+
+#[test]
+fn test_superscript() {
+	test_eval("200²", "40000");
+	test_eval("13¹³ days", "302875106592253 days");
+}
Repository: veryl-lang/veryl (Rust)

Issue:
Can't evaluate `msb` for type imported from proto package
Veryl compiler reports an `unknown_msb` error for a variable of which type is imported from a proto package.

```systemverilog
proto package foo_proto_pkg {
  type Foo = logic<2>;
}

module ModuleA::<PKG: foo_proto_pkg> {
  import PKG::*;
  let foo     : Foo   = 0;
  let _msb_foo: logic = foo[msb];
}

package bar_pkg {
  type Bar = logic<2>;
}

module ModuleB {
  import bar_pkg::*;
  let bar     : Bar   = 0;
  let _msb_bar: logic = bar[msb];
}
```

```
]8;;https://doc.veryl-lang.org/book/07_appendix/02_semantic_error.html#unknown_msb\unknown_msb (link)]8;;\

  💥 resolving msb is failed
   ╭─[:8:29]
 7 │   let foo     : Foo   = 0;
 8 │   let _msb_foo: logic = foo[msb];
   ·                             ─┬─
   ·                              ╰── Error location
 9 │ }
   ╰────
  help: 
```


Discussion:

Patch:
diff --git a/crates/analyzer/src/handlers/check_msb_lsb.rs b/crates/analyzer/src/handlers/check_msb_lsb.rs
index 07dd60386..3c6dcda91 100644
--- a/crates/analyzer/src/handlers/check_msb_lsb.rs
+++ b/crates/analyzer/src/handlers/check_msb_lsb.rs
@@ -39,6 +39,10 @@ fn trace_type(r#type: &SymType) -> Vec<(SymType, Option<SymbolKind>)> {
             ret.last_mut().unwrap().1 = Some(symbol.kind.clone());
             if let SymbolKind::TypeDef(ref x) = symbol.kind {
                 ret.append(&mut trace_type(&x.r#type));
+            } else if let SymbolKind::ProtoTypeDef(ref x) = symbol.kind {
+                if let Some(ref r#type) = x.r#type {
+                    ret.append(&mut trace_type(r#type));
+                }
             }
         }
     }


Test patch:
diff --git a/crates/analyzer/src/tests.rs b/crates/analyzer/src/tests.rs
index 6c84ef9bc..2648c6a4e 100644
--- a/crates/analyzer/src/tests.rs
+++ b/crates/analyzer/src/tests.rs
@@ -4350,6 +4350,34 @@ fn unknown_msb() {
 
     let errors = analyze(code);
     assert!(errors.is_empty());
+
+    let code = r#"
+    proto package foo_proto_pkg {
+        type Foo;
+    }
+    module ModuleA::<PKG: foo_proto_pkg> {
+        import PKG::*;
+        let foo     : Foo   = 0;
+        let _msb_foo: logic = foo[msb];
+    }
+    "#;
+
+    let errors = analyze(code);
+    assert!(matches!(errors[0], AnalyzerError::UnknownMsb { .. }));
+
+    let code = r#"
+    proto package foo_proto_pkg {
+        type Foo = logic<2>;
+    }
+    module ModuleA::<PKG: foo_proto_pkg> {
+        import PKG::*;
+        let foo     : Foo   = 0;
+        let _msb_foo: logic = foo[msb];
+    }
+    "#;
+
+    let errors = analyze(code);
+    assert!(errors.is_empty());
 }
 
 #[test]
Repository: microsoft/qdk (Rust)

Issue:
Copy and Update Assign with UDT Field doesn't recognize Field Name
**Describe the bug**

The copy-and-update-assign operator doesn't recognize UDT field names. This is in contrast to the regular copy-and=update operator, which _does_ correctly recognize the UDT field names.

**To Reproduce**

```qsharp
namespace Test {
    newtype Pair = (fst: Int, snd : Int);
    @EntryPoint()
    operation Main() : Unit {
        mutable a = Pair(3, 4);
        set a w/= snd <- 5;
    }
}
```

The reference to `snd` gives an error saying "name error: `snd` not found".

**Expected behavior**

The code should compile and run without error. `snd` should be recognized as the name of the field from `Pair`. This behavior matches what is expected of the regular copy-and-update operator behavior: `let b = a w/ snd <- 5` gives no error.



Discussion:

Patch:
diff --git a/compiler/qsc_frontend/src/resolve.rs b/compiler/qsc_frontend/src/resolve.rs
index 5eae8e462a..991b61ecd5 100644
--- a/compiler/qsc_frontend/src/resolve.rs
+++ b/compiler/qsc_frontend/src/resolve.rs
@@ -420,7 +420,8 @@ impl AstVisitor<'_> for With<'_> {
                 });
             }
             ast::ExprKind::Path(path) => self.resolver.resolve_path(NameKind::Term, path),
-            ast::ExprKind::TernOp(ast::TernOp::Update, container, index, replace) => {
+            ast::ExprKind::TernOp(ast::TernOp::Update, container, index, replace)
+            | ast::ExprKind::AssignUpdate(container, index, replace) => {
                 self.visit_expr(container);
                 if !is_field_update(&self.resolver.globals, &self.resolver.scopes, index) {
                     self.visit_expr(index);


Test patch:
diff --git a/compiler/qsc_eval/src/tests.rs b/compiler/qsc_eval/src/tests.rs
index dbc0492b8c..400f01224a 100644
--- a/compiler/qsc_eval/src/tests.rs
+++ b/compiler/qsc_eval/src/tests.rs
@@ -1877,6 +1877,24 @@ fn assignupdate_expr() {
     );
 }
 
+#[test]
+fn assignupdate_expr_using_field_name() {
+    check_expr(
+        indoc! {"
+        namespace A {
+            newtype Pair = (First : Int, Second : Int);
+        }
+    "},
+        indoc! {"{
+            open A;
+            mutable p = Pair(1, 2);
+            set p w/= First <- 3;
+            p
+        }"},
+        &expect!["(3, 2)"],
+    );
+}
+
 #[test]
 fn unop_bitwise_not_int_expr() {
     check_expr("", "~~~(13)", &expect!["-14"]);
Repository: uutils/findutils (Rust)

Issue:
different behavior with printf %A
```
$ touch a
# with our implementation:
$ find a -printf " %A+\n"          
 2024-09-11T10:34:33.361901073+00:00

# With GNU:
$ find a -printf " %A+\n"
 2024-09-11+12:34:33.3619010730
```


Discussion:
@hanbings rings a bell? thanks
> @hanbings rings a bell? thanks

Looks like it's related to https://github.com/uutils/findutils/blob/main/src/find/matchers/printf.rs#L38, let me investigate a little more closely. :)



Patch:
diff --git a/src/find/matchers/printf.rs b/src/find/matchers/printf.rs
index 451a91d8..39246186 100644
--- a/src/find/matchers/printf.rs
+++ b/src/find/matchers/printf.rs
@@ -37,18 +37,24 @@ enum TimeFormat {
 
 impl TimeFormat {
     fn apply(&self, time: SystemTime) -> Result<Cow<'static, str>, Box<dyn Error>> {
-        const CTIME_FORMAT: &str = "%a %b %d %H:%M:%S.%f0 %Y";
-
         let formatted = match self {
             TimeFormat::SinceEpoch => {
                 let duration = time.duration_since(SystemTime::UNIX_EPOCH)?;
                 format!("{}.{:09}0", duration.as_secs(), duration.subsec_nanos())
             }
-            TimeFormat::Ctime => DateTime::<Local>::from(time)
-                .format(CTIME_FORMAT)
-                .to_string(),
+            TimeFormat::Ctime => {
+                const CTIME_FORMAT: &str = "%a %b %d %H:%M:%S.%f0 %Y";
+
+                DateTime::<Local>::from(time)
+                    .format(CTIME_FORMAT)
+                    .to_string()
+            }
             TimeFormat::Strftime(format) => {
-                DateTime::<Local>::from(time).format(format).to_string()
+                // Handle a special case
+                let custom_format = format.replace("%+", "%Y-%m-%d+%H:%M:%S%.f0");
+                DateTime::<Local>::from(time)
+                    .format(&custom_format)
+                    .to_string()
             }
         };
 


Test patch:
diff --git a/tests/find_cmd_tests.rs b/tests/find_cmd_tests.rs
index ad2a34fb..2a3ffce9 100644
--- a/tests/find_cmd_tests.rs
+++ b/tests/find_cmd_tests.rs
@@ -10,6 +10,7 @@
 
 use assert_cmd::Command;
 use predicates::prelude::*;
+use regex::Regex;
 use serial_test::serial;
 use std::fs::{self, File};
 use std::io::{Read, Write};
@@ -367,6 +368,28 @@ fn find_printf() {
             ./test_data/simple/subdir/ABBBC subdir/ABBBC f\n",
         )));
 
+    fs::create_dir_all("a").expect("Failed to create directory 'a'");
+    let output = Command::cargo_bin("find")
+        .expect("found binary")
+        .args(["a", "-printf", "%A+"])
+        .assert()
+        .success()
+        .get_output()
+        .stdout
+        .clone();
+
+    let output_str = String::from_utf8(output).expect("Invalid UTF-8 in output");
+
+    println!("Actual output: '{}'", output_str.trim());
+
+    let re = Regex::new(r"^\d{4}-\d{2}-\d{2}\+\d{2}:\d{2}:\d{2}\.\d{9}0$")
+        .expect("Failed to compile regex");
+
+    assert!(
+        re.is_match(output_str.trim()),
+        "Output did not match expected timestamp format"
+    );
+
     Command::cargo_bin("find")
         .expect("found binary")
         .args([
Repository: getsentry/sentry-rust (Rust)

Issue:
[Structured logging] Stringify u64 attributes
### How do you use Sentry?

Sentry SaaS (sentry.io)

### SDK version

latest

### Steps to reproduce

Log something with an attribute with a value higher than max i64 and lower than max u64

### Expected result

Correct attribute value in Sentry, matching the one that is logged to the console.

### Actual result

serde serializes it as float and there can be loss of precision.
We should make sure that these values are actually serialized as string instead.


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa5db80b..ac98b5cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## Unreleased
+
+### Fixes
+
+- fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) by @lcian
+
 ## 0.40.0
 
 ### Breaking changes
diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs
index f7c76aee..6871d799 100644
--- a/sentry-types/src/protocol/v7.rs
+++ b/sentry-types/src/protocol/v7.rs
@@ -2217,6 +2217,10 @@ impl Serialize for LogAttribute {
                 if let Some(i) = n.as_i64() {
                     state.serialize_field("value", &i)?;
                     state.serialize_field("type", "integer")?;
+                } else if let Some(u) = n.as_u64() {
+                    // Converting to a f64 could lead to precision loss
+                    state.serialize_field("value", &u.to_string())?;
+                    state.serialize_field("type", "string")?;
                 } else if let Some(f) = n.as_f64() {
                     state.serialize_field("value", &f)?;
                     state.serialize_field("type", "double")?;


Test patch:
diff --git a/sentry-types/tests/test_protocol_v7.rs b/sentry-types/tests/test_protocol_v7.rs
index 88a567cc..5638d314 100644
--- a/sentry-types/tests/test_protocol_v7.rs
+++ b/sentry-types/tests/test_protocol_v7.rs
@@ -1536,8 +1536,12 @@ mod test_logs {
             (3.1.into(), r#"{"value":3.1,"type":"double"}"#),
             ("lol".into(), r#"{"value":"lol","type":"string"}"#),
             (false.into(), r#"{"value":false,"type":"boolean"}"#),
-            // Special case
+            // Special cases
             (Value::Null.into(), r#"{"value":"null","type":"string"}"#),
+            (
+                (u64::MAX - 1).into(),
+                r#"{"value":"18446744073709551614","type":"string"}"#,
+            ),
             // Unsupported types (for now)
             (
                 json!(r#"[1,2,3,4]"#).into(),
Repository: dtolnay/proc-macro2 (Rust)

Issue:
/**/ should be insignificant whitespace
Input | Expected | proc-macro2
--- | --- | ---
`/* */` | whitespace | correct
`/** */` | attribute | correct
`/***/` | whitespace | correct
`/**/` | whitespace | INCORRECT

```rust
extern crate proc_macro2;
use proc_macro2::TokenStream;

fn main() {
    for tt in "/**/".parse::<TokenStream>().unwrap() {
        println!("{:?}", tt.kind);
    }
}
```

```
Literal(Literal("/**/"))
```


Discussion:

Patch:
diff --git a/src/strnom.rs b/src/strnom.rs
index 1bf9f236..33964f45 100644
--- a/src/strnom.rs
+++ b/src/strnom.rs
@@ -80,6 +80,9 @@ pub fn whitespace(input: Cursor) -> PResult<()> {
                     continue;
                 }
                 break;
+            } else if s.starts_with("/**/") {
+                i += 4;
+                continue
             } else if s.starts_with("/*") && (!s.starts_with("/**") || s.starts_with("/***")) &&
                       !s.starts_with("/*!") {
                 let (_, com) = block_comment(s)?;


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 7c7275d6..ff9c205a 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -170,3 +170,10 @@ fn no_panic() {
     assert!(s.parse::<proc_macro2::TokenStream>().is_err());
 }
 
+#[test]
+fn tricky_doc_commaent() {
+    let stream = "/**/".parse::<proc_macro2::TokenStream>().unwrap();
+    let tokens = stream.into_iter().collect::<Vec<_>>();
+    assert!(tokens.is_empty(), "not empty -- {:?}", tokens);
+}
+
Repository: cocogitto/cocogitto (Rust)

Issue:
cog changelog is failing on single commit
**Describe the bug**
When there's a single commit, usually the initial commit on the repo, and one tries to generate changelog - CLI fails.

**To Reproduce**
1.  Initialize empty repo and add initial commit.
    ```sh
    git init .
    touch file1.txt
    git add file1.txt
    git commit -m 'feat: initial'
    cog bump -a --disable-bump-commit
    ```
    `cog` detects version `0.1.0`, `cog get-version` also returns `0.1.0`.
1. Try to generate changelog for `0.1.0`
    ```sh
    cog changelog --at 0.1.0
    Error: No commit found to create a changelog
    ```
1. Try to generate changelog without `--at`
    ```
    cog changelog
    Error: No commit found to create a changelog
    ```

**Expected behavior**
The changelog should be generated, containing information from the single commit tagged with `0.1.0` tag.



Discussion:

Patch:
diff --git a/src/git/rev/mod.rs b/src/git/rev/mod.rs
index de7592b6..90c90ab2 100644
--- a/src/git/rev/mod.rs
+++ b/src/git/rev/mod.rs
@@ -10,7 +10,11 @@ pub mod revwalk;
 #[derive(Debug)]
 pub struct CommitIter<'repo>(Vec<(OidOf, Commit<'repo>)>);
 
-impl CommitIter<'_> {
+impl<'repo> CommitIter<'repo> {
+    pub fn single(oid_of: OidOf, commit: Commit<'repo>) -> Self {
+        CommitIter::<'repo>(vec![(oid_of, commit)])
+    }
+
     pub fn from_oid(&self) -> OidOf {
         self.0.last().expect("non empty commit range").0.clone()
     }
diff --git a/src/git/rev/revwalk.rs b/src/git/rev/revwalk.rs
index ee96643b..f279065d 100644
--- a/src/git/rev/revwalk.rs
+++ b/src/git/rev/revwalk.rs
@@ -115,6 +115,14 @@ impl Repository {
     /// Return a commit range from a [`RevspecPattern2`]
     pub fn revwalk(&self, spec: &str) -> Result<CommitIter<'_>, Git2Error> {
         let spec = self.revspec_from_str(spec)?;
+
+        if spec.from() == spec.to() {
+            let oid = *spec.from();
+            let oid_of = self.resolve_oid_of(&oid.to_string())?;
+            let commit = self.0.find_commit(oid)?;
+            return Ok(CommitIter::single(oid_of, commit));
+        }
+
         let mut revwalk = self.0.revwalk()?;
         revwalk.push_range(&spec.to_string())?;
 


Test patch:
diff --git a/tests/cog_tests/bump.rs b/tests/cog_tests/bump.rs
index cd78e392..b3db7574 100644
--- a/tests/cog_tests/bump.rs
+++ b/tests/cog_tests/bump.rs
@@ -954,3 +954,25 @@ fn bump_bug_fix() -> Result<()> {
 
     Ok(())
 }
+
+#[sealed_test]
+fn changelog_on_first_commit_with_tag_on_first_commit() -> Result<()> {
+    git_init()?;
+    git_commit("feat: init")?;
+
+    Command::cargo_bin("cog")?
+        .arg("bump")
+        .arg("--auto")
+        .arg("--disable-bump-commit")
+        .assert()
+        .success();
+
+    Command::cargo_bin("cog")?
+        .arg("changelog")
+        .arg("--at")
+        .arg("0.1.0")
+        .assert()
+        .success();
+
+    Ok(())
+}
Repository: veryl-lang/veryl (Rust)

Issue:
Invalid factor error caused by interface instance in `$sv`
After #1999, the following code causes unexpected error.

```
module Y (
    a: modport $sv::InterfaceA::slave,
) {}

module X {
    inst x: $sv::InterfaceA;
    inst u: Y (
        a: x,
    );
}
```

```
  💥 instance cannot be used as a factor in an expression
   ╭─[:6:10]
 5 │ module X {
 6 │     inst x: $sv::InterfaceA;
   ·          ┬
   ·          ╰── Error location
 7 │     inst u: Y (
   ╰────
  help: remove instance from expression
```


Discussion:

Patch:
diff --git a/crates/analyzer/src/symbol.rs b/crates/analyzer/src/symbol.rs
index 7325068fd..bbcf68c5e 100644
--- a/crates/analyzer/src/symbol.rs
+++ b/crates/analyzer/src/symbol.rs
@@ -297,14 +297,16 @@ impl Symbol {
                     if let Ok(symbol) =
                         symbol_table::resolve((&x.type_name.generic_path(), &self.namespace))
                     {
-                        if let SymbolKind::Interface(_) = symbol.found.kind {
-                            if let Some(array) = evaluator.expression_list(&x.array) {
-                                Evaluated::create_user_defined(symbol.found.id, vec![], array)
-                            } else {
-                                Evaluated::create_unknown()
+                        match symbol.found.kind {
+                            SymbolKind::Interface(_) => {
+                                if let Some(array) = evaluator.expression_list(&x.array) {
+                                    Evaluated::create_user_defined(symbol.found.id, vec![], array)
+                                } else {
+                                    Evaluated::create_unknown()
+                                }
                             }
-                        } else {
-                            self.create_evaluated_with_error()
+                            SymbolKind::SystemVerilog => Evaluated::create_unknown(),
+                            _ => self.create_evaluated_with_error(),
                         }
                     } else {
                         Evaluated::create_unknown()


Test patch:
diff --git a/crates/analyzer/src/tests.rs b/crates/analyzer/src/tests.rs
index 596d40d0b..547bf9c39 100644
--- a/crates/analyzer/src/tests.rs
+++ b/crates/analyzer/src/tests.rs
@@ -6169,6 +6169,22 @@ fn invalid_factor_kind() {
     assert!(matches!(errors[0], AnalyzerError::InvalidFactor { .. }));
     assert!(matches!(errors[1], AnalyzerError::InvalidFactor { .. }));
 
+    let code = r#"
+    module Y (
+        a: modport $sv::InterfaceA::slave,
+    ) {}
+
+    module X {
+        inst x: $sv::InterfaceA;
+        inst u: Y (
+            a: x,
+        );
+    }
+    "#;
+
+    let errors = analyze(code);
+    assert!(errors.is_empty());
+
     // This will be reported as Mismatch Type error.
     //    let code = r#"
     //    module ModuleA::<T: type> {
Repository: kivikakk/comrak (Rust)

Issue:
incorrect parsing of link definition with control characters
More comparisons against an alternat implementation showed this case

```
[A]:\u{1b}

X [A] Y
```

In this case the `[A]:\u{1b}` is being parsed as a link-defintion, giving: 

```
<p>X <a href=\"%1B\">A</a> Y</p>
```

but the specs, both 0.30 and 0.29-gfm, say that a link destination is (emph mine)

> ...
>  * a nonempty sequence of characters that does not start with <, *does not include ASCII space or control characters*, and includes parentheses only if (a) they are backslash-escaped or (b) they are part of a balanced pair of unescaped parentheses. (Implementations may impose limits on parentheses nesting to avoid performance issues, but at least three levels of nesting should be supported.)

So this should parse as:

```
<p>[A]:\u{1b}</p>
<p>X [A] Y</p>
```



Discussion:
It looks like the GFM spec doesn't specify what an ASCII control character is - but 0.30 specifies it as anything in `\u{00}..=\u{1f}` or `\u{7f}`. 
Turns out this was easier to fix than I'd expected. PR in #219.
Thank you! :blush:



Patch:
diff --git a/src/parser/inlines.rs b/src/parser/inlines.rs
index 0c1ee57c..db1ee239 100644
--- a/src/parser/inlines.rs
+++ b/src/parser/inlines.rs
@@ -1152,7 +1152,7 @@ pub fn manual_scan_link_url_2(input: &[u8]) -> Option<(&[u8], usize)> {
             }
             nb_p -= 1;
             i += 1;
-        } else if isspace(input[i]) {
+        } else if isspace(input[i]) || input[i].is_ascii_control() {
             if i == 0 {
                 return None;
             }


Test patch:
diff --git a/src/tests.rs b/src/tests.rs
index bccb951d..b7d05a47 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -553,6 +553,14 @@ fn reference_links() {
     );
 }
 
+#[test]
+fn no_control_characters_in_reference_links() {
+    html(
+        "[A]:\u{1b}\n\nX [A] Y\n",
+        "<p>[A]:\u{1b}</p>\n<p>X [A] Y</p>\n",
+    )
+}
+
 #[test]
 fn link_entity_regression() {
     html(
Repository: lambda-fairy/maud (Rust)

Issue:
Incorrect expression hygiene results in cryptic errors
Consider the following invocation:

```rust
html! {
  (1 + 1)
}
```

This expands to

```rust
{
    extern crate alloc;
    extern crate maud;
    let mut __maud_output = alloc::string::String::with_capacity(7usize);
    {
        use ::maud::macro_private::*;
        match ChooseRenderOrDisplay(&1 + 1) { // <- the problem
            x => (&&x)
                .implements_render_or_display()
                .render_to(x.0, &mut __maud_output),
        }
    };
    maud::PreEscaped(__maud_output)
}
```

Clearly `&1 + 1` should have been `&(1 + 1)`.

(Also, the String size hint is wrong.)


Discussion:

Patch:
diff --git a/maud_macros/src/generate.rs b/maud_macros/src/generate.rs
index c9ba9fb6..ee27a55d 100644
--- a/maud_macros/src/generate.rs
+++ b/maud_macros/src/generate.rs
@@ -103,7 +103,7 @@ impl Generator {
 
     fn splice(&self, expr: TokenStream, build: &mut Builder) {
         let output_ident = self.output_ident.clone();
-        build.push_tokens(quote!(maud::macro_private::render_to!(&#expr, &mut #output_ident);));
+        build.push_tokens(quote!(maud::macro_private::render_to!(&(#expr), &mut #output_ident);));
     }
 
     fn element(&self, name: TokenStream, attrs: Vec<Attr>, body: ElementBody, build: &mut Builder) {


Test patch:
diff --git a/maud/tests/splices.rs b/maud/tests/splices.rs
index d3fd511f..8665e84b 100644
--- a/maud/tests/splices.rs
+++ b/maud/tests/splices.rs
@@ -124,3 +124,9 @@ fn nested_macro_invocation() {
     let result = html! { (format!("{best_pony} is best pony")) };
     assert_eq!(result.into_string(), "Pinkie Pie is best pony");
 }
+
+#[test]
+fn expression_grouping() {
+    let result = html! { (1 + 1) };
+    assert_eq!(result.into_string(), "2");
+}
Repository: fitzgen/bumpalo (Rust)

Issue:
alloc_layout_slow does not respect layout alignment
I wanted to add this test in #42, but it failed:

```rust
#[test]
fn test_alignment() {
    let b = Bump::new();

    let layout = std::alloc::Layout::from_size_align(64, 64).unwrap();

    for _ in 0..1024 {
        let ptr = b.alloc_layout(layout).as_ptr();
        assert_eq!(ptr as *const u8 as usize % 64, 0);
    }
}
```


Discussion:

Patch:
diff --git a/src/lib.rs b/src/lib.rs
index c00a3c0..a9f0e78 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -636,6 +636,10 @@ impl Bump {
             let current_layout = current_footer.as_ref().layout;
             let new_footer =
                 Bump::new_chunk(Some((current_layout.size(), layout)), Some(current_footer));
+            debug_assert_eq!(
+                new_footer.as_ref().data.as_ptr() as usize % layout.align(),
+                0
+            );
 
             // Set the new chunk as our new current chunk.
             self.current_chunk_footer.set(new_footer);
@@ -646,6 +650,8 @@ impl Bump {
             // this can't overflow because we successfully allocated a chunk of
             // at least the requested size.
             let ptr = new_footer.ptr.get().as_ptr() as usize - size;
+            // Round the pointer down to the requested alignment.
+            let ptr = ptr & !(layout.align() - 1);
             debug_assert!(
                 ptr <= new_footer as *const _ as usize,
                 "{:#x} <= {:#x}",


Test patch:
diff --git a/tests/tests.rs b/tests/tests.rs
index 7449f7c..d52f079 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -180,3 +180,15 @@ fn test_reset() {
     );
     assert_eq!(b.iter_allocated_chunks().count(), 1);
 }
+
+#[test]
+fn test_alignment() {
+    let b = Bump::new();
+
+    let layout = std::alloc::Layout::from_size_align(64, 64).unwrap();
+
+    for _ in 0..1024 {
+        let ptr = b.alloc_layout(layout).as_ptr();
+        assert_eq!(ptr as *const u8 as usize % 64, 0);
+    }
+}