diff --git a/diesel_compile_tests/tests/fail/derive/bad_insertable.stderr b/diesel_compile_tests/tests/fail/derive/bad_insertable.stderr index da908ef0f94b..34d625522c72 100644 --- a/diesel_compile_tests/tests/fail/derive/bad_insertable.stderr +++ b/diesel_compile_tests/tests/fail/derive/bad_insertable.stderr @@ -79,6 +79,9 @@ error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied error[E0277]: the trait bound `std::string::String: diesel::Expression` is not satisfied --> tests/fail/derive/bad_insertable.rs:12:5 | +10 | #[derive(Insertable)] + | ---------- in this derive macro expansion +11 | struct User { 12 | id: String, | ^^ the trait `diesel::Expression` is not implemented for `std::string::String`, which is required by `std::string::String: AsExpression` | @@ -93,10 +96,14 @@ error[E0277]: the trait bound `std::string::String: diesel::Expression` is not s (T0, T1, T2, T3, T4, T5, T6, T7) and $N others = note: required for `std::string::String` to implement `AsExpression` + = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied --> tests/fail/derive/bad_insertable.rs:13:5 | +10 | #[derive(Insertable)] + | ---------- in this derive macro expansion +... 13 | name: i32, | ^^^^ the trait `diesel::Expression` is not implemented for `i32`, which is required by `i32: AsExpression` | @@ -111,10 +118,14 @@ error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied (T0, T1, T2, T3, T4, T5, T6, T7) and $N others = note: required for `i32` to implement `AsExpression` + = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `std::string::String: diesel::Expression` is not satisfied --> tests/fail/derive/bad_insertable.rs:12:5 | +10 | #[derive(Insertable)] + | ---------- in this derive macro expansion +11 | struct User { 12 | id: String, | ^^ the trait `diesel::Expression` is not implemented for `std::string::String`, which is required by `&'insert std::string::String: AsExpression` | @@ -130,10 +141,14 @@ error[E0277]: the trait bound `std::string::String: diesel::Expression` is not s and $N others = note: required for `&'insert std::string::String` to implement `diesel::Expression` = note: required for `&'insert std::string::String` to implement `AsExpression` + = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied --> tests/fail/derive/bad_insertable.rs:13:5 | +10 | #[derive(Insertable)] + | ---------- in this derive macro expansion +... 13 | name: i32, | ^^^^ the trait `diesel::Expression` is not implemented for `i32`, which is required by `&'insert i32: AsExpression` | @@ -149,3 +164,4 @@ error[E0277]: the trait bound `i32: diesel::Expression` is not satisfied and $N others = note: required for `&'insert i32` to implement `diesel::Expression` = note: required for `&'insert i32` to implement `AsExpression` + = note: this error originates in the derive macro `Insertable` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/diesel_derives/src/as_changeset.rs b/diesel_derives/src/as_changeset.rs index 44ba64c6cb04..52ad7dc5b398 100644 --- a/diesel_derives/src/as_changeset.rs +++ b/diesel_derives/src/as_changeset.rs @@ -1,4 +1,4 @@ -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::{quote, quote_spanned}; use syn::spanned::Spanned as _; use syn::{parse_quote, DeriveInput, Expr, Path, Result, Type}; @@ -27,7 +27,7 @@ pub fn derive(item: DeriveInput) -> Result { if fields_for_update.is_empty() { return Err(syn::Error::new( - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), "Deriving `AsChangeset` on a structure that only contains primary keys isn't supported.\n\ help: If you want to change the primary key of a row, you should do so with `.set(table::id.eq(new_id))`.\n\ note: `#[derive(AsChangeset)]` never changes the primary key of a row." @@ -172,7 +172,7 @@ pub fn derive(item: DeriveInput) -> Result { fn field_changeset_ty_embed(field: &Field, lifetime: Option) -> TokenStream { let field_ty = &field.ty; - let span = field.span; + let span = Span::mixed_site().located_at(field.span); quote_spanned!(span=> #lifetime #field_ty) } diff --git a/diesel_derives/src/as_expression.rs b/diesel_derives/src/as_expression.rs index 19f133416dab..16fe19686a5c 100644 --- a/diesel_derives/src/as_expression.rs +++ b/diesel_derives/src/as_expression.rs @@ -12,7 +12,7 @@ pub fn derive(item: DeriveInput) -> Result { if model.sql_types.is_empty() { return Err(syn::Error::new( - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), "At least one `sql_type` is needed for deriving `AsExpression` on a structure.", )); } diff --git a/diesel_derives/src/associations.rs b/diesel_derives/src/associations.rs index 6dd7d00b9f8a..65be4cf481b9 100644 --- a/diesel_derives/src/associations.rs +++ b/diesel_derives/src/associations.rs @@ -13,7 +13,7 @@ pub fn derive(item: DeriveInput) -> Result { if model.belongs_to.is_empty() { return Err(syn::Error::new( - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), "At least one `belongs_to` is needed for deriving `Associations` on a structure.", )); } diff --git a/diesel_derives/src/field.rs b/diesel_derives/src/field.rs index 492bc9f5cfcb..a3cf11f909e2 100644 --- a/diesel_derives/src/field.rs +++ b/diesel_derives/src/field.rs @@ -119,10 +119,10 @@ impl Field { None => FieldName::Unnamed(index.into()), }; - let span = match name { + let span = Span::mixed_site().located_at(match name { FieldName::Named(ref ident) => ident.span(), FieldName::Unnamed(_) => ty.span(), - }; + }); Ok(Self { ty: ty.clone(), diff --git a/diesel_derives/src/insertable.rs b/diesel_derives/src/insertable.rs index 44af578a38d4..16623dce4158 100644 --- a/diesel_derives/src/insertable.rs +++ b/diesel_derives/src/insertable.rs @@ -2,7 +2,7 @@ use crate::attrs::AttributeSpanWrapper; use crate::field::Field; use crate::model::Model; use crate::util::{inner_of_option_ty, is_option_ty, wrap_in_dummy_mod}; -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::quote; use quote::quote_spanned; use syn::parse_quote; @@ -177,7 +177,7 @@ fn derive_into_single_table( fn field_ty_embed(field: &Field, lifetime: Option) -> TokenStream { let field_ty = &field.ty; - let span = field.span; + let span = Span::mixed_site().located_at(field.span); quote_spanned!(span=> #lifetime #field_ty) } @@ -193,7 +193,7 @@ fn field_ty_serialize_as( treat_none_as_default_value: bool, ) -> Result { let column_name = field.column_name()?.to_ident()?; - let span = field.span; + let span = Span::mixed_site().located_at(field.span); if treat_none_as_default_value { let inner_ty = inner_of_option_ty(ty); @@ -242,7 +242,7 @@ fn field_ty( treat_none_as_default_value: bool, ) -> Result { let column_name = field.column_name()?.to_ident()?; - let span = field.span; + let span = Span::mixed_site().located_at(field.span); if treat_none_as_default_value { let inner_ty = inner_of_option_ty(&field.ty); diff --git a/diesel_derives/src/model.rs b/diesel_derives/src/model.rs index d6f72520faef..6820741ada8f 100644 --- a/diesel_derives/src/model.rs +++ b/diesel_derives/src/model.rs @@ -52,7 +52,7 @@ impl Model { }) => Some(unnamed), _ if !allow_unit_structs => { return Err(syn::Error::new( - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), "This derive can only be used on non-unit structs", )); } @@ -60,7 +60,7 @@ impl Model { }; let mut table_names = vec![]; - let mut primary_key_names = vec![Ident::new("id", Span::call_site())]; + let mut primary_key_names = vec![Ident::new("id", Span::mixed_site())]; let mut treat_none_as_default_value = None; let mut treat_none_as_null = None; let mut belongs_to = vec![]; diff --git a/diesel_derives/src/queryable.rs b/diesel_derives/src/queryable.rs index 72903241dedf..f8312854272a 100644 --- a/diesel_derives/src/queryable.rs +++ b/diesel_derives/src/queryable.rs @@ -22,7 +22,7 @@ pub fn derive(item: DeriveInput) -> Result { }); let sql_type = &(0..model.fields().len()) .map(|i| { - let i = Ident::new(&format!("__ST{i}"), Span::call_site()); + let i = Ident::new(&format!("__ST{i}"), Span::mixed_site()); quote!(#i) }) .collect::>(); @@ -33,7 +33,7 @@ pub fn derive(item: DeriveInput) -> Result { .params .push(parse_quote!(__DB: diesel::backend::Backend)); for id in 0..model.fields().len() { - let ident = Ident::new(&format!("__ST{id}"), Span::call_site()); + let ident = Ident::new(&format!("__ST{id}"), Span::mixed_site()); generics.params.push(parse_quote!(#ident)); } { diff --git a/diesel_derives/src/queryable_by_name.rs b/diesel_derives/src/queryable_by_name.rs index 7848e20ed58c..8eddd6bf2e51 100644 --- a/diesel_derives/src/queryable_by_name.rs +++ b/diesel_derives/src/queryable_by_name.rs @@ -1,4 +1,4 @@ -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::{parse_quote, parse_quote_spanned, DeriveInput, Ident, LitStr, Result, Type}; @@ -45,7 +45,7 @@ pub fn derive(item: DeriveInput) -> Result { for field in model.fields() { let where_clause = generics.where_clause.get_or_insert(parse_quote!(where)); - let span = field.span; + let span = Span::mixed_site().located_at(field.span); let field_ty = field.ty_for_deserialize(); if field.embed() { where_clause @@ -63,7 +63,7 @@ pub fn derive(item: DeriveInput) -> Result { let field_check_bound = model.fields().iter().filter(|f| !f.embed()).flat_map(|f| { backends.iter().map(move |b| { let field_ty = f.ty_for_deserialize(); - let span = f.span; + let span = Span::mixed_site().located_at(f.span); let ty = sql_type(f, model).unwrap(); quote::quote_spanned! {span => #field_ty: diesel::deserialize::FromSqlRow<#ty, #b> diff --git a/diesel_derives/src/selectable.rs b/diesel_derives/src/selectable.rs index 7f85863b1121..0559320d2c08 100644 --- a/diesel_derives/src/selectable.rs +++ b/diesel_derives/src/selectable.rs @@ -1,4 +1,4 @@ -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::spanned::Spanned; use syn::DeriveInput; @@ -51,7 +51,7 @@ pub fn derive(item: DeriveInput) -> Result { .filter(|(f, _)| !f.embed()) .flat_map(|(f, ty)| { backends.iter().map(move |b| { - let span = f.ty.span(); + let span = Span::mixed_site().located_at(f.ty.span()); let field_ty = to_field_ty_bound(f.ty_for_deserialize())?; Ok(syn::parse_quote_spanned! {span => #field_ty: diesel::deserialize::FromSqlRow, #b> diff --git a/diesel_derives/src/sql_type.rs b/diesel_derives/src/sql_type.rs index 2e6f00d65464..e7a4e132383f 100644 --- a/diesel_derives/src/sql_type.rs +++ b/diesel_derives/src/sql_type.rs @@ -41,7 +41,7 @@ fn sqlite_tokens(item: &DeriveInput, model: &Model) -> Option { model .sqlite_type .as_ref() - .map(|sqlite_type| Ident::new(&sqlite_type.name.value(), Span::call_site())) + .map(|sqlite_type| Ident::new(&sqlite_type.name.value(), Span::mixed_site())) .and_then(|ty| { if cfg!(not(feature = "sqlite")) { return None; @@ -67,7 +67,7 @@ fn mysql_tokens(item: &DeriveInput, model: &Model) -> Option { model .mysql_type .as_ref() - .map(|mysql_type| Ident::new(&mysql_type.name.value(), Span::call_site())) + .map(|mysql_type| Ident::new(&mysql_type.name.value(), Span::mixed_site())) .and_then(|ty| { if cfg!(not(feature = "mysql")) { return None; diff --git a/diesel_derives/src/table.rs b/diesel_derives/src/table.rs index 90ee6d161290..c89dcce06b48 100644 --- a/diesel_derives/src/table.rs +++ b/diesel_derives/src/table.rs @@ -1,5 +1,5 @@ use diesel_table_macro_syntax::{ColumnDef, TableDecl}; -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; use syn::parse_quote; use syn::Ident; @@ -46,10 +46,10 @@ pub(crate) fn expand(input: TableDecl) -> TokenStream { let primary_key: TokenStream = match input.primary_keys.as_ref() { None if column_names.contains(&&syn::Ident::new( DEFAULT_PRIMARY_KEY_NAME, - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), )) => { - let id = syn::Ident::new(DEFAULT_PRIMARY_KEY_NAME, proc_macro2::Span::call_site()); + let id = syn::Ident::new(DEFAULT_PRIMARY_KEY_NAME, proc_macro2::Span::mixed_site()); parse_quote! { #id } @@ -76,7 +76,7 @@ pub(crate) fn expand(input: TableDecl) -> TokenStream { } message += "\t}\n}"; - let span = input.table_name.span(); + let span = Span::mixed_site().located_at(input.table_name.span()); return quote::quote_spanned! {span=> compile_error!(#message); }; @@ -129,7 +129,7 @@ pub(crate) fn expand(input: TableDecl) -> TokenStream { let reexport_column_from_dsl = input.column_defs.iter().map(|c| { let column_name = &c.column_name; if c.column_name == *table_name { - let span = c.column_name.span(); + let span = Span::mixed_site().located_at(c.column_name.span()); let message = format!( "Column `{column_name}` cannot be named the same as it's table.\n\ You may use `#[sql_name = \"{column_name}\"]` to reference the table's \ @@ -527,15 +527,15 @@ fn generate_valid_grouping_for_table_columns(table: &TableDecl) -> Vec TokenStream { fn expand_column_def(column_def: &ColumnDef) -> TokenStream { // TODO get a better span here as soon as that's // possible using stable rust - let span = column_def.column_name.span(); + let span = Span::mixed_site().located_at(column_def.column_name.span()); let meta = &column_def.meta; let column_name = &column_def.column_name; let sql_name = &column_def.sql_name; diff --git a/diesel_derives/src/util.rs b/diesel_derives/src/util.rs index 3fb06b246435..1c5243258163 100644 --- a/diesel_derives/src/util.rs +++ b/diesel_derives/src/util.rs @@ -93,7 +93,8 @@ where } pub fn wrap_in_dummy_mod(item: TokenStream) -> TokenStream { - // #[allow(unused_qualifications)] can be removed if https://github.com/rust-lang/rust/issues/130277 gets done + // allow(unused_qualifications) is here as it hard to unsure the span is correctly set. Should stay until it is + // checked by CI. See https://github.com/rust-lang/rust/issues/130277 for more details. quote! { #[allow(unused_imports)] #[allow(unused_qualifications)] @@ -154,12 +155,12 @@ pub fn ty_for_foreign_derive(item: &DeriveInput, model: &Model) -> Result Data::Struct(ref body) => match body.fields.iter().next() { Some(field) => Ok(field.ty.clone()), None => Err(syn::Error::new( - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), "foreign_derive requires at least one field", )), }, _ => Err(syn::Error::new( - proc_macro2::Span::call_site(), + proc_macro2::Span::mixed_site(), "foreign_derive can only be used with structs", )), } diff --git a/dsl_auto_type/src/auto_type/mod.rs b/dsl_auto_type/src/auto_type/mod.rs index 0cc8a20384cb..098bdc4452e9 100644 --- a/dsl_auto_type/src/auto_type/mod.rs +++ b/dsl_auto_type/src/auto_type/mod.rs @@ -66,7 +66,7 @@ pub(crate) fn auto_type_impl( (false, true, _) => false, (true, true, _) => { return Err(syn::Error::new( - Span::call_site(), + Span::mixed_site(), "type_alias and no_type_alias are mutually exclusive", ) .into())