Skip to content

chore: add deprecation notice for type ascription use #2483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions sqlx-macros-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
feature(track_path)
)]

use once_cell::sync::Lazy;

use crate::query::QueryDriver;

pub type Error = Box<dyn std::error::Error>;
Expand Down Expand Up @@ -54,6 +52,7 @@ where
{
#[cfg(feature = "_rt-tokio")]
{
use once_cell::sync::Lazy;
use tokio::runtime::{self, Runtime};

// We need a single, persistent Tokio runtime since we're caching connections,
Expand Down
45 changes: 39 additions & 6 deletions sqlx-macros-core/src/query/args.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::database::DatabaseExt;
use crate::query::QueryMacroInput;
use either::Either;
use proc_macro2::TokenStream;
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote, quote_spanned};
use sqlx_core::describe::Describe;
use syn::spanned::Spanned;
Expand Down Expand Up @@ -50,9 +50,11 @@ pub fn quote_args<DB: DatabaseExt>(
.enumerate()
.map(|(i, (param_ty, (name, expr)))| -> crate::Result<_> {
let param_ty = match get_type_override(expr) {
// cast or type ascription will fail to compile if the type does not match
// cast will fail to compile if the type does not match
// and we strip casts to wildcard
Some(_) => return Ok(quote!()),
Some((_, false)) => return Ok(quote!()),
// type ascription is deprecated
Some((ty, true)) => return Ok(create_warning(name.clone(), &ty, &expr)),
None => {
DB::param_type_for_id(&param_ty)
.ok_or_else(|| {
Expand Down Expand Up @@ -114,11 +116,42 @@ pub fn quote_args<DB: DatabaseExt>(
})
}

fn get_type_override(expr: &Expr) -> Option<&Type> {
fn create_warning(name: Ident, ty: &Type, expr: &Expr) -> TokenStream {
let Expr::Type(ExprType { expr: stripped, .. }) = expr else {
return quote!();
};
let current = quote!(#stripped: #ty).to_string();
let fix = quote!(#stripped as #ty).to_string();
let name = Ident::new(&format!("warning_{name}"), expr.span());

let message = format!(
"
\t\tType ascription pattern is deprecated, prefer casting
\t\tTry changing from
\t\t\t`{current}`
\t\tto
\t\t\t`{fix}`

\t\tSee <https://github.com/rust-lang/rfcs/pull/3307> for more information
"
);

quote_spanned!(expr.span() =>
// this shouldn't actually run
if false {
#[deprecated(note = #message)]
#[allow(non_upper_case_globals)]
const #name: () = ();
let _ = #name;
}
)
}

fn get_type_override(expr: &Expr) -> Option<(&Type, bool)> {
match expr {
Expr::Group(group) => get_type_override(&group.expr),
Expr::Cast(cast) => Some(&cast.ty),
Expr::Type(ascription) => Some(&ascription.ty),
Expr::Cast(cast) => Some((&cast.ty, false)),
Expr::Type(ascription) => Some((&ascription.ty, true)),
_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion sqlx-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ sqlx-core = { workspace = true, default-features = false, features = ["any"] }
sqlx-macros-core = { workspace = true }

proc-macro2 = { version = "1.0.36", default-features = false }
syn = { version = "1.0.84", default-features = false, features = ["full"] }
syn = { version = "1.0.84", default-features = false, features = ["parsing", "proc-macro"] }
quote = { version = "1.0.14", default-features = false }
9 changes: 6 additions & 3 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,12 @@
/// sqlx::query!("select $1::int4 as id", my_int as MyInt4)
/// ```
///
/// Using `expr as _` or `expr : _` simply signals to the macro to not type-check that bind expression,
/// and then that syntax is stripped from the expression so as to not trigger type errors
/// (or an unstable syntax feature in the case of the latter, which is called type ascription).
/// Using `expr as _` simply signals to the macro to not type-check that bind expression,
/// and then that syntax is stripped from the expression so as to not trigger type errors.
///
/// **NOTE:** type ascription syntax (`expr: _`) is deprecated and will be removed in a
/// future release. This is due to Rust's [RFC 3307](https://github.com/rust-lang/rfcs/pull/3307)
/// officially dropping support for the syntax.
///
/// ## Type Overrides: Output Columns
/// Type overrides are also available for output columns, utilizing the SQL standard's support
Expand Down