diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 265bd55436a4f..53cf30673a907 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1473,6 +1473,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)] fn consider_probe( &self, self_ty: Ty<'tcx>, @@ -1483,20 +1484,31 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { Option>, )>, ) -> ProbeResult { - debug!("consider_probe: self_ty={:?} probe={:?}", self_ty, probe); - self.probe(|_| { // First check that the self type can be related. - let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup( - DefineOpaqueTypes::Yes, - probe.xform_self_ty, - self_ty, - ) { - Ok(InferOk { obligations, value: () }) => obligations, - Err(err) => { - debug!("--> cannot relate self-types {:?}", err); - return ProbeResult::NoMatch; + let sub_obligations = match self_ty.kind() { + // HACK: opaque types will match anything for which their bounds hold. + // Thus we need to prevent them from trying to match the `&_` autoref + // candidates that get created for `&self` trait methods. + ty::Alias(ty::Opaque, alias_ty) + if self.infcx.can_define_opaque_ty(alias_ty.def_id) => + { + if !probe.xform_self_ty.is_ty_var() { + return ProbeResult::NoMatch; + } + vec![] } + _ => match self.at(&ObligationCause::dummy(), self.param_env).sup( + DefineOpaqueTypes::Yes, + probe.xform_self_ty, + self_ty, + ) { + Ok(InferOk { obligations, value: () }) => obligations, + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); + return ProbeResult::NoMatch; + } + }, }; let mut result = ProbeResult::Match; diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 12e4f70ba5751..aab68b2dd60ce 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -162,7 +162,7 @@ pub struct CandidateStep<'tcx> { #[derive(Copy, Clone, Debug, HashStable)] pub struct MethodAutoderefStepsResult<'tcx> { - /// The valid autoderef steps that could be find. + /// The valid autoderef steps that could be found. pub steps: &'tcx [CandidateStep<'tcx>], /// If Some(T), a type autoderef reported an error on. pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>, diff --git a/tests/ui/impl-trait/method-resolution4.current.stderr b/tests/ui/impl-trait/method-resolution4.current.stderr deleted file mode 100644 index d87fda55d7204..0000000000000 --- a/tests/ui/impl-trait/method-resolution4.current.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:15:5 - | -LL | std::iter::empty() - | ^^^^^^^^^^^^^^^^^^ expected `&mut _`, found `Empty<_>` - | - = note: expected mutable reference `&mut _` - found struct `std::iter::Empty<_>` -help: consider mutably borrowing here - | -LL | &mut std::iter::empty() - | ++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr index 41e914c62f37d..b48de0af3579d 100644 --- a/tests/ui/impl-trait/method-resolution4.next.stderr +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -1,11 +1,11 @@ error[E0282]: type annotations needed - --> $DIR/method-resolution4.rs:12:9 + --> $DIR/method-resolution4.rs:13:9 | LL | foo(false).next().unwrap(); | ^^^^^^^^^^ cannot infer type error[E0308]: mismatched types - --> $DIR/method-resolution4.rs:15:5 + --> $DIR/method-resolution4.rs:16:5 | LL | fn foo(b: bool) -> impl Iterator { | ------------------------ the expected opaque type diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 8c6ff6ee9c894..91884eb59fd63 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -6,6 +6,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass fn foo(b: bool) -> impl Iterator { if b { @@ -13,7 +14,7 @@ fn foo(b: bool) -> impl Iterator { //[next]~^ type annotations needed } std::iter::empty() - //~^ mismatched types + //[next]~^ mismatched types } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr deleted file mode 100644 index 3b8f0bc5a5858..0000000000000 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0284]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:25:18 - | -LL | self.bar.next().unwrap(); - | ^^^^ - | - = note: cannot satisfy `<_ as Iterator>::Item == _` -help: try using a fully qualified path to specify the expected types - | -LL | <_ as Iterator>::next(self.bar).unwrap(); - | ++++++++++++++++++++++ ~ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index 8e6cb8b4d41a8..2617ce124c105 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:25:9 + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 | LL | self.bar.next().unwrap(); | ^^^^^^^^ cannot infer type diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs index 9a3ddf629f2c8..3635479f7d85f 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -7,6 +7,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass #![feature(type_alias_impl_trait)] @@ -23,7 +24,7 @@ impl Foo { fn foo(&mut self) { self.bar.next().unwrap(); - //~^ ERROR: type annotations needed + //[next]~^ ERROR: type annotations needed } }