Custom inlay hints in a proc macro

When you want to throw an error in a proc_macro you can use syn::Error#into_compiler_error() to throw a compiler error at a specific span, and rust-analyzer on vscode will draw a red squiggly line

Is there a similar TokenStream you can emit that creates a custom inlay hint?

For example (assume the proc_macro is in a separate crate from main() so it actually compiles):

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, punctuated::Punctuated, token::Comma, LitInt};

fn sum(lhs: u32, rhs: u32) -> u32 {
    lhs + rhs
}

#[proc_macro]
pub fn sum_macro(input: TokenStream) -> TokenStream {
    let args = parse_macro_input!(input with Punctuated<LitInt, Comma>::parse_terminated);
    let mut iter = args.iter().map(|v| v.base10_parse::<u32>().unwrap());

    let lhs = iter.next().unwrap_or(0);
    let rhs = iter.next().unwrap_or(0);

    quote! { #lhs + #rhs }.into()
}

fn main() {
    sum(1, 2);
    sum_macro!(1, 2);
}

Looks like this in vscode with rust analyzer:

Is there a way of manually inserting inlay hints for the two arguments like those automatically done for the sum() function?

I'm 99.9% sure this isn't currently possible.

1 Like

Maybe it works if inside the macro you generate a function with parameter names matching the inlay hints you want and then calling this function with the arguments of the macro?

I guess you could wrap the macro in a function like this which might be what you mean?

fn sum(lhs: u32, rhs: u32) -> u32 {
    sum_macro!(lhs, rhs)
}

although that would only work for functional macros not derive or attribute ones

No, I mean that sum_macro!(1, 2) would expand to

{
    fn sum(lhs: u32, rhs: u32) -> u32 { lhs + rhs }
    sum(1, 2)
}

or to

{
    fn name_args<T, U>(lhs: T, rhs: U) -> (T, U) { (lhs, rhs) }
    let (a, b) = name_args(1, 2);
    a + b
}

in other words the macro itself makes a call which would have those inlay hints. Rust-analyzer may then forward the inlay hints for the inner call to the macro invocation the user wrote. I'm not sure if that actually happens though. You did have to try.

Nice idea, but sadly nope: