Register associated consts during collection, not emission
`assoc_const` both emits the constant and records its name, and it runs during emission -- so an array length naming one could not resolve it, because lengths are mapped long before that. `[u8; ObjectIdentifier::MAX_SIZE]` in the dependency graph is the case. Registered in `collect_impl` alongside everything else a later pass needs to look up. The emission-time registration stays; it writes the same entry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2687049 parent: cb19206 modified
src/lower.rs +17 -3 | @@ -908,10 +908,24 @@ impl Lowerer { | ||
| 908 | 908 | // Before anything else: a method body may declare its own types, and |
| 909 | 909 | // the trait branches below return early. |
| 910 | 910 | self.note_const_generics(&im.generics)?; |
| 911 | + // Associated consts are registered here for the same reason anything | |
| 912 | + // else is: an array length elsewhere may name one, and that name has | |
| 913 | + // to resolve before any body is lowered. `assoc_const` records them | |
| 914 | + // too, but it runs during emission, which is far too late. | |
| 915 | + let tyn = type_name(self_ty); | |
| 911 | 916 | for it in &im.items { |
| 912 | - if let syn::ImplItem::Fn(m) = it { | |
| 913 | - self.collect_body_items(&m.block)?; | |
| 914 | - self.note_const_generics(&m.sig.generics)?; | |
| 917 | + match it { | |
| 918 | + syn::ImplItem::Fn(m) => { | |
| 919 | + self.collect_body_items(&m.block)?; | |
| 920 | + self.note_const_generics(&m.sig.generics)?; | |
| 921 | + } | |
| 922 | + syn::ImplItem::Const(c) => { | |
| 923 | + let t = self.map_ty(&c.ty)?.owned(); | |
| 924 | + let n = ident(&format!("{}_{}", tyn, c.ident)); | |
| 925 | + self.assoc_consts | |
| 926 | + .insert((tyn.clone(), c.ident.to_string()), (n, t)); | |
| 927 | + } | |
| 928 | + _ => {} | |
| 915 | 929 | } |
| 916 | 930 | } |
| 917 | 931 | { |
| @@ -908,10 +908,24 @@ impl Lowerer { | |||
| 908 | // Before anything else: a method body may declare its own types, and | 908 | // Before anything else: a method body may declare its own types, and |
| 909 | // the trait branches below return early. | 909 | // the trait branches below return early. |
| 910 | self.note_const_generics(&im.generics)?; | 910 | self.note_const_generics(&im.generics)?; |
| 911 | + // Associated consts are registered here for the same reason anything | ||
| 912 | + // else is: an array length elsewhere may name one, and that name has | ||
| 913 | + // to resolve before any body is lowered. `assoc_const` records them | ||
| 914 | + // too, but it runs during emission, which is far too late. | ||
| 915 | + let tyn = type_name(self_ty); | ||
| 911 | for it in &im.items { | 916 | for it in &im.items { |
| 912 | - if let syn::ImplItem::Fn(m) = it { | 917 | + match it { |
| 913 | - self.collect_body_items(&m.block)?; | 918 | + syn::ImplItem::Fn(m) => { |
| 914 | - self.note_const_generics(&m.sig.generics)?; | 919 | + self.collect_body_items(&m.block)?; |
| 920 | + self.note_const_generics(&m.sig.generics)?; | ||
| 921 | + } | ||
| 922 | + syn::ImplItem::Const(c) => { | ||
| 923 | + let t = self.map_ty(&c.ty)?.owned(); | ||
| 924 | + let n = ident(&format!("{}_{}", tyn, c.ident)); | ||
| 925 | + self.assoc_consts | ||
| 926 | + .insert((tyn.clone(), c.ident.to_string()), (n, t)); | ||
| 927 | + } | ||
| 928 | + _ => {} | ||
| 915 | } | 929 | } |
| 916 | } | 930 | } |
| 917 | { | 931 | { |