One way to achieve what you want is the following:
macro_rules! unique_args {
    ($($idents:ident),*) => {
        {
            #[allow(dead_code, non_camel_case_types)]
            enum Idents { $($idents,)* __CountIdentsLast }
        }
    };
}
macro_rules! _my_elem {
    ($val:expr, $($var:expr),*) => {{
        $($val == $var)||*
    }};
}
macro_rules! my_elem {
    ($($tt:tt)*) => {{
        unique_args!($($tt)*);
        _my_elem!($($tt)*)
    }};
}
The idea is that having the same identifier twice will cause a compiler error because an enum cannot have duplicate variant names.
You can use this as such:
if my_elem!(w, x, y, z) {
    println!("{}", w);
}
Here is an example with an error:
// error[E0428]: a value named `y` has already been defined in this enum
if my_elem!(w, x, y, y) {
    println!("{}", w);
}
However, this will only work with identifiers.
If you want to use literals as well, you will need a macro with a different syntax to be able to differentiate between a literal and an identifier:
macro_rules! unique_idents {
    () => {
    };
    ($tt:tt) => {
    };
    ($ident1:ident, $ident2:ident) => {
        {
            #[allow(dead_code, non_camel_case_types)]
            enum Idents {
                $ident1,
                $ident2,
            }
        }
    };
    ($ident:ident, lit $expr:expr) => {
    };
    ($ident1:ident, $ident2:ident, $($tt:tt)*) => {
        {
            #[allow(dead_code, non_camel_case_types)]
            enum Idents {
                $ident1,
                $ident2,
            }
            unique_idents!($ident1, $($tt)*);
            unique_idents!($ident2, $($tt)*);
        }
    };
    ($ident:ident, lit $expr:expr, $($tt:tt)*) => {
        unique_idents!($ident, $($tt)*);
    };
    (lit $expr:expr, $($tt:tt)*) => {
        unique_idents!($($tt)*);
    };
}
macro_rules! unique_literals {
    () => {
    };
    ($tt:tt) => {
    };
    (lit $lit1:expr, lit $lit2:expr) => {{
            type ArrayForStaticAssert_ = [i8; 0 - (($lit1 == $lit2) as usize)];
    }};
    (lit $lit:expr, $ident:ident) => {
    };
    (lit $lit1:expr, lit $lit2:ident, $($tt:tt)*) => {{
            unique_literals!(lit $lit1, lit $lit2);
            unique_literals!(lit $lit1, $($tt)*);
            unique_literals!(lit $lit2, $($tt)*);
    }};
    (lit $lit:expr, $ident:ident, $($tt:tt)*) => {
        unique_literals!(lit $lit, $($tt)*);
    };
    ($ident:ident, $($tt:tt)*) => {
        unique_literals!($($tt)*);
    };
}
macro_rules! unique_args2 {
    ($($tt:tt)*) => {{
        unique_idents!($($tt)*);
        unique_literals!($($tt)*);
    }};
}
macro_rules! _elem {
    () => {
        false
    };
    ($val:expr) => {
        false
    };
    ($val1:expr, $val2:expr) => {{
        $val1 == $val2
    }};
    ($val1:expr, lit $val2:expr) => {{
        $val1 == $val2
    }};
    ($val1:expr, $val2:expr, $($tt:tt)*) => {{
        $val1 == $val2 || _elem!($val1, $($tt)*)
    }};
    ($val1:expr, lit $val2:expr, $($tt:tt)*) => {{
        $val1 == $val2 || _elem!($val1, $($tt)*)
    }};
}
macro_rules! elem {
    ($($tt:tt)*) => {{
        unique_args2!($($tt)*);
        _elem!($($tt)*)
    }};
}
The uniq_idents! macro uses the same trick as above.
The unique_literals! macro will cause a subtract with overflow error that is caught at compile time.
With these macros, you will need to prefix each literal by lit:
if elem!(w, x, lit 1, z) {
    println!("{}", w);
}
Here are some examples of errors:
// error[E0428]: a value named `y` has already been defined in this enum
if elem!(w, x, y, y) {
    println!("{}", w);
}
// error[E0080]: constant evaluation error
if elem!(w, x, lit 1, z, lit 1) {
    println!("{}", w);
}
I think it is the best we can do without using a compiler plugin.
It is possible to improve these macros, but you get the idea.
Even though there is a stringify! macro that can be use to convert any expression to a string, I don't think we currently have a way to compare these strings at compile time (without a compiler plugin), at least until we have const fn.