Skip to content

Spurious (?) "trait bound not satisfied" with associated type constructors #34834

Closed
@SimonSapin

Description

@SimonSapin

I’m using the technique mentioned at https://github.com/rust-lang/rfcs/pull/1598/files/8e922c0cede49b0b07ac6fcf29ea736aab29acb9#r68995241 and used at https://github.com/nikomatsakis/nll/blob/master/graph-algorithms/src/lib.rs to have in a trait an associated type constructor that takes a lifetime parameter.

rustc 1.12.0-nightly (7ad125c 2016-07-11)

pub trait TypeConstructor<'a> {
    type BorrowedNamespace;
}

pub trait SelectorImpl
where Self: for<'a> TypeConstructor<'a> {
    // These two definitions should be equivalent (for `ExampleImpl`), but only the latter compiles.
    type Namespace: PartialEq + for<'a> PartialEq<<Self as TypeConstructor<'a>>::BorrowedNamespace>;
//  type Namespace: PartialEq + for<'a> PartialEq<&'a str>;

    // For illustration:
    fn get_namespace<'a>(&'a self) -> <Self as TypeConstructor<'a>>::BorrowedNamespace;
}


pub struct ExampleImpl;

impl<'a> TypeConstructor<'a> for ExampleImpl {
    type BorrowedNamespace = &'a str;
}

impl SelectorImpl for ExampleImpl {
    type Namespace = String;

    fn get_namespace<'a>(&'a self) -> &'a str { unimplemented!() }
}
error: the trait bound `for<'a> std::string::String: std::cmp::PartialEq<<ExampleImpl as TypeConstructor<'a>>::BorrowedNamespace>` is not satisfied [--explain E0277]
  --> a.rs:22:6
   |>
22 |> impl SelectorImpl for ExampleImpl {
   |>      ^^^^^^^^^^^^
help: the following implementations were found:
help:   <std::string::String as std::cmp::PartialEq>
help:   <std::string::String as std::cmp::PartialEq<str>>
help:   <std::string::String as std::cmp::PartialEq<&'a str>>
help:   <std::string::String as std::cmp::PartialEq<std::borrow::Cow<'a, str>>>
note: required by `SelectorImpl`

error: aborting due to previous error

Since<ExampleImpl as TypeConstructor<'a>>::BorrowedNamespace is &'a str for any 'a, I believe the bound for<'a> std::string::String: std::cmp::PartialEq<<ExampleImpl as TypeConstructor<'a>>::BorrowedNamespace> is equivalent to for<'a> std::string::String: std::cmp::PartialEq<&'a str>, which is the third bound that was found.

Metadata

Metadata

Assignees

Labels

A-type-systemArea: Type systemC-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types 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