nandi/rustnimpublic Fork
⑂ 211aebe
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/rustnim.git
git clone ssh://git@rickub.com/nandi/rustnim.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

Lower `Borrow::borrow`, the free-function `PartialEq`, and `cmp::Ordering`

`equivalent` compiles -- the third of libcosmic's dependencies to go the whole
way, and `cfg-if` makes a fourth: it had been failing on the output filename
the inventory chose, not on anything rustnim did.

`Borrow::borrow` yields a reference to the same value, and a reference is the
value here. Not `RefCell::borrow`, which is a runtime borrow check returning a
guard -- rustnim does not model `RefCell` at all, so there is nothing to
confuse it with.

`PartialEq::eq(a, b)` in the spelling the derived impls use, alongside the
method form that was already there.

`Ordering` needs its qualifier: `cmp::Ordering` and `atomic::Ordering` are
different types that end in the same segment, and mapping on the last segment
alone would have given an atomic's memory ordering a comparison type. A
crate's own `Ordering` wins over both.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandithebull committed 2026-09-20T11:05:28-07:00 Browse files
211aebe parent: 8038a82
modified src/lower.rs +33 -0
@@ -1545,6 +1545,22 @@ impl Lowerer {
15451545 }
15461546
15471547 fn map_ty_inner(&self, t: &syn::Type) -> Result<Nim, String> {
1548+ // `cmp::Ordering` and `atomic::Ordering` are different types that end
1549+ // in the same segment, so this one needs the qualifier. A crate's own
1550+ // `Ordering` wins over both.
1551+ if let syn::Type::Path(p) = t {
1552+ let segs: Vec<String> =
1553+ p.path.segments.iter().map(|s| s.ident.to_string()).collect();
1554+ if segs.last().is_some_and(|n| n == "Ordering")
1555+ && !self.enums.contains_key("Ordering")
1556+ && !self.structs.contains_key("Ordering")
1557+ {
1558+ let atomic = segs.iter().any(|s| s == "atomic");
1559+ return Ok(Nim::Prim(
1560+ if atomic { "MemoryOrder" } else { "RsOrdering" }.into(),
1561+ ));
1562+ }
1563+ }
15481564 // `Self::Item` names an associated type of the enclosing `impl`.
15491565 if let syn::Type::Path(p) = t {
15501566 let segs: Vec<String> =
@@ -7582,6 +7598,16 @@ impl Lowerer {
75827598 }
75837599 }
75847600 }
7601+ // `PartialEq::eq(a, b)` / `ne` in their free-function spelling,
7602+ // which is what the derived impls use.
7603+ "eq" | "ne" if codes.len() == 2 => {
7604+ let op = if name == "eq" { "==" } else { "!=" };
7605+ let b = self.expr_at(&c.args[1], args[0].ty.as_ref())?;
7606+ return Ok(Val::new(
7607+ format!("({} {} {})", codes[0], op, b.code),
7608+ Some(Nim::Prim("bool".into())),
7609+ ));
7610+ }
75857611 // `cmp::max` / `cmp::min` are Nim's `max` / `min` on the same
75867612 // ordering.
75877613 "max" | "min" if codes.len() == 2 => {
@@ -8230,6 +8256,13 @@ impl Lowerer {
82308256 }
82318257 "clone" | "to_vec" | "to_owned" | "as_slice" | "as_ref" | "as_mut" | "iter"
82328258 | "into_iter" => (recv.code.clone(), rt.clone()),
8259+ // `Borrow::borrow` yields a reference to the same value, and a
8260+ // reference *is* the value here. Not `RefCell::borrow`, which is
8261+ // a runtime borrow check returning a guard -- rustnim does not
8262+ // model `RefCell` at all, so there is nothing to confuse it with.
8263+ "borrow" | "borrow_mut" if m.args.is_empty() => {
8264+ (recv.code.clone(), rt.clone())
8265+ }
82338266 "unwrap" | "expect" => {
82348267 // Expanded inline rather than called as a generic proc: when
82358268 // the payload is a view, Nim can only borrow from a path
@@ -1545,6 +1545,22 @@ impl Lowerer {
1545 }1545 }
1546 1546
1547 fn map_ty_inner(&self, t: &syn::Type) -> Result<Nim, String> {1547 fn map_ty_inner(&self, t: &syn::Type) -> Result<Nim, String> {
1548+ // `cmp::Ordering` and `atomic::Ordering` are different types that end
1549+ // in the same segment, so this one needs the qualifier. A crate's own
1550+ // `Ordering` wins over both.
1551+ if let syn::Type::Path(p) = t {
1552+ let segs: Vec<String> =
1553+ p.path.segments.iter().map(|s| s.ident.to_string()).collect();
1554+ if segs.last().is_some_and(|n| n == "Ordering")
1555+ && !self.enums.contains_key("Ordering")
1556+ && !self.structs.contains_key("Ordering")
1557+ {
1558+ let atomic = segs.iter().any(|s| s == "atomic");
1559+ return Ok(Nim::Prim(
1560+ if atomic { "MemoryOrder" } else { "RsOrdering" }.into(),
1561+ ));
1562+ }
1563+ }
1548 // `Self::Item` names an associated type of the enclosing `impl`.1564 // `Self::Item` names an associated type of the enclosing `impl`.
1549 if let syn::Type::Path(p) = t {1565 if let syn::Type::Path(p) = t {
1550 let segs: Vec<String> =1566 let segs: Vec<String> =
@@ -7582,6 +7598,16 @@ impl Lowerer {
7582 }7598 }
7583 }7599 }
7584 }7600 }
7601+ // `PartialEq::eq(a, b)` / `ne` in their free-function spelling,
7602+ // which is what the derived impls use.
7603+ "eq" | "ne" if codes.len() == 2 => {
7604+ let op = if name == "eq" { "==" } else { "!=" };
7605+ let b = self.expr_at(&c.args[1], args[0].ty.as_ref())?;
7606+ return Ok(Val::new(
7607+ format!("({} {} {})", codes[0], op, b.code),
7608+ Some(Nim::Prim("bool".into())),
7609+ ));
7610+ }
7585 // `cmp::max` / `cmp::min` are Nim's `max` / `min` on the same7611 // `cmp::max` / `cmp::min` are Nim's `max` / `min` on the same
7586 // ordering.7612 // ordering.
7587 "max" | "min" if codes.len() == 2 => {7613 "max" | "min" if codes.len() == 2 => {
@@ -8230,6 +8256,13 @@ impl Lowerer {
8230 }8256 }
8231 "clone" | "to_vec" | "to_owned" | "as_slice" | "as_ref" | "as_mut" | "iter"8257 "clone" | "to_vec" | "to_owned" | "as_slice" | "as_ref" | "as_mut" | "iter"
8232 | "into_iter" => (recv.code.clone(), rt.clone()),8258 | "into_iter" => (recv.code.clone(), rt.clone()),
8259+ // `Borrow::borrow` yields a reference to the same value, and a
8260+ // reference *is* the value here. Not `RefCell::borrow`, which is
8261+ // a runtime borrow check returning a guard -- rustnim does not
8262+ // model `RefCell` at all, so there is nothing to confuse it with.
8263+ "borrow" | "borrow_mut" if m.args.is_empty() => {
8264+ (recv.code.clone(), rt.clone())
8265+ }
8233 "unwrap" | "expect" => {8266 "unwrap" | "expect" => {
8234 // Expanded inline rather than called as a generic proc: when8267 // Expanded inline rather than called as a generic proc: when
8235 // the payload is a view, Nim can only borrow from a path8268 // the payload is a view, Nim can only borrow from a path