-
Notifications
You must be signed in to change notification settings - Fork 0
Emit proc-macro expansion directly via quote! instead of delegating to __devirt_define! #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| struct Hot { | ||
| name: String, | ||
| } | ||
|
|
||
| struct Cold { | ||
| name: String, | ||
| } | ||
|
|
||
| #[devirt::devirt(Hot)] | ||
| pub trait Named { | ||
| fn name<'a>(&'a self) -> &'a str; | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Named for Hot { | ||
| fn name<'a>(&'a self) -> &'a str { &self.name } | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Named for Cold { | ||
| fn name<'a>(&'a self) -> &'a str { &self.name } | ||
| } | ||
|
|
||
| fn greet(n: &dyn Named) -> String { | ||
| format!("Hello, {}!", n.name()) | ||
| } | ||
|
|
||
| fn main() { | ||
| let h = Hot { name: "world".into() }; | ||
| let c = Cold { name: "rust".into() }; | ||
| assert_eq!(greet(&h), "Hello, world!"); | ||
| assert_eq!(greet(&c), "Hello, rust!"); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| struct Hot { | ||
| val: f64, | ||
| } | ||
|
|
||
| struct Cold { | ||
| val: f64, | ||
| } | ||
|
|
||
| #[devirt::devirt(Hot)] | ||
| pub trait Computed { | ||
| #[must_use] | ||
| fn compute(&self) -> f64; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| #[devirt::devirt] | ||
| impl Computed for Hot { | ||
| fn compute(&self) -> f64 { self.val * 2.0 } | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Computed for Cold { | ||
| fn compute(&self) -> f64 { self.val * 3.0 } | ||
| } | ||
|
|
||
| fn main() { | ||
| let h = Hot { val: 1.0 }; | ||
| let c = Cold { val: 1.0 }; | ||
| let dh: &dyn Computed = &h; | ||
| let dc: &dyn Computed = &c; | ||
| let _ = dh.compute(); // should NOT warn (result is used via let _) | ||
| let _ = dc.compute(); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // Verifies that #[must_use] on a trait method is preserved through | ||
| // macro expansion: calling compute() without using the result must | ||
| // trigger an error under deny(unused_must_use). | ||
| #![deny(unused_must_use)] | ||
|
|
||
| struct Hot { | ||
| val: f64, | ||
| } | ||
|
|
||
| #[devirt::devirt(Hot)] | ||
| pub trait Computed { | ||
| #[must_use] | ||
| fn compute(&self) -> f64; | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Computed for Hot { | ||
| fn compute(&self) -> f64 { self.val * 2.0 } | ||
| } | ||
|
|
||
| fn main() { | ||
| let h = Hot { val: 1.0 }; | ||
| let d: &dyn Computed = &h; | ||
| d.compute(); // ERROR: unused return value that must be used | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| error: unused return value of `<(dyn Computed + '__devirt)>::compute` that must be used | ||
| --> tests/ui_attr/attr_must_use_unused.rs:24:5 | ||
| | | ||
| 24 | d.compute(); // ERROR: unused return value that must be used | ||
| | ^^^^^^^^^^^ | ||
| | | ||
| note: the lint level is defined here | ||
| --> tests/ui_attr/attr_must_use_unused.rs:4:9 | ||
| | | ||
| 4 | #![deny(unused_must_use)] | ||
| | ^^^^^^^^^^^^^^^ | ||
| help: use `let _ = ...` to ignore the resulting value | ||
| | | ||
| 24 | let _ = d.compute(); // ERROR: unused return value that must be used | ||
| | +++++++ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| use std::fmt::Debug; | ||
|
|
||
| #[derive(Debug)] | ||
| struct Hot { | ||
| val: u64, | ||
| } | ||
|
|
||
| #[derive(Debug)] | ||
| struct Cold { | ||
| val: u64, | ||
| } | ||
|
|
||
| #[devirt::devirt(Hot)] | ||
| pub trait Inspectable: Debug { | ||
| fn value(&self) -> u64; | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Inspectable for Hot { | ||
| fn value(&self) -> u64 { self.val } | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Inspectable for Cold { | ||
| fn value(&self) -> u64 { self.val + 1 } | ||
| } | ||
|
|
||
| fn inspect(i: &dyn Inspectable) -> String { | ||
| format!("{:?} = {}", i, i.value()) | ||
| } | ||
|
|
||
| fn main() { | ||
| let h = Hot { val: 42 }; | ||
| let c = Cold { val: 42 }; | ||
| let s = inspect(&h); | ||
| assert!(s.contains("42"), "expected '42' in '{s}'"); | ||
| let s = inspect(&c); | ||
| assert!(s.contains("43"), "expected '43' in '{s}'"); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| struct Hot { | ||
| data: *const u8, | ||
| } | ||
|
|
||
| struct Cold { | ||
| data: *const u8, | ||
| } | ||
|
|
||
| #[devirt::devirt(Hot)] | ||
| pub trait Dangerous { | ||
| unsafe fn deref(&self) -> u8; | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Dangerous for Hot { | ||
| unsafe fn deref(&self) -> u8 { unsafe { *self.data } } | ||
| } | ||
|
|
||
| #[devirt::devirt] | ||
| impl Dangerous for Cold { | ||
| unsafe fn deref(&self) -> u8 { unsafe { *self.data } } | ||
| } | ||
|
|
||
| fn main() { | ||
| let val: u8 = 42; | ||
| let h = Hot { data: &val }; | ||
| let c = Cold { data: &val }; | ||
| let dh: &dyn Dangerous = &h; | ||
| let dc: &dyn Dangerous = &c; | ||
| assert_eq!(unsafe { dh.deref() }, 42); | ||
| assert_eq!(unsafe { dc.deref() }, 42); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| struct Hot { | ||
| val: u64, | ||
| } | ||
|
|
||
| #[devirt::devirt(Hot)] | ||
| pub unsafe trait Trusted { | ||
| fn verify(&self) -> bool; | ||
| } | ||
|
|
||
| // Missing `unsafe` on impl — should fail because __TrustedImpl is unsafe. | ||
| #[devirt::devirt] | ||
| impl Trusted for Hot { | ||
| fn verify(&self) -> bool { self.val > 0 } | ||
| } | ||
|
|
||
| fn main() {} |
12 changes: 12 additions & 0 deletions
12
crates/core/tests/ui_attr/attr_unsafe_missing_on_impl.stderr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| error[E0200]: the trait `__TrustedImpl` requires an `unsafe impl` declaration | ||
| --> tests/ui_attr/attr_unsafe_missing_on_impl.rs:11:1 | ||
| | | ||
| 11 | #[devirt::devirt] | ||
| | ^^^^^^^^^^^^^^^^^ | ||
| | | ||
| = note: the trait `__TrustedImpl` enforces invariants that the compiler can't check. Review the trait documentation and make sure this implementation upholds those invariants before adding the `unsafe` keyword | ||
| = note: this error originates in the attribute macro `devirt::devirt` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
| help: add `unsafe` to this trait implementation | ||
| | | ||
| 11 | unsafe #[devirt::devirt] | ||
| | ++++++ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Architecture contract drift from the repository macro-expansion rule.
Line 33 through Line 38 document direct proc-macro dispatch emission instead of routing through
__devirt_define!. That introduces two expansion engines and diverges from the repo’s stated single-source expansion contract; please either restore delegation or update the project rule/docs in the same change set.As per coding guidelines "
crates/core/src/**/*.rs: Place all dispatch expansion logic in__devirt_define!macro with#[doc(hidden)],#[macro_export]attributes, and implement two entry points:@trait... and@impl...".🤖 Prompt for AI Agents