Skip to content

Commit

Permalink
Add more stack macro tests
Browse files Browse the repository at this point in the history
  • Loading branch information
birktj committed Apr 22, 2023
1 parent 1cc5772 commit 92d6b84
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 13 deletions.
31 changes: 20 additions & 11 deletions nalgebra-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use syn::spanned::Spanned;
use syn::{parse_macro_input, Token};
use syn::{Expr, Lit};

use proc_macro2::{Delimiter, Spacing, TokenStream as TokenStream2, TokenTree};
use proc_macro2::{Delimiter, Spacing, Span, TokenStream as TokenStream2, TokenTree};
use proc_macro2::{Group, Punct};

struct Matrix {
Expand Down Expand Up @@ -445,11 +445,14 @@ impl ConcatElem {
#[proc_macro]
pub fn stack(stream: TokenStream) -> TokenStream {
let matrix = parse_macro_input!(stream as Matrix);
proc_macro::TokenStream::from(stack_impl("__11f075cdd4a86538", matrix))
proc_macro::TokenStream::from(match stack_impl("__11f075cdd4a86538", matrix) {
Ok(res) => res,
Err(err) => err.into_compile_error(),
})
}

#[allow(clippy::too_many_lines)]
fn stack_impl(prefix: &str, matrix: Matrix) -> TokenStream2 {
fn stack_impl(prefix: &str, matrix: Matrix) -> Result<TokenStream2> {
let n_macro_rows = matrix.nrows();
let n_macro_cols = matrix.ncols();

Expand Down Expand Up @@ -485,7 +488,7 @@ fn stack_impl(prefix: &str, matrix: Matrix) -> TokenStream2 {
}).reduce(|a, b| quote!{
<nalgebra::constraint::ShapeConstraint as nalgebra::constraint::DimEq<_, _>>::representative(#a, #b)
.expect("The concatenated matrices do not have the same number of columns")
}).expect("At least one element in each row must be an expression of type `Matrix`");
}).ok_or(Error::new(Span::call_site(), "At least one element in each row must be an expression of type `Matrix`"))?;

let size_ident = format_ident!("{}_cat_row_{}_size", prefix, i);
let offset_ident = format_ident!("{}_cat_row_{}_offset", prefix, i);
Expand All @@ -511,7 +514,7 @@ fn stack_impl(prefix: &str, matrix: Matrix) -> TokenStream2 {
}).reduce(|a, b| quote!{
<nalgebra::constraint::ShapeConstraint as nalgebra::constraint::DimEq<_, _>>::representative(#a, #b)
.expect("The concatenated matrices do not have the same number of rows")
}).expect("At least one element in each column must be an expression of type `Matrix`");
}).ok_or(Error::new(Span::call_site(), "At least one element in each column must be an expression of type `Matrix`"))?;

let size_ident = format_ident!("{}_cat_col_{}_size", prefix, j);
let offset_ident = format_ident!("{}_cat_col_{}_offset", prefix, j);
Expand Down Expand Up @@ -540,7 +543,10 @@ fn stack_impl(prefix: &str, matrix: Matrix) -> TokenStream2 {
<_ as nalgebra::DimAdd<_>>::add(#a, #b)
}
})
.expect("More than zero rows in concatenation");
.ok_or(Error::new(
Span::call_site(),
"`stack` macro cannot be used without any arguments",
))?;

let num_cols = (0..n_macro_cols)
.map(|j| {
Expand All @@ -552,7 +558,10 @@ fn stack_impl(prefix: &str, matrix: Matrix) -> TokenStream2 {
<_ as nalgebra::DimAdd<_>>::add(#a, #b)
}
})
.unwrap();
.ok_or(Error::new(
Span::call_site(),
"`stack` macro cannot be used without any arguments",
))?;

// It should be possible to use `uninitialized_generic` here instead
// however that would mean that the macro needs to generate unsafe code
Expand Down Expand Up @@ -583,12 +592,12 @@ fn stack_impl(prefix: &str, matrix: Matrix) -> TokenStream2 {
}
}

quote! {
Ok(quote! {
{
#output
matrix
}
}
})
}

#[cfg(test)]
Expand All @@ -602,7 +611,7 @@ mod tests {
0, b;
];

let result = stack_impl("", input);
let result = stack_impl("", input).unwrap();

let expected = quote! {{
let _cat_0_0 = a;
Expand Down Expand Up @@ -645,7 +654,7 @@ mod tests {
e, 0, 0;
];

let result = stack_impl("", input);
let result = stack_impl("", input).unwrap();

let expected = quote! {{
let _cat_0_0 = a;
Expand Down
64 changes: 63 additions & 1 deletion nalgebra-macros/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use nalgebra::{
Point1, Point2, Point3, Point4, Point5, Point6, SMatrix, SVector, Vector1, Vector2, Vector3,
Vector4, Vector5, Vector6,
};
use nalgebra_macros::{stack, dmatrix, dvector, matrix, point, vector};
use nalgebra_macros::{dmatrix, dvector, matrix, point, stack, vector};

fn check_statically_same_type<T>(_: &T, _: &T) {}

Expand Down Expand Up @@ -365,3 +365,65 @@ fn stack_nested() {

assert_eq_and_type!(m, res);
}

#[test]
fn stack_single() {
let a = matrix![1, 2; 3, 4];
let b = stack![a];

assert_eq_and_type!(a, b);
}

#[test]
fn stack_single_row() {
let a = matrix![1, 2; 3, 4];
let m = stack![a, a];

let res = matrix![
1, 2, 1, 2;
3, 4, 3, 4;
];

assert_eq_and_type!(m, res);
}

#[test]
fn stack_single_col() {
let a = matrix![1, 2; 3, 4];
let m = stack![a; a];

let res = matrix![
1, 2;
3, 4;
1, 2;
3, 4;
];

assert_eq_and_type!(m, res);
}

#[test]
fn stack_expr() {
let a = matrix![1, 2; 3, 4];
let b = matrix![5, 6; 7, 8];
let m = stack![a + b; b - a];

let res = matrix![
6, 8;
10, 12;
4, 4;
4, 4;
];

assert_eq_and_type!(m, res);
}

#[test]
fn stack_trybuild_tests() {
let t = trybuild::TestCases::new();

// Verify error message when try to conactenate no matrices
t.compile_fail("tests/trybuild/stack_empty.rs");
t.compile_fail("tests/trybuild/stack_empty_row.rs");
t.compile_fail("tests/trybuild/stack_empty_col.rs");
}
5 changes: 5 additions & 0 deletions nalgebra-macros/tests/trybuild/stack_empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use nalgebra_macros::stack;

fn main() {
stack![];
}
7 changes: 7 additions & 0 deletions nalgebra-macros/tests/trybuild/stack_empty.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: `stack` macro cannot be used without any arguments
--> tests/trybuild/stack_empty.rs:4:5
|
4 | stack![];
| ^^^^^^^^
|
= note: this error originates in the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
6 changes: 6 additions & 0 deletions nalgebra-macros/tests/trybuild/stack_empty_col.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use nalgebra_macros::{matrix, stack};

fn main() {
let m = matrix![1, 2; 3, 4];
stack![0, m];
}
7 changes: 7 additions & 0 deletions nalgebra-macros/tests/trybuild/stack_empty_col.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: At least one element in each column must be an expression of type `Matrix`
--> tests/trybuild/stack_empty_col.rs:5:5
|
5 | stack![0, m];
| ^^^^^^^^^^^^
|
= note: this error originates in the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
6 changes: 6 additions & 0 deletions nalgebra-macros/tests/trybuild/stack_empty_row.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use nalgebra_macros::{matrix, stack};

fn main() {
let m = matrix![1, 2; 3, 4];
stack![0; m];
}
7 changes: 7 additions & 0 deletions nalgebra-macros/tests/trybuild/stack_empty_row.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: At least one element in each row must be an expression of type `Matrix`
--> tests/trybuild/stack_empty_row.rs:5:5
|
5 | stack![0; m];
| ^^^^^^^^^^^^
|
= note: this error originates in the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info)
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pub use crate::sparse::*;
pub use base as core;

#[cfg(feature = "macros")]
pub use nalgebra_macros::{stack, dmatrix, dvector, matrix, point, vector};
pub use nalgebra_macros::{dmatrix, dvector, matrix, point, stack, vector};

use simba::scalar::SupersetOf;
use std::cmp::{self, Ordering, PartialOrd};
Expand Down

0 comments on commit 92d6b84

Please sign in to comment.