From f92000816e0cf8bdfe6ad422464ce0fa6144b496 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Tue, 3 Jan 2023 14:08:20 +0100 Subject: [PATCH 1/3] Improve proc macro attribute diagnostics --- .../locales/en-US/passes.ftl | 21 +++ compiler/rustc_passes/src/check_attr.rs | 130 +++++++++++++++++- compiler/rustc_passes/src/errors.rs | 50 +++++++ compiler/rustc_span/src/symbol.rs | 1 + library/proc_macro/src/lib.rs | 1 + tests/ui/proc-macro/proc-macro-abi.rs | 28 ++++ tests/ui/proc-macro/proc-macro-abi.stderr | 20 +++ .../signature-proc-macro-attribute.rs | 29 ++++ .../signature-proc-macro-attribute.stderr | 42 ++++++ .../proc-macro/signature-proc-macro-derive.rs | 28 ++++ .../signature-proc-macro-derive.stderr | 40 ++++++ tests/ui/proc-macro/signature-proc-macro.rs | 28 ++++ .../ui/proc-macro/signature-proc-macro.stderr | 40 ++++++ tests/ui/proc-macro/signature.rs | 6 +- tests/ui/proc-macro/signature.stderr | 46 +++++-- 15 files changed, 488 insertions(+), 22 deletions(-) create mode 100644 tests/ui/proc-macro/proc-macro-abi.rs create mode 100644 tests/ui/proc-macro/proc-macro-abi.stderr create mode 100644 tests/ui/proc-macro/signature-proc-macro-attribute.rs create mode 100644 tests/ui/proc-macro/signature-proc-macro-attribute.stderr create mode 100644 tests/ui/proc-macro/signature-proc-macro-derive.rs create mode 100644 tests/ui/proc-macro/signature-proc-macro-derive.stderr create mode 100644 tests/ui/proc-macro/signature-proc-macro.rs create mode 100644 tests/ui/proc-macro/signature-proc-macro.stderr diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 001e53d1d0e4c..63db6b6837b47 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -707,3 +707,24 @@ passes_ignored_derived_impls = [one] trait {$trait_list}, but this is *[other] traits {$trait_list}, but these are } intentionally ignored during dead code analysis + +passes_proc_macro_typeerror = mismatched {$kind} signature + .label = found {$found}, expected type `proc_macro::TokenStream` + .note = {$kind}s must have a signature of `{$expected_signature}` + +passes_proc_macro_diff_arg_count = mismatched {$kind} signature + .label = found unexpected {$count -> + [one] argument + *[other] arguments + } + .note = {$kind}s must have a signature of `{$expected_signature}` + +passes_proc_macro_missing_args = mismatched {$kind} signature + .label = {$kind} must have {$expected_input_count -> + [one] one argument + *[other] two arguments + } of type `proc_macro::TokenStream` + +passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"` + +passes_proc_macro_unsafe = proc macro functions may not be `unsafe` diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c59c06ac31ed7..517bf2533c5e6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -6,11 +6,12 @@ use crate::errors::{ self, AttrApplication, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel, ObjectLifetimeErr, - OnlyHasEffectOn, TransparentIncompatible, UnrecognizedReprHint, + OnlyHasEffectOn, ProcMacroDiffArguments, ProcMacroInvalidAbi, ProcMacroMissingArguments, + ProcMacroTypeError, ProcMacroUnsafe, TransparentIncompatible, UnrecognizedReprHint, }; use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{fluent, Applicability, MultiSpan}; +use rustc_errors::{fluent, Applicability, IntoDiagnosticArg, MultiSpan}; use rustc_expand::base::resolve_path; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; @@ -19,11 +20,11 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID, }; -use rustc_hir::{MethodKind, Target}; +use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_session::lint::builtin::{ CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES, }; @@ -31,6 +32,7 @@ use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; +use std::cell::Cell; use std::collections::hash_map::Entry; pub(crate) fn target_from_impl_item<'tcx>( @@ -62,8 +64,27 @@ enum ItemLike<'tcx> { ForeignItem, } +#[derive(Copy, Clone)] +pub(crate) enum ProcMacroKind { + FunctionLike, + Derive, + Attribute, +} + +impl IntoDiagnosticArg for ProcMacroKind { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + match self { + ProcMacroKind::Attribute => "attribute proc macro", + ProcMacroKind::Derive => "derive proc macro", + ProcMacroKind::FunctionLike => "function-like proc macro", + } + .into_diagnostic_arg() + } +} + struct CheckAttrVisitor<'tcx> { tcx: TyCtxt<'tcx>, + abort: Cell, } impl CheckAttrVisitor<'_> { @@ -172,7 +193,7 @@ impl CheckAttrVisitor<'_> { sym::path => self.check_generic_attr(hir_id, attr, target, Target::Mod), sym::plugin_registrar => self.check_plugin_registrar(hir_id, attr, target), sym::macro_export => self.check_macro_export(hir_id, attr, target), - sym::ignore | sym::should_panic | sym::proc_macro_derive => { + sym::ignore | sym::should_panic => { self.check_generic_attr(hir_id, attr, target, Target::Fn) } sym::automatically_derived => { @@ -182,6 +203,16 @@ impl CheckAttrVisitor<'_> { self.check_generic_attr(hir_id, attr, target, Target::Mod) } sym::rustc_object_lifetime_default => self.check_object_lifetime_default(hir_id), + sym::proc_macro => { + self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) + } + sym::proc_macro_attribute => { + self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute); + } + sym::proc_macro_derive => { + self.check_generic_attr(hir_id, attr, target, Target::Fn); + self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) + } _ => {} } @@ -2052,6 +2083,90 @@ impl CheckAttrVisitor<'_> { errors::Unused { attr_span: attr.span, note }, ); } + + fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) { + let expected_input_count = match kind { + ProcMacroKind::Attribute => 2, + ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1, + }; + + let expected_signature = match kind { + ProcMacroKind::Attribute => "fn(TokenStream, TokenStream) -> TokenStream", + ProcMacroKind::Derive | ProcMacroKind::FunctionLike => "fn(TokenStream) -> TokenStream", + }; + + let tcx = self.tcx; + if target == Target::Fn { + let Some(tokenstream) = tcx.get_diagnostic_item(sym::TokenStream) else {return}; + let tokenstream = tcx.type_of(tokenstream); + + let id = hir_id.expect_owner(); + let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id).unwrap(); + + let sig = tcx.fn_sig(id); + + if sig.abi() != Abi::Rust { + tcx.sess + .emit_err(ProcMacroInvalidAbi { span: hir_sig.span, abi: sig.abi().name() }); + self.abort.set(true); + } + + if sig.unsafety() == Unsafety::Unsafe { + tcx.sess.emit_err(ProcMacroUnsafe { span: hir_sig.span }); + self.abort.set(true); + } + + let output = sig.output().skip_binder(); + + // Typecheck the output + if tcx.normalize_erasing_regions(ParamEnv::empty(), output) != tokenstream { + tcx.sess.emit_err(ProcMacroTypeError { + span: hir_sig.decl.output.span(), + found: output, + kind, + expected_signature, + }); + self.abort.set(true); + } + + // Typecheck "expected_input_count" inputs, emitting + // `ProcMacroMissingArguments` if there are not enough. + if let Some(args) = sig.inputs().skip_binder().get(0..expected_input_count) { + for (arg, input) in args.iter().zip(hir_sig.decl.inputs) { + if tcx.normalize_erasing_regions(ParamEnv::empty(), *arg) != tokenstream { + tcx.sess.emit_err(ProcMacroTypeError { + span: input.span, + found: *arg, + kind, + expected_signature, + }); + self.abort.set(true); + } + } + } else { + tcx.sess.emit_err(ProcMacroMissingArguments { + expected_input_count, + span: hir_sig.span, + kind, + expected_signature, + }); + self.abort.set(true); + } + + // Check that there are not too many arguments + let body_id = tcx.hir().body_owned_by(id.def_id); + let excess = tcx.hir().body(body_id).params.get(expected_input_count..); + if let Some(excess @ [begin @ end] | excess @ [begin, .., end]) = excess { + tcx.sess.emit_err(ProcMacroDiffArguments { + span: begin.span.to(end.span), + count: excess.len(), + kind, + expected_signature, + }); + self.abort.set(true); + } + } + } } impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { @@ -2214,12 +2329,15 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) } fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - let check_attr_visitor = &mut CheckAttrVisitor { tcx }; + let check_attr_visitor = &mut CheckAttrVisitor { tcx, abort: Cell::new(false) }; tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor); if module_def_id.is_top_level_module() { check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None); check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs()); } + if check_attr_visitor.abort.get() { + tcx.sess.abort_if_errors() + } } pub(crate) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index c6cd69add28a0..68103608ec9d9 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -12,6 +12,7 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{Span, Symbol, DUMMY_SP}; +use crate::check_attr::ProcMacroKind; use crate::lang_items::Duplicate; #[derive(LintDiagnostic)] @@ -1508,3 +1509,52 @@ pub struct ChangeFieldsToBeOfUnitType { #[suggestion_part(code = "()")] pub spans: Vec, } + +#[derive(Diagnostic)] +#[diag(passes_proc_macro_typeerror)] +#[note] +pub(crate) struct ProcMacroTypeError<'tcx> { + #[primary_span] + #[label] + pub span: Span, + pub found: Ty<'tcx>, + pub kind: ProcMacroKind, + pub expected_signature: &'static str, +} + +#[derive(Diagnostic)] +#[diag(passes_proc_macro_diff_arg_count)] +pub(crate) struct ProcMacroDiffArguments { + #[primary_span] + #[label] + pub span: Span, + pub count: usize, + pub kind: ProcMacroKind, + pub expected_signature: &'static str, +} + +#[derive(Diagnostic)] +#[diag(passes_proc_macro_missing_args)] +pub(crate) struct ProcMacroMissingArguments { + #[primary_span] + #[label] + pub span: Span, + pub expected_input_count: usize, + pub kind: ProcMacroKind, + pub expected_signature: &'static str, +} + +#[derive(Diagnostic)] +#[diag(passes_proc_macro_invalid_abi)] +pub(crate) struct ProcMacroInvalidAbi { + #[primary_span] + pub span: Span, + pub abi: &'static str, +} + +#[derive(Diagnostic)] +#[diag(passes_proc_macro_unsafe)] +pub(crate) struct ProcMacroUnsafe { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fbb12701d96ab..0cc9567d4d672 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -287,6 +287,7 @@ symbols! { Target, ToOwned, ToString, + TokenStream, Try, TryCaptureGeneric, TryCapturePrintable, diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index f0e4f5d8a8013..8bff40c279aaa 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -74,6 +74,7 @@ pub fn is_available() -> bool { /// /// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]` /// and `#[proc_macro_derive]` definitions. +#[rustc_diagnostic_item = "TokenStream"] #[stable(feature = "proc_macro_lib", since = "1.15.0")] #[derive(Clone)] pub struct TokenStream(Option); diff --git a/tests/ui/proc-macro/proc-macro-abi.rs b/tests/ui/proc-macro/proc-macro-abi.rs new file mode 100644 index 0000000000000..2a40ddd496ce8 --- /dev/null +++ b/tests/ui/proc-macro/proc-macro-abi.rs @@ -0,0 +1,28 @@ +#![crate_type = "proc-macro"] +#![allow(warnings)] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub extern "C" fn abi(a: TokenStream) -> TokenStream { + //~^ ERROR proc macro functions may not be `extern + a +} + +#[proc_macro] +pub extern "system" fn abi2(a: TokenStream) -> TokenStream { + //~^ ERROR proc macro functions may not be `extern + a +} + +#[proc_macro] +pub extern fn abi3(a: TokenStream) -> TokenStream { + //~^ ERROR proc macro functions may not be `extern + a +} + +#[proc_macro] +pub extern "Rust" fn abi4(a: TokenStream) -> TokenStream { + a +} diff --git a/tests/ui/proc-macro/proc-macro-abi.stderr b/tests/ui/proc-macro/proc-macro-abi.stderr new file mode 100644 index 0000000000000..fa5f5dc098998 --- /dev/null +++ b/tests/ui/proc-macro/proc-macro-abi.stderr @@ -0,0 +1,20 @@ +error: proc macro functions may not be `extern "C"` + --> $DIR/proc-macro-abi.rs:8:1 + | +LL | pub extern "C" fn abi(a: TokenStream) -> TokenStream { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: proc macro functions may not be `extern "system"` + --> $DIR/proc-macro-abi.rs:14:1 + | +LL | pub extern "system" fn abi2(a: TokenStream) -> TokenStream { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: proc macro functions may not be `extern "C"` + --> $DIR/proc-macro-abi.rs:20:1 + | +LL | pub extern fn abi3(a: TokenStream) -> TokenStream { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.rs b/tests/ui/proc-macro/signature-proc-macro-attribute.rs new file mode 100644 index 0000000000000..fb17710950106 --- /dev/null +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.rs @@ -0,0 +1,29 @@ +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn bad_input(input: String) -> TokenStream { + //~^ ERROR mismatched attribute proc macro signature + ::proc_macro::TokenStream::new() +} + +#[proc_macro_attribute] +pub fn bad_output(input: TokenStream) -> String { + //~^ ERROR mismatched attribute proc macro signature + //~| ERROR mismatched attribute proc macro signature + String::from("blah") +} + +#[proc_macro_attribute] +pub fn bad_everything(input: String) -> String { + //~^ ERROR mismatched attribute proc macro signature + //~| ERROR mismatched attribute proc macro signature + input +} + +#[proc_macro_attribute] +pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { + //~^ ERROR mismatched attribute proc macro signature +} diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr new file mode 100644 index 0000000000000..ecfd2b06e109c --- /dev/null +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr @@ -0,0 +1,42 @@ +error: mismatched attribute proc macro signature + --> $DIR/signature-proc-macro-attribute.rs:7:1 + | +LL | pub fn bad_input(input: String) -> TokenStream { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` + +error: mismatched attribute proc macro signature + --> $DIR/signature-proc-macro-attribute.rs:13:42 + | +LL | pub fn bad_output(input: TokenStream) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: attribute proc macros must have a signature of `fn(TokenStream, TokenStream) -> TokenStream` + +error: mismatched attribute proc macro signature + --> $DIR/signature-proc-macro-attribute.rs:13:1 + | +LL | pub fn bad_output(input: TokenStream) -> String { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` + +error: mismatched attribute proc macro signature + --> $DIR/signature-proc-macro-attribute.rs:20:41 + | +LL | pub fn bad_everything(input: String) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: attribute proc macros must have a signature of `fn(TokenStream, TokenStream) -> TokenStream` + +error: mismatched attribute proc macro signature + --> $DIR/signature-proc-macro-attribute.rs:20:1 + | +LL | pub fn bad_everything(input: String) -> String { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` + +error: mismatched attribute proc macro signature + --> $DIR/signature-proc-macro-attribute.rs:27:49 + | +LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { + | ^^^^^^^^^ found unexpected argument + +error: aborting due to 6 previous errors + diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.rs b/tests/ui/proc-macro/signature-proc-macro-derive.rs new file mode 100644 index 0000000000000..a079157538fb6 --- /dev/null +++ b/tests/ui/proc-macro/signature-proc-macro-derive.rs @@ -0,0 +1,28 @@ +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Blah)] +pub fn bad_input(input: String) -> TokenStream { + //~^ ERROR mismatched derive proc macro signature + TokenStream::new() +} + +#[proc_macro_derive(Bleh)] +pub fn bad_output(input: TokenStream) -> String { + //~^ ERROR mismatched derive proc macro signature + String::from("blah") +} + +#[proc_macro_derive(Bluh)] +pub fn bad_everything(input: String) -> String { + //~^ ERROR mismatched derive proc macro signature + //~| ERROR mismatched derive proc macro signature + input +} + +#[proc_macro_derive(Blih)] +pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { + //~^ ERROR mismatched derive proc macro signature +} diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.stderr b/tests/ui/proc-macro/signature-proc-macro-derive.stderr new file mode 100644 index 0000000000000..bb2bd9a93d24b --- /dev/null +++ b/tests/ui/proc-macro/signature-proc-macro-derive.stderr @@ -0,0 +1,40 @@ +error: mismatched derive proc macro signature + --> $DIR/signature-proc-macro-derive.rs:7:25 + | +LL | pub fn bad_input(input: String) -> TokenStream { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched derive proc macro signature + --> $DIR/signature-proc-macro-derive.rs:13:42 + | +LL | pub fn bad_output(input: TokenStream) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched derive proc macro signature + --> $DIR/signature-proc-macro-derive.rs:19:41 + | +LL | pub fn bad_everything(input: String) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched derive proc macro signature + --> $DIR/signature-proc-macro-derive.rs:19:30 + | +LL | pub fn bad_everything(input: String) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched derive proc macro signature + --> $DIR/signature-proc-macro-derive.rs:26:33 + | +LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ found unexpected arguments + +error: aborting due to 5 previous errors + diff --git a/tests/ui/proc-macro/signature-proc-macro.rs b/tests/ui/proc-macro/signature-proc-macro.rs new file mode 100644 index 0000000000000..35d5be2171283 --- /dev/null +++ b/tests/ui/proc-macro/signature-proc-macro.rs @@ -0,0 +1,28 @@ +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn bad_input(input: String) -> TokenStream { + //~^ ERROR mismatched function-like proc macro signature + ::proc_macro::TokenStream::new() +} + +#[proc_macro] +pub fn bad_output(input: TokenStream) -> String { + //~^ ERROR mismatched function-like proc macro signature + String::from("blah") +} + +#[proc_macro] +pub fn bad_everything(input: String) -> String { + //~^ ERROR mismatched function-like proc macro signature + //~| ERROR mismatched function-like proc macro signature + input +} + +#[proc_macro] +pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { + //~^ ERROR mismatched function-like proc macro signature +} diff --git a/tests/ui/proc-macro/signature-proc-macro.stderr b/tests/ui/proc-macro/signature-proc-macro.stderr new file mode 100644 index 0000000000000..32241e1b9e00a --- /dev/null +++ b/tests/ui/proc-macro/signature-proc-macro.stderr @@ -0,0 +1,40 @@ +error: mismatched function-like proc macro signature + --> $DIR/signature-proc-macro.rs:7:25 + | +LL | pub fn bad_input(input: String) -> TokenStream { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched function-like proc macro signature + --> $DIR/signature-proc-macro.rs:13:42 + | +LL | pub fn bad_output(input: TokenStream) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched function-like proc macro signature + --> $DIR/signature-proc-macro.rs:19:41 + | +LL | pub fn bad_everything(input: String) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched function-like proc macro signature + --> $DIR/signature-proc-macro.rs:19:30 + | +LL | pub fn bad_everything(input: String) -> String { + | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` + | + = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched function-like proc macro signature + --> $DIR/signature-proc-macro.rs:26:33 + | +LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ found unexpected arguments + +error: aborting due to 5 previous errors + diff --git a/tests/ui/proc-macro/signature.rs b/tests/ui/proc-macro/signature.rs index 2302238253e82..11187aa31bd80 100644 --- a/tests/ui/proc-macro/signature.rs +++ b/tests/ui/proc-macro/signature.rs @@ -8,6 +8,10 @@ extern crate proc_macro; #[proc_macro_derive(A)] pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { - //~^ ERROR: expected a `Fn<(proc_macro::TokenStream,)>` closure, found `unsafe extern "C" fn + //~^ ERROR: mismatched derive proc macro signature + //~| mismatched derive proc macro signature + //~| mismatched derive proc macro signature + //~| proc macro functions may not be `extern + //~| proc macro functions may not be `unsafe loop {} } diff --git a/tests/ui/proc-macro/signature.stderr b/tests/ui/proc-macro/signature.stderr index 79f2001da0055..3dbe3f22a0df8 100644 --- a/tests/ui/proc-macro/signature.stderr +++ b/tests/ui/proc-macro/signature.stderr @@ -1,20 +1,36 @@ -error[E0277]: expected a `Fn<(proc_macro::TokenStream,)>` closure, found `unsafe extern "C" fn(i32, u32) -> u32 {foo}` +error: proc macro functions may not be `extern "C"` --> $DIR/signature.rs:10:1 | -LL | / pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { -LL | | -LL | | loop {} -LL | | } - | | ^ - | | | - | |_call the function in a closure: `|| unsafe { /* code */ }` - | required by a bound introduced by this call +LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: proc macro functions may not be `unsafe` + --> $DIR/signature.rs:10:1 + | +LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: mismatched derive proc macro signature + --> $DIR/signature.rs:10:49 + | +LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { + | ^^^ found u32, expected type `proc_macro::TokenStream` + | + = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched derive proc macro signature + --> $DIR/signature.rs:10:33 + | +LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { + | ^^^ found i32, expected type `proc_macro::TokenStream` + | + = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` + +error: mismatched derive proc macro signature + --> $DIR/signature.rs:10:38 | - = help: the trait `Fn<(proc_macro::TokenStream,)>` is not implemented for fn item `unsafe extern "C" fn(i32, u32) -> u32 {foo}` - = note: unsafe function cannot be called generically without an unsafe block -note: required by a bound in `ProcMacro::custom_derive` - --> $SRC_DIR/proc_macro/src/bridge/client.rs:LL:COL +LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { + | ^^^^^^ found unexpected argument -error: aborting due to previous error +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0277`. From a8e3abd04cf85080d921c2d1875e0094b2db5155 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Sun, 8 Jan 2023 01:37:22 +0100 Subject: [PATCH 2/3] Address feedback --- compiler/rustc_passes/src/check_attr.rs | 56 +++++++++++++++-------- tests/ui/proc-macro/allowed-signatures.rs | 24 ++++++++++ tests/ui/proc-macro/proc-macro-abi.rs | 6 +-- 3 files changed, 63 insertions(+), 23 deletions(-) create mode 100644 tests/ui/proc-macro/allowed-signatures.rs diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 517bf2533c5e6..c2ce46d965cf3 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -23,6 +23,7 @@ use rustc_hir::{ use rustc_hir::{MethodKind, Target, Unsafety}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; +use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_session::lint::builtin::{ @@ -84,6 +85,8 @@ impl IntoDiagnosticArg for ProcMacroKind { struct CheckAttrVisitor<'tcx> { tcx: TyCtxt<'tcx>, + + // Whether or not this visitor should abort after finding errors abort: Cell, } @@ -2084,6 +2087,9 @@ impl CheckAttrVisitor<'_> { ); } + /// A best effort attempt to create an error for a mismatching proc macro signature. + /// + /// If this best effort goes wrong, it will just emit a worse error later (see #102923) fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) { let expected_input_count = match kind { ProcMacroKind::Attribute => 2, @@ -2103,23 +2109,30 @@ impl CheckAttrVisitor<'_> { let id = hir_id.expect_owner(); let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id).unwrap(); - let sig = tcx.fn_sig(id); + let sig = tcx.liberate_late_bound_regions(id.to_def_id(), tcx.fn_sig(id)); + let sig = tcx.normalize_erasing_regions(ParamEnv::empty(), sig); + + // We don't currently require that the function signature is equal to + // `fn(TokenStream) -> TokenStream`, but instead monomorphizes to + // `fn(TokenStream) -> TokenStream` after some substitution of generic arguments. + // + // Properly checking this means pulling in additional `rustc` crates, so we don't. + let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsInfer }; - if sig.abi() != Abi::Rust { - tcx.sess - .emit_err(ProcMacroInvalidAbi { span: hir_sig.span, abi: sig.abi().name() }); + if sig.abi != Abi::Rust { + tcx.sess.emit_err(ProcMacroInvalidAbi { span: hir_sig.span, abi: sig.abi.name() }); self.abort.set(true); } - if sig.unsafety() == Unsafety::Unsafe { + if sig.unsafety == Unsafety::Unsafe { tcx.sess.emit_err(ProcMacroUnsafe { span: hir_sig.span }); self.abort.set(true); } - let output = sig.output().skip_binder(); + let output = sig.output(); // Typecheck the output - if tcx.normalize_erasing_regions(ParamEnv::empty(), output) != tokenstream { + if !drcx.types_may_unify(output, tokenstream) { tcx.sess.emit_err(ProcMacroTypeError { span: hir_sig.decl.output.span(), found: output, @@ -2129,11 +2142,22 @@ impl CheckAttrVisitor<'_> { self.abort.set(true); } - // Typecheck "expected_input_count" inputs, emitting - // `ProcMacroMissingArguments` if there are not enough. - if let Some(args) = sig.inputs().skip_binder().get(0..expected_input_count) { - for (arg, input) in args.iter().zip(hir_sig.decl.inputs) { - if tcx.normalize_erasing_regions(ParamEnv::empty(), *arg) != tokenstream { + if sig.inputs().len() < expected_input_count { + tcx.sess.emit_err(ProcMacroMissingArguments { + expected_input_count, + span: hir_sig.span, + kind, + expected_signature, + }); + self.abort.set(true); + } + + // Check that the inputs are correct, if there are enough. + if sig.inputs().len() >= expected_input_count { + for (arg, input) in + sig.inputs().iter().zip(hir_sig.decl.inputs).take(expected_input_count) + { + if !drcx.types_may_unify(*arg, tokenstream) { tcx.sess.emit_err(ProcMacroTypeError { span: input.span, found: *arg, @@ -2143,14 +2167,6 @@ impl CheckAttrVisitor<'_> { self.abort.set(true); } } - } else { - tcx.sess.emit_err(ProcMacroMissingArguments { - expected_input_count, - span: hir_sig.span, - kind, - expected_signature, - }); - self.abort.set(true); } // Check that there are not too many arguments diff --git a/tests/ui/proc-macro/allowed-signatures.rs b/tests/ui/proc-macro/allowed-signatures.rs new file mode 100644 index 0000000000000..03c6ef86632df --- /dev/null +++ b/tests/ui/proc-macro/allowed-signatures.rs @@ -0,0 +1,24 @@ +// check-pass + +#![crate_type = "proc-macro"] +#![allow(private_in_public)] +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn foo(t: T) -> TokenStream { + TokenStream::new() +} + +trait Project { + type Assoc; +} + +impl Project for () { + type Assoc = TokenStream; +} + +#[proc_macro] +pub fn uwu(_input: <() as Project>::Assoc) -> <() as Project>::Assoc { + TokenStream::new() +} diff --git a/tests/ui/proc-macro/proc-macro-abi.rs b/tests/ui/proc-macro/proc-macro-abi.rs index 2a40ddd496ce8..8e9d50d7832d5 100644 --- a/tests/ui/proc-macro/proc-macro-abi.rs +++ b/tests/ui/proc-macro/proc-macro-abi.rs @@ -6,19 +6,19 @@ use proc_macro::TokenStream; #[proc_macro] pub extern "C" fn abi(a: TokenStream) -> TokenStream { - //~^ ERROR proc macro functions may not be `extern + //~^ ERROR proc macro functions may not be `extern "C"` a } #[proc_macro] pub extern "system" fn abi2(a: TokenStream) -> TokenStream { - //~^ ERROR proc macro functions may not be `extern + //~^ ERROR proc macro functions may not be `extern "system"` a } #[proc_macro] pub extern fn abi3(a: TokenStream) -> TokenStream { - //~^ ERROR proc macro functions may not be `extern + //~^ ERROR proc macro functions may not be `extern "C"` a } From 8e43414bce77cfe2030b875e365c77691897b95f Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Thu, 19 Jan 2023 16:31:50 +0100 Subject: [PATCH 3/3] Fix proc macro tests --- tests/ui/proc-macro/allowed-signatures.rs | 2 ++ tests/ui/proc-macro/proc-macro-abi.rs | 3 +++ tests/ui/proc-macro/proc-macro-abi.stderr | 6 +++--- .../ui/proc-macro/signature-proc-macro-attribute.rs | 3 +++ .../proc-macro/signature-proc-macro-attribute.stderr | 12 ++++++------ tests/ui/proc-macro/signature-proc-macro-derive.rs | 3 +++ .../ui/proc-macro/signature-proc-macro-derive.stderr | 10 +++++----- tests/ui/proc-macro/signature-proc-macro.rs | 3 +++ tests/ui/proc-macro/signature-proc-macro.stderr | 10 +++++----- 9 files changed, 33 insertions(+), 19 deletions(-) diff --git a/tests/ui/proc-macro/allowed-signatures.rs b/tests/ui/proc-macro/allowed-signatures.rs index 03c6ef86632df..8685087611248 100644 --- a/tests/ui/proc-macro/allowed-signatures.rs +++ b/tests/ui/proc-macro/allowed-signatures.rs @@ -1,4 +1,6 @@ // check-pass +// force-host +// no-prefer-dynamic #![crate_type = "proc-macro"] #![allow(private_in_public)] diff --git a/tests/ui/proc-macro/proc-macro-abi.rs b/tests/ui/proc-macro/proc-macro-abi.rs index 8e9d50d7832d5..873660a5b3ab9 100644 --- a/tests/ui/proc-macro/proc-macro-abi.rs +++ b/tests/ui/proc-macro/proc-macro-abi.rs @@ -1,3 +1,6 @@ +// force-host +// no-prefer-dynamic + #![crate_type = "proc-macro"] #![allow(warnings)] diff --git a/tests/ui/proc-macro/proc-macro-abi.stderr b/tests/ui/proc-macro/proc-macro-abi.stderr index fa5f5dc098998..9a781be0996dd 100644 --- a/tests/ui/proc-macro/proc-macro-abi.stderr +++ b/tests/ui/proc-macro/proc-macro-abi.stderr @@ -1,17 +1,17 @@ error: proc macro functions may not be `extern "C"` - --> $DIR/proc-macro-abi.rs:8:1 + --> $DIR/proc-macro-abi.rs:11:1 | LL | pub extern "C" fn abi(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: proc macro functions may not be `extern "system"` - --> $DIR/proc-macro-abi.rs:14:1 + --> $DIR/proc-macro-abi.rs:17:1 | LL | pub extern "system" fn abi2(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: proc macro functions may not be `extern "C"` - --> $DIR/proc-macro-abi.rs:20:1 + --> $DIR/proc-macro-abi.rs:23:1 | LL | pub extern fn abi3(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.rs b/tests/ui/proc-macro/signature-proc-macro-attribute.rs index fb17710950106..51abc8e7d3edb 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.rs +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.rs @@ -1,3 +1,6 @@ +// force-host +// no-prefer-dynamic + #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr index ecfd2b06e109c..abf7a6f3ce922 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr @@ -1,11 +1,11 @@ error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:7:1 + --> $DIR/signature-proc-macro-attribute.rs:10:1 | LL | pub fn bad_input(input: String) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:13:42 + --> $DIR/signature-proc-macro-attribute.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -13,13 +13,13 @@ LL | pub fn bad_output(input: TokenStream) -> String { = note: attribute proc macros must have a signature of `fn(TokenStream, TokenStream) -> TokenStream` error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:13:1 + --> $DIR/signature-proc-macro-attribute.rs:16:1 | LL | pub fn bad_output(input: TokenStream) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:20:41 + --> $DIR/signature-proc-macro-attribute.rs:23:41 | LL | pub fn bad_everything(input: String) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -27,13 +27,13 @@ LL | pub fn bad_everything(input: String) -> String { = note: attribute proc macros must have a signature of `fn(TokenStream, TokenStream) -> TokenStream` error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:20:1 + --> $DIR/signature-proc-macro-attribute.rs:23:1 | LL | pub fn bad_everything(input: String) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attribute proc macro must have two arguments of type `proc_macro::TokenStream` error: mismatched attribute proc macro signature - --> $DIR/signature-proc-macro-attribute.rs:27:49 + --> $DIR/signature-proc-macro-attribute.rs:30:49 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^ found unexpected argument diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.rs b/tests/ui/proc-macro/signature-proc-macro-derive.rs index a079157538fb6..f2fd824b675b6 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.rs +++ b/tests/ui/proc-macro/signature-proc-macro-derive.rs @@ -1,3 +1,6 @@ +// force-host +// no-prefer-dynamic + #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.stderr b/tests/ui/proc-macro/signature-proc-macro-derive.stderr index bb2bd9a93d24b..a358ae277037f 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-derive.stderr @@ -1,5 +1,5 @@ error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:7:25 + --> $DIR/signature-proc-macro-derive.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -7,7 +7,7 @@ LL | pub fn bad_input(input: String) -> TokenStream { = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:13:42 + --> $DIR/signature-proc-macro-derive.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -15,7 +15,7 @@ LL | pub fn bad_output(input: TokenStream) -> String { = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:19:41 + --> $DIR/signature-proc-macro-derive.rs:22:41 | LL | pub fn bad_everything(input: String) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -23,7 +23,7 @@ LL | pub fn bad_everything(input: String) -> String { = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:19:30 + --> $DIR/signature-proc-macro-derive.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -31,7 +31,7 @@ LL | pub fn bad_everything(input: String) -> String { = note: derive proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched derive proc macro signature - --> $DIR/signature-proc-macro-derive.rs:26:33 + --> $DIR/signature-proc-macro-derive.rs:29:33 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^ found unexpected arguments diff --git a/tests/ui/proc-macro/signature-proc-macro.rs b/tests/ui/proc-macro/signature-proc-macro.rs index 35d5be2171283..54770aacd1a98 100644 --- a/tests/ui/proc-macro/signature-proc-macro.rs +++ b/tests/ui/proc-macro/signature-proc-macro.rs @@ -1,3 +1,6 @@ +// force-host +// no-prefer-dynamic + #![crate_type = "proc-macro"] extern crate proc_macro; diff --git a/tests/ui/proc-macro/signature-proc-macro.stderr b/tests/ui/proc-macro/signature-proc-macro.stderr index 32241e1b9e00a..4b14a54e67503 100644 --- a/tests/ui/proc-macro/signature-proc-macro.stderr +++ b/tests/ui/proc-macro/signature-proc-macro.stderr @@ -1,5 +1,5 @@ error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:7:25 + --> $DIR/signature-proc-macro.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -7,7 +7,7 @@ LL | pub fn bad_input(input: String) -> TokenStream { = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:13:42 + --> $DIR/signature-proc-macro.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -15,7 +15,7 @@ LL | pub fn bad_output(input: TokenStream) -> String { = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:19:41 + --> $DIR/signature-proc-macro.rs:22:41 | LL | pub fn bad_everything(input: String) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -23,7 +23,7 @@ LL | pub fn bad_everything(input: String) -> String { = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:19:30 + --> $DIR/signature-proc-macro.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { | ^^^^^^ found std::string::String, expected type `proc_macro::TokenStream` @@ -31,7 +31,7 @@ LL | pub fn bad_everything(input: String) -> String { = note: function-like proc macros must have a signature of `fn(TokenStream) -> TokenStream` error: mismatched function-like proc macro signature - --> $DIR/signature-proc-macro.rs:26:33 + --> $DIR/signature-proc-macro.rs:29:33 | LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^ found unexpected arguments