Skip to content

Commit 0bcc41f

Browse files
committed
[macros] Support const fns with bounds on MSRV
gherrit-pr-id: Icdb256acfdb274f34312cf5b216a02ca426338a1
1 parent 855c237 commit 0bcc41f

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

src/util/macros.rs

+80
Original file line numberDiff line numberDiff line change
@@ -802,3 +802,83 @@ macro_rules! impl_size_eq {
802802
};
803803
};
804804
}
805+
806+
macro_rules! const_fn {
807+
(
808+
$vis:vis $name:ident $(< $($tyvar:ident),* >)?
809+
( $($arg:ident: $argty:ty),* ) -> $retty:ty
810+
$(
811+
where $($wheretyvar:ident: $wherebound:path,)*
812+
)?
813+
$body:block
814+
) => {
815+
#[allow(non_camel_case_types)]
816+
$vis trait $name $(< $($tyvar),* >)?
817+
where Self: crate::util::macros::HasArgs<($($argty,)*), Args = ($($argty,)*)>,
818+
$(
819+
$($wheretyvar: $wherebound),*
820+
)?
821+
{
822+
const ARGS: Self::Args;
823+
824+
const __RETURN: $retty = {
825+
let ($($arg),*) = Self::ARGS;
826+
loop {
827+
break $body;
828+
}
829+
};
830+
}
831+
};
832+
}
833+
834+
macro_rules! call_const_fn {
835+
(
836+
$name:ident $(:: $names:ident)* $(:: < $($ty:ty),* >)? ($($arg:expr),*)
837+
) => {
838+
{
839+
enum Call {}
840+
841+
impl $name $(:: $names)* $(< $($ty),* >)? for Call {
842+
const ARGS: Self::Args = ($($arg,)*);
843+
}
844+
845+
<Call as $name $(:: $names)* $(:: < $($ty),* >)?>::__RETURN
846+
}
847+
};
848+
}
849+
850+
// Used in the implementation of `const_fn!`.
851+
pub(crate) trait HasArgs<A> {
852+
type Args;
853+
}
854+
855+
impl<A, T> HasArgs<A> for T {
856+
type Args = A;
857+
}
858+
859+
mod tests {
860+
#[test]
861+
fn test_const_fn() {
862+
trait Foo {
863+
const N: usize;
864+
}
865+
866+
impl Foo for () {
867+
const N: usize = 5;
868+
}
869+
870+
const_fn!(foobar<T>(_t: T, n: usize) -> usize
871+
where
872+
T: Foo,
873+
T: Copy,
874+
{
875+
T::N * n
876+
});
877+
878+
const BLAH: usize = call_const_fn!(foobar::<()>((), 4));
879+
880+
const _: () = {
881+
static_assert!(=> BLAH == 20);
882+
};
883+
}
884+
}

0 commit comments

Comments
 (0)