Skip to content

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

@chipshort

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.

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