Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ pub fn phantom(args: TokenStream, input: TokenStream) -> TokenStream {
let ident = &input.ident;
let call_site = Span::call_site();
let void_namespace = Ident::new(&format!("__void_{}", ident), call_site);
let value_namespace = Ident::new(&format!("__value_{}", ident), call_site);
let fake_ident = Ident::new(&format!("{}__Phantom", ident), ident.span());

let vis = &input.vis;
let vis_super = visibility::vis_super(vis);
Expand Down Expand Up @@ -296,7 +296,11 @@ pub fn phantom(args: TokenStream, input: TokenStream) -> TokenStream {
ty_generics.push(quote!(#lifetime));
phantoms.push(variance::apply(param, elem, &type_param));
}
GenericParam::Const(_) => {}
GenericParam::Const(param) => {
let ident = &param.ident;
impl_generics.push(quote!(#param));
ty_generics.push(quote!(#ident));
}
}
}

Expand Down Expand Up @@ -355,19 +359,19 @@ pub fn phantom(args: TokenStream, input: TokenStream) -> TokenStream {
}
}

mod #value_namespace {
#[doc(hidden)]
#vis_super use super::#ident::#ident;
}

#[doc(hidden)]
#[allow(non_camel_case_types)]
#(#attrs)*
#vis #enum_token #ident #generics #where_clause {
#vis #enum_token #fake_ident #generics #where_clause {
__Phantom(#void_namespace::#ident <#(#ty_generics),*>),
#ident,
}

#[doc(hidden)]
#vis use self::#value_namespace::*;
#vis use #fake_ident::*;

#[allow(unused_imports, type_alias_bounds)]
#vis type #ident #generics #where_clause = #fake_ident <#(#ty_generics),*>;

#derives
})
Expand Down
6 changes: 6 additions & 0 deletions tests/function-body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use ghost::phantom;

const fn main() {
#[phantom]
struct MyPhantom<T: ?Sized>;
}
4 changes: 2 additions & 2 deletions tests/ui/autotraits.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ note: required because it appears within the type `__void_MyPhantom::MyPhantom<*
|
4 | struct MyPhantom<T: ?Sized>;
| ^^^^^^^^^
note: required because it appears within the type `MyPhantom<*const u8>`
note: required because it appears within the type `MyPhantom__Phantom<*const u8>`
--> tests/ui/autotraits.rs:4:8
|
4 | struct MyPhantom<T: ?Sized>;
Expand Down Expand Up @@ -44,7 +44,7 @@ note: required because it appears within the type `__void_MyPhantom::MyPhantom<*
|
4 | struct MyPhantom<T: ?Sized>;
| ^^^^^^^^^
note: required because it appears within the type `MyPhantom<*const u8>`
note: required because it appears within the type `MyPhantom__Phantom<*const u8>`
--> tests/ui/autotraits.rs:4:8
|
4 | struct MyPhantom<T: ?Sized>;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/ffi.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: `extern` fn uses type `MyPhantom<i32>`, which is not FFI-safe
error: `extern` fn uses type `MyPhantom__Phantom<i32>`, which is not FFI-safe
--> tests/ui/ffi.rs:8:39
|
8 | pub extern "C" fn extern_fn(_phantom: MyPhantom<i32>) {}
Expand Down
8 changes: 0 additions & 8 deletions tests/ui/function-body.rs

This file was deleted.

8 changes: 4 additions & 4 deletions tests/ui/invariant.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ error: lifetime may not live long enough
7 | phantom
| ^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
= note: requirement occurs because of the type `InvariantPhantom<&str>`, which makes the generic argument `&str` invariant
= note: the enum `InvariantPhantom<T>` is invariant over the parameter `T`
= note: requirement occurs because of the type `InvariantPhantom__Phantom<&str>`, which makes the generic argument `&str` invariant
= note: the enum `InvariantPhantom__Phantom<T>` is invariant over the parameter `T`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: lifetime may not live long enough
Expand All @@ -18,6 +18,6 @@ error: lifetime may not live long enough
11 | phantom
| ^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
= note: requirement occurs because of the type `InvariantPhantom<&str>`, which makes the generic argument `&str` invariant
= note: the enum `InvariantPhantom<T>` is invariant over the parameter `T`
= note: requirement occurs because of the type `InvariantPhantom__Phantom<&str>`, which makes the generic argument `&str` invariant
= note: the enum `InvariantPhantom__Phantom<T>` is invariant over the parameter `T`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
20 changes: 10 additions & 10 deletions tests/ui/pattern-match.stderr
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
error[E0004]: non-exhaustive patterns: `MyPhantom::__Phantom(_)` not covered
error[E0004]: non-exhaustive patterns: `MyPhantom__Phantom::__Phantom(_)` not covered
--> tests/ui/pattern-match.rs:9:11
|
9 | match phantom {
| ^^^^^^^ pattern `MyPhantom::__Phantom(_)` not covered
| ^^^^^^^ pattern `MyPhantom__Phantom::__Phantom(_)` not covered
|
note: `MyPhantom<u8>` defined here
note: `MyPhantom__Phantom<u8>` defined here
--> tests/ui/pattern-match.rs:4:8
|
3 | #[phantom]
| ---------- not covered
4 | struct MyPhantom<T: ?Sized>;
| ^^^^^^^^^
= note: the matched value is of type `MyPhantom<u8>`
= note: the matched value is of type `MyPhantom__Phantom<u8>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
10~ MyPhantom => {},
11+ MyPhantom::__Phantom(_) => todo!()
11+ MyPhantom__Phantom::__Phantom(_) => todo!()
|

error[E0004]: non-exhaustive patterns: `MyPhantom::__Phantom(_)` not covered
error[E0004]: non-exhaustive patterns: `MyPhantom__Phantom::__Phantom(_)` not covered
--> tests/ui/pattern-match.rs:13:11
|
13 | match phantom {
| ^^^^^^^ pattern `MyPhantom::__Phantom(_)` not covered
| ^^^^^^^ pattern `MyPhantom__Phantom::__Phantom(_)` not covered
|
note: `MyPhantom<u8>` defined here
note: `MyPhantom__Phantom<u8>` defined here
--> tests/ui/pattern-match.rs:4:8
|
3 | #[phantom]
| ---------- not covered
4 | struct MyPhantom<T: ?Sized>;
| ^^^^^^^^^
= note: the matched value is of type `MyPhantom<u8>`
= note: the matched value is of type `MyPhantom__Phantom<u8>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
14 ~ MyPhantom::<u8> => {},
15 + MyPhantom::__Phantom(_) => todo!()
15 + MyPhantom__Phantom::__Phantom(_) => todo!()
|