// SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information use fayalite::{ bundle::BundleType, enum_::EnumType, int::{BoolOrIntType, IntType}, prelude::*, ty::StaticType, }; use std::marker::PhantomData; #[hdl(outline_generated)] pub struct S { pub a: T, b: UInt<3>, pub(crate) c: ArrayType, Len>, pub d: T2, pub _phantom: PhantomData<(T, Len)>, } #[hdl(outline_generated)] pub struct S3 { pub a: T, b: UInt<3>, pub(crate) c: Array, LEN>, pub d: S, ()>, } #[hdl(outline_generated)] pub enum E { A, B(UInt<3>), C(T), } #[hdl(outline_generated)] pub struct S2 { pub v: E, } // check that #[hdl] properly handles hygiene macro_rules! types_in_macros { ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident, $D:ident, $E:ident, $F:ident) => { #[hdl] struct $F {} #[hdl] struct $A<$B, $C: Size, const $D: usize, $E = $F> { $a: $B, $b: UIntType<$C>, $c: SInt<$D>, $d: HdlOption<$E>, $e: $E, $f: $F, } #[allow(non_camel_case_types)] #[hdl] enum $B<$C: Size, const $D: usize, $E = $F> { $a($A<(), $C, $D, $E>), $b(UIntType<$C>), $c(SInt<$D>), $d, $e($E), $f($F), } }; // ensure every identifier has different hygiene () => { types_in_macros!(a); }; ($a:ident) => { types_in_macros!($a, b); }; ($a:ident, $b:ident) => { types_in_macros!($a, $b, c); }; ($a:ident, $b:ident, $c:ident) => { types_in_macros!($a, $b, $c, d); }; ($a:ident, $b:ident, $c:ident, $d:ident) => { types_in_macros!($a, $b, $c, $d, e); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => { types_in_macros!($a, $b, $c, $d, $e, f); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident) => { types_in_macros!($a, $b, $c, $d, $e, $f, A); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident) => { types_in_macros!($a, $b, $c, $d, $e, $f, $A, B); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident) => { types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, C); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident) => { types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, $C, D); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident, $D:ident) => { types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, $C, $D, E); }; ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident, $f:ident, $A:ident, $B:ident, $C:ident, $D:ident, $E:ident) => { types_in_macros!($a, $b, $c, $d, $e, $f, $A, $B, $C, $D, $E, F); }; } types_in_macros!(); mod bound_kind { use fayalite::prelude::*; #[hdl] pub struct Type { v: T, } #[hdl] pub struct Size { v: UIntType, } } macro_rules! check_bounds { ($name:ident<$(#[$field:ident, $kind:ident] $var:ident: $($bound:ident +)*),*>) => { #[hdl(outline_generated)] struct $name<$($var: $($bound +)*,)*> { $($field: bound_kind::$kind<$var>,)* } }; } check_bounds!(CheckBoundsS0<#[a, Size] A: Size +>); check_bounds!(CheckBoundsS1<#[a, Size] A: KnownSize +>); check_bounds!(CheckBoundsT0<#[a, Type] A: Type +>); check_bounds!(CheckBoundsT1<#[a, Type] A: BoolOrIntType +>); check_bounds!(CheckBoundsT2<#[a, Type] A: BundleType +>); check_bounds!(CheckBoundsT3<#[a, Type] A: EnumType +>); check_bounds!(CheckBoundsT4<#[a, Type] A: IntType +>); check_bounds!(CheckBoundsT5<#[a, Type] A: StaticType +>); check_bounds!(CheckBoundsSS0<#[a, Size] A: Size +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsSS1<#[a, Size] A: KnownSize +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsST0<#[a, Size] A: Size +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsST1<#[a, Size] A: KnownSize +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsTS0<#[a, Type] A: Type +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsTS1<#[a, Type] A: BoolOrIntType +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsTS2<#[a, Type] A: BundleType +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsTS3<#[a, Type] A: EnumType +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsTS4<#[a, Type] A: IntType +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsTS5<#[a, Type] A: StaticType +, #[b, Size] B: Size +>); check_bounds!(CheckBoundsTT0<#[a, Type] A: Type +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsTT1<#[a, Type] A: BoolOrIntType +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsTT2<#[a, Type] A: BundleType +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsTT3<#[a, Type] A: EnumType +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsTT4<#[a, Type] A: IntType +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsTT5<#[a, Type] A: StaticType +, #[b, Type] B: Type +>); check_bounds!(CheckBoundsSSS0<#[a, Size] A: Size +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsSSS1<#[a, Size] A: KnownSize +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsSST0<#[a, Size] A: Size +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsSST1<#[a, Size] A: KnownSize +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsSTS0<#[a, Size] A: Size +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsSTS1<#[a, Size] A: KnownSize +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsSTT0<#[a, Size] A: Size +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsSTT1<#[a, Size] A: KnownSize +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTSS0<#[a, Type] A: Type +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTSS1<#[a, Type] A: BoolOrIntType +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTSS2<#[a, Type] A: BundleType +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTSS3<#[a, Type] A: EnumType +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTSS4<#[a, Type] A: IntType +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTSS5<#[a, Type] A: StaticType +, #[b, Size] B: Size +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTST0<#[a, Type] A: Type +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTST1<#[a, Type] A: BoolOrIntType +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTST2<#[a, Type] A: BundleType +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTST3<#[a, Type] A: EnumType +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTST4<#[a, Type] A: IntType +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTST5<#[a, Type] A: StaticType +, #[b, Size] B: Size +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTS0<#[a, Type] A: Type +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTTS1<#[a, Type] A: BoolOrIntType +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTTS2<#[a, Type] A: BundleType +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTTS3<#[a, Type] A: EnumType +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTTS4<#[a, Type] A: IntType +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTTS5<#[a, Type] A: StaticType +, #[b, Type] B: Type +, #[c, Size] C: Size +>); check_bounds!(CheckBoundsTTT0<#[a, Type] A: Type +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT1<#[a, Type] A: BoolOrIntType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT2<#[a, Type] A: BundleType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT3<#[a, Type] A: EnumType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT4<#[a, Type] A: IntType +, #[b, Type] B: Type +, #[c, Type] C: Type +>); check_bounds!(CheckBoundsTTT5<#[a, Type] A: StaticType +, #[b, Type] B: Type +, #[c, Type] C: Type +>);