Auto merge of #85511 - Mark-Simulacrum:eq-not-sup, r=nikomatsakis

Adjust self-type check to require equality

When we encounter `SomeType::<X>::foo`, `self_ty` is `SomeType<X>` and the method is defined in an impl on `SomeType<A>`. Previously, we required simply that `self_ty <: impl_ty`, but this is too lax: we should require equality in order to use the method. This was found as part of unrelated work on never type stabilization, but also fixes one of the wf test cases.
This commit is contained in:
bors 2021-05-21 16:36:36 +00:00
commit 9c0379c0f5
6 changed files with 34 additions and 20 deletions

View File

@ -1522,7 +1522,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = tcx.type_of(impl_def_id);
let impl_ty = self.instantiate_type_scheme(span, &substs, ty);
match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) {
Ok(ok) => self.register_infer_ok_obligations(ok),
Err(_) => {
self.tcx.sess.delay_span_bug(

View File

@ -17,7 +17,6 @@ fn main() {
let fp = BufWriter::new(fp);
//~^ ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
//~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
//~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
writeln!(fp, "hello world").unwrap(); //~ ERROR the method
}

View File

@ -7,19 +7,6 @@ LL | let fp = BufWriter::new(fp);
= note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
= note: required by `BufWriter::<W>::new`
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
|
LL | let fp = BufWriter::new(fp);
| ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
|
::: $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
LL | pub struct BufWriter<W: Write> {
| ----- required by this bound in `BufWriter`
|
= note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
|
@ -34,7 +21,7 @@ LL | pub struct BufWriter<W: Write> {
= note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn std::io::Write>`, but its trait bounds were not satisfied
--> $DIR/mut-borrow-needed-by-trait.rs:22:5
--> $DIR/mut-borrow-needed-by-trait.rs:21:5
|
LL | writeln!(fp, "hello world").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `BufWriter<&dyn std::io::Write>` due to unsatisfied trait bounds
@ -49,7 +36,7 @@ LL | pub struct BufWriter<W: Write> {
which is required by `BufWriter<&dyn std::io::Write>: std::io::Write`
= note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.

View File

@ -68,7 +68,7 @@ LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | <Evil>::inherent_evil(b) // bug? shouldn't this be an error
LL | <Evil>::inherent_evil(b)
| ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`

View File

@ -47,7 +47,8 @@ fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
}
fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
<Evil>::inherent_evil(b) // bug? shouldn't this be an error
<Evil>::inherent_evil(b)
//~^ ERROR cannot infer an appropriate lifetime
}

View File

@ -103,7 +103,34 @@ note: ...so that reference does not outlive borrowed content
LL | <IndirectEvil>::static_evil(b)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
--> $DIR/wf-static-method.rs:50:5
|
LL | <Evil>::inherent_evil(b)
| ^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 49:22...
--> $DIR/wf-static-method.rs:49:22
|
LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/wf-static-method.rs:50:27
|
LL | <Evil>::inherent_evil(b)
| ^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 49:18...
--> $DIR/wf-static-method.rs:49:18
|
LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/wf-static-method.rs:50:5
|
LL | <Evil>::inherent_evil(b)
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0312, E0478, E0495.
For more information about an error, try `rustc --explain E0312`.