Skip to content

Cause an error for a function, but not a tuple struct #3

Description

@chipshort

The README currently says:

The macro will cause a compiler error if it encounters a function where a struct was expected

Ideally, we would do the same if we encounter a tuple struct where a function was expected (i.e. a lower case tuple struct).
Currently this is handled like a function call (which it is in a way), but that means the struct is constructed on the stack and moved unto the heap afterwards. This does not cause UB, but it can overflow the stack.
However, I could not find a way to do that reliably. The closest i got was the following code:

/// Validates that the given expression is not a tuple struct instantiation of the form `Struct(...)`.
///
/// This is needed to distinguish between function calls and struct instantiations and
/// cause a compile error for the latter.
fn validate_not_tuple_struct(path: &Path) -> TokenStream {
    // The only way to reject a tuple struct instantiation, but accept a function call that I found is
    // to shadow the name with a let-binding. For tuple structs, this causes a compiler error,
    // but not for function calls.
    let ident = path.segments.last().expect("empty ident not supported");

    quote_spanned! {path.span()=> {
        #[allow(unused)] {
                #[allow(unused)]
                use #path;
                #[allow(unused, clippy::let_unit_value)]
                let #ident = ();
        };
    }}
}

However, that use #path; causes a compiler error for paths like String::from.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions