diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 4cac7cb93f581..9dac7a8aaf428 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -75,8 +75,10 @@ builtin_macros_autodiff_mode = unknown Mode: `{$mode}`. Use `Forward` or `Revers builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode builtin_macros_autodiff_not_build = this rustc version does not support autodiff builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} +builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode builtin_macros_autodiff_ty_activity = {$act} can not be used for this type + builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s .label = not applicable here diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6d9c35756574e..6707ab8edde9f 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -8,7 +8,8 @@ mod llvm_enzyme { use std::string::String; use rustc_ast::expand::autodiff_attrs::{ - AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ty_for_activity, + AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, + valid_ty_for_activity, }; use rustc_ast::ptr::P; use rustc_ast::token::{Token, TokenKind}; @@ -632,10 +633,22 @@ mod llvm_enzyme { errors = true; } } + + if has_ret && !valid_ret_activity(x.mode, x.ret_activity) { + dcx.emit_err(errors::AutoDiffInvalidRetAct { + span, + mode: x.mode.to_string(), + act: x.ret_activity.to_string(), + }); + // We don't set `errors = true` to avoid annoying type errors relative + // to the expanded macro type signature + } + if errors { // This is not the right signature, but we can continue parsing. return (sig.clone(), new_inputs, idents, true); } + let unsafe_activities = x .input_activity .iter() diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index ab1e0d8ee896b..30597944124cb 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -185,6 +185,15 @@ mod autodiff { pub(crate) act: String, } + #[derive(Diagnostic)] + #[diag(builtin_macros_autodiff_ret_activity)] + pub(crate) struct AutoDiffInvalidRetAct { + #[primary_span] + pub(crate) span: Span, + pub(crate) mode: String, + pub(crate) act: String, + } + #[derive(Diagnostic)] #[diag(builtin_macros_autodiff_mode)] pub(crate) struct AutoDiffInvalidMode { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 673740b4aab9f..a01f5d372a2da 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,9 +1,7 @@ use std::str::FromStr; use rustc_abi::ExternAbi; -use rustc_ast::expand::autodiff_attrs::{ - AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity, -}; +use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; use rustc_ast::{MetaItem, MetaItemInner, attr}; use rustc_attr_parsing::ReprAttr::ReprAlign; use rustc_attr_parsing::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr}; @@ -930,15 +928,6 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { } } - for &input in &arg_activities { - if !valid_input_activity(mode, input) { - span_bug!(attr.span(), "Invalid input activity {} for {} mode", input, mode); - } - } - if !valid_ret_activity(mode, ret_activity) { - span_bug!(attr.span(), "Invalid return activity {} for {} mode", ret_activity, mode); - } - Some(AutoDiffAttrs { mode, ret_activity, input_activity: arg_activities }) } diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs index c0548d2bbb8ff..638ba16c5c966 100644 --- a/tests/ui/autodiff/autodiff_illegal.rs +++ b/tests/ui/autodiff/autodiff_illegal.rs @@ -12,41 +12,40 @@ use std::autodiff::autodiff; // We can't use Duplicated on scalars #[autodiff(df1, Reverse, Duplicated)] pub fn f1(x: f64) { -//~^ ERROR Duplicated can not be used for this type + //~^ ERROR Duplicated can not be used for this type unimplemented!() } // Too many activities #[autodiff(df3, Reverse, Duplicated, Const)] pub fn f3(x: f64) { -//~^^ ERROR expected 1 activities, but found 2 + //~^^ ERROR expected 1 activities, but found 2 unimplemented!() } // To few activities #[autodiff(df4, Reverse)] pub fn f4(x: f64) { -//~^^ ERROR expected 1 activities, but found 0 + //~^^ ERROR expected 1 activities, but found 0 unimplemented!() } // We can't use Dual in Reverse mode #[autodiff(df5, Reverse, Dual)] pub fn f5(x: f64) { -//~^^ ERROR Dual can not be used in Reverse Mode + //~^^ ERROR Dual can not be used in Reverse Mode unimplemented!() } // We can't use Duplicated in Forward mode #[autodiff(df6, Forward, Duplicated)] pub fn f6(x: f64) { -//~^^ ERROR Duplicated can not be used in Forward Mode -//~^^ ERROR Duplicated can not be used for this type + //~^^ ERROR Duplicated can not be used in Forward Mode + //~^^ ERROR Duplicated can not be used for this type unimplemented!() } fn dummy() { - #[autodiff(df7, Forward, Dual)] let mut x = 5; //~^ ERROR autodiff must be applied to function @@ -64,21 +63,21 @@ fn dummy() { // Malformed, where args? #[autodiff] pub fn f7(x: f64) { -//~^ ERROR autodiff must be applied to function + //~^ ERROR autodiff must be applied to function unimplemented!() } // Malformed, where args? #[autodiff()] pub fn f8(x: f64) { -//~^ ERROR autodiff requires at least a name and mode + //~^ ERROR autodiff requires at least a name and mode unimplemented!() } // Invalid attribute syntax #[autodiff = ""] pub fn f9(x: f64) { -//~^ ERROR autodiff must be applied to function + //~^ ERROR autodiff must be applied to function unimplemented!() } @@ -87,21 +86,25 @@ fn fn_exists() {} // We colide with an already existing function #[autodiff(fn_exists, Reverse, Active)] pub fn f10(x: f64) { +<<<<<<< HEAD +======= //~^^ ERROR the name `fn_exists` is defined multiple times [E0428] +>>>>>>> 465e6968091de8a29af3d5315c8517b264c7df64 + //~^^ ERROR the name `fn_exists` is defined multiple times [E0428] unimplemented!() } // Malformed, missing a mode #[autodiff(df11)] pub fn f11() { -//~^ ERROR autodiff requires at least a name and mode + //~^ ERROR autodiff requires at least a name and mode unimplemented!() } // Invalid Mode #[autodiff(df12, Debug)] pub fn f12() { -//~^^ ERROR unknown Mode: `Debug`. Use `Forward` or `Reverse` + //~^^ ERROR unknown Mode: `Debug`. Use `Forward` or `Reverse` unimplemented!() } @@ -109,7 +112,7 @@ pub fn f12() { // or use two autodiff macros. #[autodiff(df13, Forward, Reverse)] pub fn f13() { -//~^^ ERROR did not recognize Activity: `Reverse` + //~^^ ERROR did not recognize Activity: `Reverse` unimplemented!() } @@ -130,7 +133,7 @@ type MyFloat = f32; // like THIR which has type information available. #[autodiff(df15, Reverse, Active, Active)] fn f15(x: MyFloat) -> f32 { -//~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] + //~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] unimplemented!() } @@ -141,7 +144,9 @@ fn f16(x: f32) -> MyFloat { } #[repr(transparent)] -struct F64Trans { inner: f64 } +struct F64Trans { + inner: f64, +} // We would like to support `#[repr(transparent)]` f32/f64 wrapper in return type in the future #[autodiff(df17, Reverse, Active, Active)] @@ -156,5 +161,24 @@ fn f18(x: F64Trans) -> f64 { unimplemented!() } +// Invalid return activity +#[autodiff(df19, Forward, Dual, Active)] +fn f19(x: f32) -> f32 { + //~^^ ERROR invalid return activity Active in Forward Mode + unimplemented!() +} + +#[autodiff(df20, Reverse, Active, Dual)] +fn f20(x: f32) -> f32 { + //~^^ ERROR invalid return activity Dual in Reverse Mode + unimplemented!() +} + +// Duplicated cannot be used as return activity +#[autodiff(df21, Reverse, Active, Duplicated)] +fn f21(x: f32) -> f32 { + //~^^ ERROR invalid return activity Duplicated in Reverse Mode + unimplemented!() +} fn main() {} diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr index 3a7242b2f5d95..610c4d8e6b20e 100644 --- a/tests/ui/autodiff/autodiff_illegal.stderr +++ b/tests/ui/autodiff/autodiff_illegal.stderr @@ -1,152 +1,22 @@ -error[E0658]: attributes on expressions are experimental - --> $DIR/autodiff_illegal.rs:54:5 - | -LL | #[autodiff(df7, Forward, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #15701 for more information - = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: Duplicated can not be used for this type - --> $DIR/autodiff_illegal.rs:14:14 - | -LL | pub fn f1(x: f64) { - | ^^^ - -error: expected 1 activities, but found 2 - --> $DIR/autodiff_illegal.rs:20:1 - | -LL | #[autodiff(df3, Reverse, Duplicated, Const)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: expected 1 activities, but found 0 - --> $DIR/autodiff_illegal.rs:27:1 - | -LL | #[autodiff(df4, Reverse)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: Dual can not be used in Reverse Mode - --> $DIR/autodiff_illegal.rs:34:1 - | -LL | #[autodiff(df5, Reverse, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: Duplicated can not be used in Forward Mode - --> $DIR/autodiff_illegal.rs:41:1 - | -LL | #[autodiff(df6, Forward, Duplicated)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: Duplicated can not be used for this type - --> $DIR/autodiff_illegal.rs:42:14 - | -LL | pub fn f6(x: f64) { - | ^^^ - -error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:51:5 - | -LL | let mut x = 5; - | ^^^^^^^^^^^^^^ - -error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:55:5 - | -LL | x = x + 3; - | ^ - -error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:60:5 - | -LL | let add_one_v2 = |x: u32| -> u32 { x + 1 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:66:1 - | -LL | / pub fn f7(x: f64) { -LL | | -LL | | unimplemented!() -LL | | } - | |_^ - -error: autodiff requires at least a name and mode - --> $DIR/autodiff_illegal.rs:73:1 - | -LL | / pub fn f8(x: f64) { -LL | | -LL | | unimplemented!() -LL | | } - | |_^ - -error: autodiff must be applied to function - --> $DIR/autodiff_illegal.rs:80:1 - | -LL | / pub fn f9(x: f64) { -LL | | -LL | | unimplemented!() -LL | | } - | |_^ - -error[E0428]: the name `fn_exists` is defined multiple times - --> $DIR/autodiff_illegal.rs:88:1 - | -LL | fn fn_exists() {} - | -------------- previous definition of the value `fn_exists` here -... -LL | #[autodiff(fn_exists, Reverse, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fn_exists` redefined here - | - = note: `fn_exists` must be defined only once in the value namespace of this module - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: autodiff requires at least a name and mode - --> $DIR/autodiff_illegal.rs:96:1 - | -LL | / pub fn f11() { -LL | | -LL | | unimplemented!() -LL | | } - | |_^ - -error: unknown Mode: `Debug`. Use `Forward` or `Reverse` - --> $DIR/autodiff_illegal.rs:102:18 - | -LL | #[autodiff(df12, Debug)] - | ^^^^^ - -error: did not recognize Activity: `Reverse` - --> $DIR/autodiff_illegal.rs:110:27 - | -LL | #[autodiff(df13, Forward, Reverse)] - | ^^^^^^^ - -error[E0433]: failed to resolve: use of undeclared type `MyFloat` - --> $DIR/autodiff_illegal.rs:131:1 - | -LL | #[autodiff(df15, Reverse, Active, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat` - | - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0433]: failed to resolve: use of undeclared type `F64Trans` - --> $DIR/autodiff_illegal.rs:153:1 - | -LL | #[autodiff(df18, Reverse, Active, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans` - | - = note: this error originates in the attribute macro `autodiff` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 19 previous errors +error: encountered diff marker + --> $DIR/autodiff_illegal.rs:89:1 + | +LL | <<<<<<< HEAD + | ^^^^^^^ between this marker and `=======` is the code that we're merging into +LL | ======= + | ------- between this marker and `>>>>>>>` is the incoming code +LL | +LL | >>>>>>> 465e6968091de8a29af3d5315c8517b264c7df64 + | ^^^^^^^ this marker concludes the conflict region + | + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit + +error: aborting due to 1 previous error -Some errors have detailed explanations: E0428, E0433, E0658. -For more information about an error, try `rustc --explain E0428`.