Skip to content

Commit 42a4c22

Browse files
committed
Improve error messages for table!
We now use an explicit `compile_error!` call to produce a meaningful error message if a user provided an unsupported number of columns for a specific table. Before this change we would fail with a large error message about unimplemented trait bounds.
1 parent f48ff1f commit 42a4c22

File tree

4 files changed

+168
-0
lines changed

4 files changed

+168
-0
lines changed

diesel/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,7 @@ pub use crate::result::Error::NotFound;
444444
pub(crate) mod diesel {
445445
pub use super::*;
446446
}
447+
448+
// workaround https://github.com/rust-lang/rust/pull/52234
449+
#[doc(hidden)]
450+
pub use __diesel_check_column_count_internal as __diesel_check_column_count;

diesel/src/macros/mod.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,32 @@ macro_rules! __diesel_parse_columns {
645645
#[doc(hidden)]
646646
macro_rules! __diesel_table_impl {
647647
(
648+
table = { $($table: tt)* },
649+
columns = [$({
650+
name = $column_name:ident,
651+
sql_name = $column_sql_name:expr,
652+
ty = ($($column_ty:tt)*),
653+
$($column:tt)*
654+
},)+],
655+
) => {
656+
$crate::__diesel_check_column_count!{
657+
inner = {
658+
$crate::__diesel_table_impl! {
659+
impl_table,
660+
table = { $($table)*},
661+
columns = [$({
662+
name = $column_name,
663+
sql_name = $column_sql_name,
664+
ty = ($($column_ty)*),
665+
$($column)*
666+
},)+],
667+
}
668+
},
669+
($($column_name,)*)
670+
}
671+
};
672+
(
673+
impl_table,
648674
table = {
649675
imports = [$($imports:tt)*],
650676
meta = [$($meta:tt)*],
@@ -1324,6 +1350,106 @@ macro_rules! __diesel_with_dollar_sign {
13241350
}
13251351

13261352

1353+
macro_rules! impl_column_check {
1354+
($(
1355+
$Tuple:tt {
1356+
$(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
1357+
}
1358+
)+) => {
1359+
__diesel_with_dollar_sign! {
1360+
($d:tt) => {
1361+
#[macro_export]
1362+
#[doc(hidden)]
1363+
macro_rules! __diesel_check_column_count_internal {
1364+
$(
1365+
(inner = {$d($d inner: tt)*}, ($($d $T: ident,)*)) => {
1366+
$d($d inner)*
1367+
};
1368+
)*
1369+
(inner = {$d($d inner: tt)*}, ($d($d names: ident,)*)) => {
1370+
$crate::__diesel_error_table_size!();
1371+
}
1372+
}
1373+
1374+
// workaround https://github.com/rust-lang/rust/pull/52234
1375+
#[doc(hidden)]
1376+
pub use __diesel_check_column_count_internal as __diesel_check_column_count;
1377+
}
1378+
}
1379+
}
1380+
}
1381+
1382+
crate::__diesel_for_each_tuple!(impl_column_check);
1383+
1384+
#[cfg(not(any(
1385+
feature = "32-column-tables",
1386+
feature = "64-column-tables",
1387+
feature = "128-column-tables"
1388+
)))]
1389+
#[macro_export]
1390+
#[doc(hidden)]
1391+
macro_rules! __diesel_error_table_size {
1392+
() => {
1393+
compile_error!(
1394+
"Table contains more than 16 columns. Consider enabling the `32-column-tables` feature to enable diesels support for tables with more than 16 columns."
1395+
);
1396+
1397+
}
1398+
}
1399+
1400+
1401+
#[cfg(all(
1402+
feature = "32-column-tables",
1403+
not(feature = "64-column-tables"),
1404+
not(feature = "128-column-tables")
1405+
))]
1406+
#[macro_export]
1407+
#[doc(hidden)]
1408+
macro_rules! __diesel_error_table_size {
1409+
() => {
1410+
compile_error!(
1411+
"Table contains more than 32 columns. Consider enabling the `64-column-tables` feature to enable diesels support for tables with more than 32 columns."
1412+
);
1413+
1414+
}
1415+
}
1416+
1417+
1418+
#[cfg(all(
1419+
feature = "32-column-tables",
1420+
feature = "64-column-tables",
1421+
not(feature = "128-column-tables")
1422+
))]
1423+
#[macro_export]
1424+
#[doc(hidden)]
1425+
macro_rules! __diesel_error_table_size {
1426+
() => {
1427+
compile_error!(
1428+
"Table contains more than 64 columns. Consider enabling the `128-column-tables` feature to enable diesels support for tables with more than 64 columns."
1429+
);
1430+
1431+
}
1432+
}
1433+
1434+
1435+
#[cfg(all(
1436+
feature = "32-column-tables",
1437+
feature = "64-column-tables",
1438+
feature = "128-column-tables"
1439+
))]
1440+
#[macro_export]
1441+
#[doc(hidden)]
1442+
macro_rules! __diesel_error_table_size {
1443+
() => {
1444+
compile_error!(
1445+
"You reached the end. Diesel does not support tables with more than 128 columns. Consider using less columns."
1446+
);
1447+
}
1448+
}
1449+
1450+
1451+
1452+
13271453
// The order of these modules is important (at least for those which have tests).
13281454
// Utility macros which don't call any others need to come first.
13291455
#[macro_use]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use diesel::prelude::table;
2+
3+
table! {
4+
test_table(column_1) {
5+
column_1 -> Integer,
6+
column_2 -> Integer,
7+
column_3 -> Integer,
8+
column_4 -> Integer,
9+
column_5 -> Integer,
10+
column_6 -> Integer,
11+
column_7 -> Integer,
12+
column_8 -> Integer,
13+
column_9 -> Integer,
14+
column_10 -> Integer,
15+
column_12 -> Integer,
16+
column_13 -> Integer,
17+
column_14 -> Integer,
18+
column_15 -> Integer,
19+
column_16 -> Integer,
20+
column_17 -> Integer,
21+
column_18 -> Integer,
22+
}
23+
}
24+
25+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: Table contains more than 16 columns. Consider enabling the `32-column-tables` feature to enable diesels support for tables with more than 16 columns.
2+
--> tests/fail/check_message_for_to_many_columns.rs:3:1
3+
|
4+
3 | / table! {
5+
4 | | test_table(column_1) {
6+
5 | | column_1 -> Integer,
7+
6 | | column_2 -> Integer,
8+
... |
9+
22 | | }
10+
23 | | }
11+
| |_^
12+
|
13+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)