From 4aa34df88706c7c8e497cb12b59edda0abc371b2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 10 Jun 2024 10:15:37 +0000 Subject: [PATCH] Use subtyping instead of equality, since method resolution also uses subtyping --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 9 +++------ ...rong-projection-self-ty-on-invalid-type.rs | 10 ++++++++++ ...-projection-self-ty-on-invalid-type.stderr | 12 +++++++++++ ...ong-projection-self-ty-on-invalid-type2.rs | 17 ++++++++++++++++ ...projection-self-ty-on-invalid-type2.stderr | 20 +++++++++++++++++++ ...erce-issue-49593-box-never.fallback.stderr | 11 ++++++++++ ...ce-issue-49593-box-never.nofallback.stderr | 8 ++++---- .../coercion/coerce-issue-49593-box-never.rs | 9 +++++---- .../generic_arg_infer/issue-91614.stderr | 2 +- .../need_type_info/type-alias-indirect.stderr | 2 +- .../need_type_info/type-alias.stderr | 6 +++--- .../suggestions/mut-borrow-needed-by-trait.rs | 1 + .../mut-borrow-needed-by-trait.stderr | 16 ++++++++++++--- 13 files changed, 101 insertions(+), 22 deletions(-) create mode 100644 tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.rs create mode 100644 tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.stderr create mode 100644 tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.rs create mode 100644 tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.stderr create mode 100644 tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index e354e1ec59c63..affbaa9c456e9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -750,16 +750,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Resolves an associated value path into a base type and associated constant, or method /// resolution. The newly resolved definition is written into `type_dependent_defs`. + #[instrument(level = "trace", skip(self), ret)] pub fn resolve_ty_and_res_fully_qualified_call( &self, qpath: &'tcx QPath<'tcx>, hir_id: HirId, span: Span, ) -> (Res, Option>, &'tcx [hir::PathSegment<'tcx>]) { - debug!( - "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}", - qpath, hir_id, span - ); let (ty, qself, item_segment) = match *qpath { QPath::Resolved(ref opt_qself, path) => { return ( @@ -1419,10 +1416,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This also occurs for an enum variant on a type alias. let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); let self_ty = self.normalize(span, self_ty); - match self.at(&self.misc(span), self.param_env).eq( + match self.at(&self.misc(span), self.param_env).sub( DefineOpaqueTypes::No, - impl_ty, self_ty, + impl_ty, ) { Ok(ok) => self.register_infer_ok_obligations(ok), Err(_) => { diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.rs b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.rs new file mode 100644 index 0000000000000..e2fc2961a448d --- /dev/null +++ b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.rs @@ -0,0 +1,10 @@ +struct Fail; +//~^ ERROR: type parameter `T` is never used + +impl Fail { + const C: () = (); +} + +fn main() { + Fail::<()>::C +} diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.stderr new file mode 100644 index 0000000000000..c0ae634ab5513 --- /dev/null +++ b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type.stderr @@ -0,0 +1,12 @@ +error[E0392]: type parameter `T` is never used + --> $DIR/wrong-projection-self-ty-on-invalid-type.rs:1:13 + | +LL | struct Fail; + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0392`. diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.rs b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.rs new file mode 100644 index 0000000000000..cb53d902ba18a --- /dev/null +++ b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.rs @@ -0,0 +1,17 @@ +trait Proj { + type Assoc; +} +impl Proj for T { + type Assoc = T; +} + +struct Fail, U>(T); + +impl Fail { + const C: () = (); +} + +fn main() { + Fail::::C + //~^ ERROR: type mismatch +} diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.stderr new file mode 100644 index 0000000000000..a089a540074d7 --- /dev/null +++ b/tests/ui/associated-consts/wrong-projection-self-ty-on-invalid-type2.stderr @@ -0,0 +1,20 @@ +error[E0271]: type mismatch resolving `::Assoc == u32` + --> $DIR/wrong-projection-self-ty-on-invalid-type2.rs:15:5 + | +LL | Fail::::C + | ^^^^^^^^^^^^^^^^ type mismatch resolving `::Assoc == u32` + | +note: expected this to be `u32` + --> $DIR/wrong-projection-self-ty-on-invalid-type2.rs:5:18 + | +LL | type Assoc = T; + | ^ +note: required by a bound in `Fail` + --> $DIR/wrong-projection-self-ty-on-invalid-type2.rs:8:21 + | +LL | struct Fail, U>(T); + | ^^^^^^^^^ required by this bound in `Fail` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr new file mode 100644 index 0000000000000..e9b43d6145c2a --- /dev/null +++ b/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `(): std::error::Error` is not satisfied + --> $DIR/coerce-issue-49593-box-never.rs:19:5 + | +LL | Box::<_ /* ! */>::new(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` + | + = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr index 0d98fa93e5a4b..1215f5f9d885e 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr +++ b/tests/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied - --> $DIR/coerce-issue-49593-box-never.rs:18:53 + --> $DIR/coerce-issue-49593-box-never.rs:19:5 | -LL | /* *mut $0 is coerced to Box here */ Box::<_ /* ! */>::new(x) - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` +LL | Box::<_ /* ! */>::new(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` | = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>` error[E0277]: the trait bound `(): std::error::Error` is not satisfied - --> $DIR/coerce-issue-49593-box-never.rs:23:49 + --> $DIR/coerce-issue-49593-box-never.rs:24:49 | LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.rs b/tests/ui/coercion/coerce-issue-49593-box-never.rs index 19a2c036fbcb3..f93fbb70dce6d 100644 --- a/tests/ui/coercion/coerce-issue-49593-box-never.rs +++ b/tests/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,7 +1,6 @@ //@ revisions: nofallback fallback //@ ignore-windows - the number of `Error` impls is platform-dependent -//@[fallback] check-pass -//@[nofallback] check-fail +//@check-fail #![feature(never_type)] #![cfg_attr(fallback, feature(never_type_fallback))] @@ -15,8 +14,10 @@ fn raw_ptr_box(t: T) -> *mut T { } fn foo(x: !) -> Box { - /* *mut $0 is coerced to Box here */ Box::<_ /* ! */>::new(x) - //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied + // Subtyping during method resolution will generate new inference vars and + // subtype them. Thus fallback will not fall back to `!`, but `()` instead. + Box::<_ /* ! */>::new(x) + //~^ ERROR trait bound `(): std::error::Error` is not satisfied } fn foo_raw_ptr(x: !) -> *mut dyn Error { diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 5ee42c19dd3db..563406ad5eaa9 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -15,7 +15,7 @@ note: required by a bound in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the type for type parameter `T` is specified | -LL | let y: Mask<_, N> = Mask::<_, _>::splat(false); +LL | let y: Mask = Mask::<_, _>::splat(false); | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/inference/need_type_info/type-alias-indirect.stderr b/tests/ui/inference/need_type_info/type-alias-indirect.stderr index 535c0044aec03..5c5b4c149c170 100644 --- a/tests/ui/inference/need_type_info/type-alias-indirect.stderr +++ b/tests/ui/inference/need_type_info/type-alias-indirect.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/type-alias-indirect.rs:14:5 | LL | IndirectAlias::new(); - | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` error: aborting due to 1 previous error diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr index 2c39a3f56466f..fd9bcf2fe3f39 100644 --- a/tests/ui/inference/need_type_info/type-alias.stderr +++ b/tests/ui/inference/need_type_info/type-alias.stderr @@ -2,19 +2,19 @@ error[E0282]: type annotations needed --> $DIR/type-alias.rs:12:5 | LL | DirectAlias::new() - | ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectAlias` error[E0282]: type annotations needed --> $DIR/type-alias.rs:18:5 | LL | IndirectAlias::new(); - | ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias` error[E0282]: type annotations needed --> $DIR/type-alias.rs:32:5 | LL | DirectButWithDefaultAlias::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectButWithDefaultAlias` error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs index 66e1e77c905e0..924bfd82eb832 100644 --- a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs +++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs @@ -17,6 +17,7 @@ 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 } diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr index 09a9b1d3b3482..b2f9150142fe4 100644 --- a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -10,6 +10,16 @@ LL | let fp = BufWriter::new(fp); note: required by a bound in `BufWriter::::new` --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL +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` + | + = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` +note: required by a bound in `BufWriter` + --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL + error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | @@ -21,13 +31,13 @@ note: required by a bound in `BufWriter` --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:21:14 + --> $DIR/mut-borrow-needed-by-trait.rs:22:14 | LL | writeln!(fp, "hello world").unwrap(); | ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds | note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method - --> $DIR/mut-borrow-needed-by-trait.rs:21:14 + --> $DIR/mut-borrow-needed-by-trait.rs:22:14 | LL | writeln!(fp, "hello world").unwrap(); | ^^ @@ -35,7 +45,7 @@ LL | writeln!(fp, "hello world").unwrap(); `&dyn std::io::Write: std::io::Write` which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`.