Skip to content

Commit

Permalink
make CoercePointee errors translatable
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Dec 2, 2024
1 parent 32eea2f commit 7028bd6
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 48 deletions.
15 changes: 15 additions & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,21 @@ builtin_macros_cfg_accessible_indeterminate = cannot determine whether the path
builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal
builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified
builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified
builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized`
builtin_macros_coerce_pointee_requires_one_field = `CoercePointee` can only be derived on `struct`s with at least one field
builtin_macros_coerce_pointee_requires_one_generic = `CoercePointee` can only be derived on `struct`s that are generic over at least one type
builtin_macros_coerce_pointee_requires_one_pointee = exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
builtin_macros_coerce_pointee_requires_transparent = `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
builtin_macros_coerce_pointee_too_many_pointees = only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
.label = here another type parameter is marked as `#[pointee]`
builtin_macros_concat_bytes_array = cannot concatenate doubly nested array
.note = byte strings are treated as arrays of bytes
.help = try flattening the array
Expand Down
97 changes: 56 additions & 41 deletions compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_ast::{
use rustc_attr as attr;
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_macros::Diagnostic;
use rustc_span::symbol::{Ident, sym};
use rustc_span::{Span, Symbol};
use thin_vec::{ThinVec, thin_vec};
Expand Down Expand Up @@ -38,35 +39,20 @@ pub(crate) fn expand_deriving_coerce_pointee(
.any(|r| matches!(r, attr::ReprTransparent))
});
if !is_transparent {
cx.dcx()
.struct_span_err(
span,
"`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`",
)
.emit();
cx.dcx().emit_err(RequireTransparent { span });
return;
}
if !matches!(
struct_data,
VariantData::Struct { fields, recovered: _ } | VariantData::Tuple(fields, _)
if !fields.is_empty())
{
cx.dcx()
.struct_span_err(
span,
"`CoercePointee` can only be derived on `struct`s with at least one field",
)
.emit();
cx.dcx().emit_err(RequireOneField { span });
return;
}
(aitem.ident, g)
} else {
cx.dcx()
.struct_span_err(
span,
"`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`",
)
.emit();
cx.dcx().emit_err(RequireTransparent { span });
return;
};

Expand Down Expand Up @@ -95,10 +81,7 @@ pub(crate) fn expand_deriving_coerce_pointee(

let pointee_param_idx = if type_params.is_empty() {
// `#[derive(CoercePointee)]` requires at least one generic type on the target `struct`
cx.dcx().struct_span_err(
span,
"`CoercePointee` can only be derived on `struct`s that are generic over at least one type",
).emit();
cx.dcx().emit_err(RequireOneGeneric { span });
return;
} else if type_params.len() == 1 {
// Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such
Expand All @@ -111,19 +94,11 @@ pub(crate) fn expand_deriving_coerce_pointee(
match (pointees.next(), pointees.next()) {
(Some((idx, _span)), None) => idx,
(None, _) => {
cx.dcx().struct_span_err(
span,
"exactly one generic type parameter must be marked as #[pointee] to derive CoercePointee traits",
).emit();
cx.dcx().emit_err(RequireOnePointee { span });
return;
}
(Some((_, one)), Some((_, another))) => {
cx.dcx()
.struct_span_err(
vec![one, another],
"only one type parameter can be marked as `#[pointee]` when deriving CoercePointee traits",
)
.emit();
cx.dcx().emit_err(TooManyPointees { one, another });
return;
}
}
Expand Down Expand Up @@ -181,15 +156,10 @@ pub(crate) fn expand_deriving_coerce_pointee(
pointee_ty_ident.name,
)
{
cx.dcx()
.struct_span_err(
pointee_ty_ident.span,
format!(
"`derive(CoercePointee)` requires {} to be marked `?Sized`",
pointee_ty_ident.name
),
)
.emit();
cx.dcx().emit_err(RequiresMaybeSized {
span: pointee_ty_ident.span,
name: pointee_ty_ident.name.to_ident_string(),
});
return;
}
let arg = GenericArg::Type(s_ty.clone());
Expand Down Expand Up @@ -459,3 +429,48 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b>
}
}
}

#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_transparent)]
struct RequireTransparent {
#[primary_span]
span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_one_field)]
struct RequireOneField {
#[primary_span]
span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_one_generic)]
struct RequireOneGeneric {
#[primary_span]
span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_one_pointee)]
struct RequireOnePointee {
#[primary_span]
span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_too_many_pointees)]
struct TooManyPointees {
#[primary_span]
one: Span,
#[label]
another: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_maybe_sized)]
struct RequiresMaybeSized {
#[primary_span]
span: Span,
name: String,
}
6 changes: 3 additions & 3 deletions tests/ui/deriving/deriving-coerce-pointee-neg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
struct NoGeneric<'a>(&'a u8);

#[derive(CoercePointee)]
//~^ ERROR: exactly one generic type parameter must be marked as #[pointee] to derive CoercePointee traits
//~^ ERROR: exactly one generic type parameter must be marked as #[pointee] to derive `CoercePointee` traits
#[repr(transparent)]
struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
a: (&'a T1, &'a T2),
Expand All @@ -38,7 +38,7 @@ struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
#[derive(CoercePointee)]
#[repr(transparent)]
struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving CoercePointee traits
//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits

#[derive(CoercePointee)]
//~^ ERROR: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
Expand All @@ -49,7 +49,7 @@ struct NotTransparent<'a, #[pointee] T: ?Sized> {
#[derive(CoercePointee)]
#[repr(transparent)]
struct NoMaybeSized<'a, #[pointee] T> {
//~^ ERROR: `derive(CoercePointee)` requires T to be marked `?Sized`
//~^ ERROR: `derive(CoercePointee)` requires `T` to be marked `?Sized`
ptr: &'a T,
}

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/deriving/deriving-coerce-pointee-neg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ LL | #[derive(CoercePointee)]
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)

error: exactly one generic type parameter must be marked as #[pointee] to derive CoercePointee traits
error: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
--> $DIR/deriving-coerce-pointee-neg.rs:31:10
|
LL | #[derive(CoercePointee)]
| ^^^^^^^^^^^^^
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)

error: only one type parameter can be marked as `#[pointee]` when deriving CoercePointee traits
error: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
--> $DIR/deriving-coerce-pointee-neg.rs:40:39
|
LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
| ^ ^
| ^ - here another type parameter is marked as `#[pointee]`

error: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
--> $DIR/deriving-coerce-pointee-neg.rs:43:10
Expand All @@ -52,7 +52,7 @@ LL | #[derive(CoercePointee)]
|
= note: this error originates in the derive macro `CoercePointee` (in Nightly builds, run with -Z macro-backtrace for more info)

error: `derive(CoercePointee)` requires T to be marked `?Sized`
error: `derive(CoercePointee)` requires `T` to be marked `?Sized`
--> $DIR/deriving-coerce-pointee-neg.rs:51:36
|
LL | struct NoMaybeSized<'a, #[pointee] T> {
Expand Down

0 comments on commit 7028bd6

Please sign in to comment.