Skip to content

Compiler unable to match types with trait implementation #43644

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

Open
debris opened this issue Aug 4, 2017 · 5 comments
Open

Compiler unable to match types with trait implementation #43644

debris opened this issue Aug 4, 2017 · 5 comments
Labels
A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@debris
Copy link
Contributor

debris commented Aug 4, 2017

rustc 1.19.0 (0ade33941 2017-07-17)

The following piece of code:

pub struct Foo {
	pub data: [u8; 64],
}

pub struct FooRef<'a> {
	pub data: &'a [u8; 64],
}

impl<'a> From<&'a Foo> for FooRef<'a> {
	fn from(foo: &'a Foo) -> Self {
		FooRef {
			data: &foo.data,
		}
	}
}

impl Foo {
	pub fn do_something<'a, F>(&self, _foo: F) where FooRef<'a>: From<F> {
		let _test_foo = FooRef::from(self);
	}

	pub fn do_something2<F>(&self, _foo: F) {
		let _test_foo2 = FooRef::from(self);
	}
}

fails with:

error[E0308]: mismatched types
  --> foo/src/lib.rs:19:32
   |
19 | 		let _test_foo = FooRef::from(self);
   | 		                             ^^^^ expected type parameter, found &Foo
   |
   = note: expected type `F`
              found type `&Foo`

error: aborting due to previous error(s)

Because of additional lifetime or template at line 19, compiler is no longer able to resolve FooRef::from(self);

Link to the repo:

https://github.com/debris/borrowchecker_test

run with cargo check -p foo

It may not be an issue, but in that case, it needs better error message. And also, please tell me how to make it work ;)

@durka
Copy link
Contributor

durka commented Aug 4, 2017

It seems you already know how to make it work: remove the where clause! This also seems to work:

pub fn do_something<'a, F>(&'a self, _foo: F) where FooRef<'a>: From<F> {
	let _test_foo = <FooRef as From<&Foo>>::from(self);
}

As for the problem itself I think it might be related to #41756:

The same mechanisms also lead to cases where:

  1. Adding a valid where clause can cause code to stop compiling.
  2. Adding a where clause can change program behavior.

@debris
Copy link
Contributor Author

debris commented Aug 4, 2017

But I need this closure ;) Your example also does not work ;)

Here is my workaround:

pub fn do_something<'a, F>(&'a self, foo: F) where FooRef<'a>: From<F> {
    let foo_ref: FooRef = foo.into();
    self.do_something_internal(foo_ref)
}

pub fn do_something_internal(&self, _foo: FooRef) {
    let _self_ref: FooRef = self.into();
    // ... 
}

@durka
Copy link
Contributor

durka commented Aug 5, 2017

My workaround does work -- note that I also added 'a to self. Your workaround is fine as well, in fact, it may even be advantageous since long generic functions lead to binary bloat (the compiler must generate separate versions of the function for each type used to call it), so doing conversions and then handing off to a non-generic is a fairly common pattern.

@debris
Copy link
Contributor Author

debris commented Aug 5, 2017

Yes, it works indeed, sry. And thank you very much for explanation :)

@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. A-type-system Area: Type system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 10, 2017
@Spoonbender
Copy link

Triage: no change

@fmease fmease added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants