diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 465508e12058f..ecf75411e5f2f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2725,7 +2725,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { a: ty::Region<'tcx>, b: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { - if (a.is_var() && b.is_free_or_static()) || (b.is_var() && a.is_free_or_static()) || a == b + if (a.is_var() && b.is_free_or_static()) + || (b.is_var() && a.is_free_or_static()) + || (a.is_var() && b.is_var()) + || a == b { Ok(a) } else { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index a93f9ec0397d2..54f01577c5e56 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -690,13 +690,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { real_trait_pred = parent_trait_pred; } - // Skipping binder here, remapping below - let real_ty = real_trait_pred.self_ty().skip_binder(); - if self.can_eq(obligation.param_env, real_ty, arg_ty).is_err() { + let real_ty = real_trait_pred.self_ty(); + // We `erase_late_bound_regions` here because `make_subregion` does not handle + // `ReLateBound`, and we don't particularly care about the regions. + if self + .can_eq(obligation.param_env, self.tcx.erase_late_bound_regions(real_ty), arg_ty) + .is_err() + { continue; } - if let ty::Ref(region, base_ty, mutbl) = *real_ty.kind() { + if let ty::Ref(region, base_ty, mutbl) = *real_ty.skip_binder().kind() { let mut autoderef = Autoderef::new( self, obligation.param_env, diff --git a/src/test/ui/generic-associated-types/issue-101020.rs b/src/test/ui/generic-associated-types/issue-101020.rs new file mode 100644 index 0000000000000..51cabe21e6291 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-101020.rs @@ -0,0 +1,37 @@ +#![feature(generic_associated_types)] + +pub trait LendingIterator { + type Item<'a> + where + Self: 'a; + + fn consume(self, _f: F) + where + Self: Sized, + for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>, + { + } +} + +impl LendingIterator for &mut I { + type Item<'a> = I::Item<'a> where Self: 'a; +} +struct EmptyIter; +impl LendingIterator for EmptyIter { + type Item<'a> = &'a mut () where Self:'a; +} +pub trait FuncInput<'a, F> +where + F: Foo, + Self: Sized, +{ +} +impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo {} +trait Foo {} + +fn map_test() { + (&mut EmptyIter).consume(()); + //~^ ERROR the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-101020.stderr b/src/test/ui/generic-associated-types/issue-101020.stderr new file mode 100644 index 0000000000000..7fde89eb75e51 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-101020.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied + --> $DIR/issue-101020.rs:33:5 + | +LL | (&mut EmptyIter).consume(()); + | ^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call + | | + | the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()` + | +note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>` + --> $DIR/issue-101020.rs:29:20 + | +LL | impl<'a, T, F: 'a> FuncInput<'a, F> for T where F: Foo {} + | ^^^^^^^^^^^^^^^^ ^ +note: required by a bound in `LendingIterator::consume` + --> $DIR/issue-101020.rs:11:33 + | +LL | fn consume(self, _f: F) + | ------- required by a bound in this +... +LL | for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `LendingIterator::consume` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.