Don't bind hidden types when searching for matching impls

This commit is contained in:
Oli Scherer 2022-02-10 14:53:50 +00:00
parent f42a6793ce
commit 1c5bfb1770
7 changed files with 74 additions and 39 deletions

View file

@ -2163,6 +2163,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let InferOk { obligations, .. } = self
.infcx
.at(&cause, obligation.param_env)
.define_opaque_types(false)
.eq(placeholder_obligation_trait_ref, impl_trait_ref)
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
nested_obligations.extend(obligations);

View file

@ -4,7 +4,7 @@ fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
//~^ ERROR nested `impl Trait` is not allowed
//~| ERROR `impl Into<u32>` doesn't implement `Debug`
//~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
//~^ ERROR nested `impl Trait` is not allowed
@ -17,7 +17,7 @@ struct X;
impl X {
fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
//~^ ERROR nested `impl Trait` is not allowed
//~| ERROR `impl Into<u32>` doesn't implement `Debug`
//~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
}
fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {

View file

@ -46,27 +46,21 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
| ^^^^^^^^^^^^^^
error[E0277]: `impl Into<u32>` doesn't implement `Debug`
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
--> $DIR/nested_impl_trait.rs:5:70
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^ `impl Into<u32>` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| ^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
|
help: consider further restricting this bound
|
LL | fn bad_in_ret_position(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++
= note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
error[E0277]: `impl Into<u32>` doesn't implement `Debug`
error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
--> $DIR/nested_impl_trait.rs:18:58
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^ `impl Into<u32>` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| ^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
|
help: consider further restricting this bound
|
LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++
= note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>`
error: aborting due to 8 previous errors

View file

@ -0,0 +1,17 @@
#![feature(type_alias_impl_trait)]
type Foo = impl PartialEq<(Foo, i32)>;
struct Bar;
impl PartialEq<(Foo, i32)> for Bar {
fn eq(&self, _other: &(Foo, i32)) -> bool {
true
}
}
fn foo() -> Foo {
Bar //~ ERROR can't compare `Bar` with `(Bar, i32)`
}
fn main() {}

View file

@ -0,0 +1,11 @@
error[E0277]: can't compare `Bar` with `(Bar, i32)`
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs:14:5
|
LL | Bar
| ^^^ no implementation for `Bar == (Bar, i32)`
|
= help: the trait `PartialEq<(Bar, i32)>` is not implemented for `Bar`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -2,36 +2,18 @@
#![feature(type_alias_impl_trait)]
mod direct {
type Foo = impl PartialEq<(Foo, i32)>;
type Foo = impl PartialEq<(Foo, i32)>;
struct Bar;
struct Bar;
impl PartialEq<(Foo, i32)> for Bar {
fn eq(&self, _other: &(Foo, i32)) -> bool {
true
}
}
fn foo() -> Foo {
Bar
impl PartialEq<(Bar, i32)> for Bar {
fn eq(&self, _other: &(Bar, i32)) -> bool {
true
}
}
mod indirect {
type Foo = impl PartialEq<(Foo, i32)>;
struct Bar;
impl PartialEq<(Bar, i32)> for Bar {
fn eq(&self, _other: &(Bar, i32)) -> bool {
true
}
}
fn foo() -> Foo {
Bar
}
fn foo() -> Foo {
Bar
}
fn main() {}

View file

@ -0,0 +1,30 @@
// check-pass
use std::fmt::Debug;
pub struct EventStream<S> {
stream: S,
}
impl<S: Debug> EventStream<S> {
fn into_stream(self) -> impl Debug {
unimplemented!()
}
pub fn into_reader(self) -> impl Debug {
ReaderStream::from(self.into_stream())
}
}
#[derive(Debug)]
pub struct ReaderStream<S> {
stream: S,
}
impl<S> From<S> for ReaderStream<S> {
fn from(stream: S) -> Self {
ReaderStream { stream }
}
}
fn main() {}