Skip to content

E0277 causes syntax error when adding several bounds at the same time via several errors #106881

Open
@matthiaskrgr

Description

@matthiaskrgr

Code

#![feature(associated_type_defaults)]

use std::{
    fmt::Display,
    ops::{AddAssign, Deref},
};

trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
    // This Output is said to be Copy. Yet we default to Self
    // and it's accepted, not knowing if Self ineed is Copy
    type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
    //~^ ERROR the trait bound `Self: Copy` is not satisfied
    //~| ERROR the trait bound `Self: Deref` is not satisfied
    //~| ERROR cannot add-assign `&'static str` to `Self`
    //~| ERROR `Self` doesn't implement `std::fmt::Display`

    // We said the Output type was Copy, so we can Copy it freely!
    fn unchecked_copy(other: &Self::Output) -> Self::Output {
        (*other)
    }

    fn make_origin(s: Self) -> Self::Output {
        s.into()
    }
}

impl<T> UncheckedCopy for T {}

fn bug<T: UncheckedCopy>(origin: T) {
    let origin = T::make_origin(origin);
    let mut copy = T::unchecked_copy(&origin);

    // assert we indeed have 2 strings pointing to the same buffer.
    assert_eq!(origin.as_ptr(), copy.as_ptr());

    // Drop the origin. Any use of `copy` is UB.
    drop(origin);

    copy += "This is invalid!";
    println!("{}", copy);
}

fn main() {
    bug(String::from("hello!"));
}

Current output

warning: unnecessary parentheses around block return value
  --> src/lib.rs:19:9
   |
19 |         (*other)
   |         ^      ^
   |
   = note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
   |
19 -         (*other)
19 +         *other
   |

error[E0277]: the trait bound `T: Copy` is not satisfied
  --> src/lib.rs:27:27
   |
27 | impl<T> UncheckedCopy for T {}
   |                           ^ the trait `Copy` is not implemented for `T`
   |
note: required by a bound in `UncheckedCopy`
  --> src/lib.rs:8:84
   |
8  | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
   |                                                                                    ^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
   |
27 | impl<T: std::marker::Copy> UncheckedCopy for T {}
   |       +++++++++++++++++++

error[E0277]: the trait bound `T: Deref` is not satisfied
  --> src/lib.rs:27:27
   |
27 | impl<T> UncheckedCopy for T {}
   |                           ^ the trait `Deref` is not implemented for `T`
   |
note: required by a bound in `UncheckedCopy`
  --> src/lib.rs:8:76
   |
8  | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
   |                                                                            ^^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
   |
27 | impl<T: std::ops::Deref> UncheckedCopy for T {}
   |       +++++++++++++++++

error[E0277]: cannot add-assign `&'static str` to `T`
  --> src/lib.rs:27:27
   |
27 | impl<T> UncheckedCopy for T {}
   |                           ^ no implementation for `T += &'static str`
   |
note: required by a bound in `UncheckedCopy`
  --> src/lib.rs:8:50
   |
8  | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
   |
27 | impl<T: std::ops::AddAssign<&'static str>> UncheckedCopy for T {}
   |       +++++++++++++++++++++++++++++++++++

error[E0277]: `T` doesn't implement `std::fmt::Display`
  --> src/lib.rs:27:27
   |
27 | impl<T> UncheckedCopy for T {}
   |                           ^ `T` cannot be formatted with the default formatter
   |
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy`
  --> src/lib.rs:8:30
   |
8  | trait UncheckedCopy: Sized + std::fmt::Display + AddAssign<&'static str> + Deref + Copy {
   |                              ^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy`
help: consider restricting type parameter `T`
   |
27 | impl<T: std::fmt::Display> UncheckedCopy for T {}
   |       +++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.

Here we have several errors trying to add bounds to impl<T> UncheckedCopy for T {}.

help: consider restricting type parameter `T`
   |
27 | impl<T: std::marker::Copy> UncheckedCopy for T {}

This would work when adding only a single bound, but here we end up adding several bounds, separated by : which causes syntax error, the "fully fixed" code ends up being
impl<T: std::marker::Copy: std::ops::Deref: std::ops::AddAssign<&'static str>: std::fmt::Display> UncheckedCopy for T {}

Can we make rust clever enough to separate these by + ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions