Skip to content

Commit 3b62b73

Browse files
committed
chore: add deprecation notice for type ascription use
1 parent 4f1ac1d commit 3b62b73

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

sqlx-macros-core/src/query/args.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::database::DatabaseExt;
22
use crate::query::QueryMacroInput;
33
use either::Either;
4-
use proc_macro2::TokenStream;
5-
use quote::{format_ident, quote, quote_spanned};
4+
use proc_macro2::{Ident, TokenStream};
5+
use quote::{format_ident, quote, quote_spanned, ToTokens};
66
use sqlx_core::describe::Describe;
77
use syn::spanned::Spanned;
88
use syn::{Expr, ExprCast, ExprGroup, ExprType, Type};
@@ -32,6 +32,8 @@ pub fn quote_args<DB: DatabaseExt>(
3232
#(let #arg_name = &(#arg_expr);)*
3333
};
3434

35+
let mut args_warnings: Vec<TokenStream> = vec![];
36+
3537
let args_check = match info.parameters() {
3638
None | Some(Either::Right(_)) => {
3739
// all we can do is check arity which we did
@@ -52,7 +54,12 @@ pub fn quote_args<DB: DatabaseExt>(
5254
let param_ty = match get_type_override(expr) {
5355
// cast or type ascription will fail to compile if the type does not match
5456
// and we strip casts to wildcard
55-
Some(_) => return Ok(quote!()),
57+
Some((_, false)) => return Ok(quote!()),
58+
Some((ty, true)) => {
59+
let warning = create_warning(name.clone(), ty.clone(), expr.clone());
60+
args_warnings.push(warning);
61+
return Ok(quote!())
62+
},
5663
None => {
5764
DB::param_type_for_id(&param_ty)
5865
.ok_or_else(|| {
@@ -101,6 +108,8 @@ pub fn quote_args<DB: DatabaseExt>(
101108
let args_count = input.arg_exprs.len();
102109

103110
Ok(quote! {
111+
#(#args_warnings)*
112+
104113
#arg_bindings
105114

106115
#args_check
@@ -114,11 +123,37 @@ pub fn quote_args<DB: DatabaseExt>(
114123
})
115124
}
116125

117-
fn get_type_override(expr: &Expr) -> Option<&Type> {
126+
fn create_warning(name: Ident, ty: Type, expr: Expr) -> TokenStream {
127+
let span = expr.span();
128+
let stripped = strip_wildcard(expr).to_token_stream();
129+
let current = quote!(#stripped: #ty).to_string();
130+
let fix = quote!(#stripped as #ty).to_string();
131+
132+
let message = format!(
133+
"
134+
\t\tType ascription pattern is deprecated, prefer casting
135+
\t\tTry changing from
136+
\t\t\t`{current}`
137+
\t\tto
138+
\t\t\t`{fix}`
139+
140+
\t\tSee <https://github.com/rust-lang/rfcs/pull/3307> for more information
141+
"
142+
);
143+
let name = Ident::new(&format!("warning_{name}"), span);
144+
quote_spanned!(span =>
145+
#[deprecated(note = #message)]
146+
#[allow(non_upper_case_globals)]
147+
const #name: () = ();
148+
let _ = #name;
149+
)
150+
}
151+
152+
fn get_type_override(expr: &Expr) -> Option<(&Type, bool)> {
118153
match expr {
119154
Expr::Group(group) => get_type_override(&group.expr),
120-
Expr::Cast(cast) => Some(&cast.ty),
121-
Expr::Type(ascription) => Some(&ascription.ty),
155+
Expr::Cast(cast) => Some((&cast.ty, false)),
156+
Expr::Type(ascription) => Some((&ascription.ty, true)),
122157
_ => None,
123158
}
124159
}

0 commit comments

Comments
 (0)