Skip to content

Commit

Permalink
chore: add deprecation notice for type ascription use (#2483)
Browse files Browse the repository at this point in the history
* chore: add deprecation notice for type ascription use

* docs: type ascription deprecation
  • Loading branch information
saiintbrisson authored May 4, 2023
1 parent 39acaf1 commit 4095ac4
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
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

0 comments on commit 4095ac4

Please sign in to comment.