about summary refs log tree commit diff
path: root/compiler/rustc_feature/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-17 20:07:02 +0100
committerGitHub <noreply@github.com>2022-01-17 20:07:02 +0100
commit32d85c0b5ab357a3f7cdba4fb43b8cc678e44c30 (patch)
tree91aae51eedf278b7576910b0cbc686c279736035 /compiler/rustc_feature/src
parent67bcbde3c50bdf50a48eb0e6a664cc8d02276d9d (diff)
parent28edd7ac090d621ad8fd0ebe220d897d9df386a9 (diff)
downloadrust-32d85c0b5ab357a3f7cdba4fb43b8cc678e44c30.tar.gz
rust-32d85c0b5ab357a3f7cdba4fb43b8cc678e44c30.zip
Rollup merge of #92164 - WaffleLapkin:rustc_must_implement_one_of_attr, r=Aaron1011
Implement `#[rustc_must_implement_one_of]` attribute

This PR adds a new attribute — `#[rustc_must_implement_one_of]` that allows changing the "minimal complete definition" of a trait. It's similar to GHC's minimal `{-# MINIMAL #-}` pragma, though `#[rustc_must_implement_one_of]` is weaker atm.

Such attribute was long wanted. It can be, for example, used in `Read` trait to make transitions to recently added `read_buf` easier:
```rust
#[rustc_must_implement_one_of(read, read_buf)]
pub trait Read {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        let mut buf = ReadBuf::new(buf);
        self.read_buf(&mut buf)?;
        Ok(buf.filled_len())
    }

    fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
        default_read_buf(|b| self.read(b), buf)
    }
}

impl Read for Ty0 {}
//^ This will fail to compile even though all `Read` methods have default implementations

// Both of these will compile just fine
impl Read for Ty1 {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> { /* ... */ }
}
impl Read for Ty2 {
    fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> { /* ... */ }
}
```

For now, this is implemented as an internal attribute to start experimenting on the design of this feature. In the future we may want to extend it:
- Allow arbitrary requirements like `a | (b & c)`
- Allow multiple requirements like
  - ```rust
    #[rustc_must_implement_one_of(a, b)]
    #[rustc_must_implement_one_of(c, d)]
    ```
- Make it appear in rustdoc documentation
- Change the syntax?
- Etc

Eventually, we should make an RFC and make this (or rather similar) attribute public.

---

I'm fairly new to compiler development and not at all sure if the implementation makes sense, but at least it passes tests :)
Diffstat (limited to 'compiler/rustc_feature/src')
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
1 files changed, 6 insertions, 0 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 46817bc9c3f..5309f217b4a 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -682,6 +682,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         "the `#[rustc_skip_array_during_method_dispatch]` attribute is used to exclude a trait \
         from method dispatch when the receiver is an array, for compatibility in editions < 2021."
     ),
+    rustc_attr!(
+        rustc_must_implement_one_of, Normal, template!(List: "function1, function2, ..."), ErrorFollowing,
+        "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \
+        definition of a trait, it's currently in experimental form and should be changed before \
+        being exposed outside of the std"
+    ),
 
     // ==========================================================================
     // Internal attributes, Testing: