Skip to content

Commit

Permalink
Rollup merge of #116149 - compiler-errors:anonymize, r=lcnr
Browse files Browse the repository at this point in the history
Anonymize binders for `refining_impl_trait` check

We're naively using the equality impl for `ty::Clause` in the refinement check, which is okay *except* for binders, which carry some information about where they come from in the AST. Those locations are not gonna be equal between traits and impls, so anonymize those clauses so that this doesn't matter.

Fixes #116135
  • Loading branch information
matthiaskrgr authored Sep 27, 2023
2 parents d485887 + 305524d commit 50417a5
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
29 changes: 25 additions & 4 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
use rustc_lint_defs::builtin::REFINING_IMPL_TRAIT;
use rustc_middle::traits::{ObligationCause, Reveal};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
};
use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::traits::{
Expand Down Expand Up @@ -176,9 +176,13 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
return;
};

// For quicker lookup, use an `IndexSet`
// (we don't use one earlier because it's not foldable..)
let trait_bounds = FxIndexSet::from_iter(trait_bounds);
// For quicker lookup, use an `IndexSet` (we don't use one earlier because
// it's not foldable..).
// Also, We have to anonymize binders in these types because they may contain
// `BrNamed` bound vars, which contain unique `DefId`s which correspond to syntax
// locations that we don't care about when checking bound equality.
let trait_bounds = FxIndexSet::from_iter(trait_bounds.fold_with(&mut Anonymize { tcx }));
let impl_bounds = impl_bounds.fold_with(&mut Anonymize { tcx });

// Find any clauses that are present in the impl's RPITITs that are not
// present in the trait's RPITITs. This will trigger on trivial predicates,
Expand Down Expand Up @@ -309,3 +313,20 @@ fn type_visibility<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<ty::Visibili
_ => None,
}
}

struct Anonymize<'tcx> {
tcx: TyCtxt<'tcx>,
}

impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Anonymize<'tcx> {
fn interner(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
self.tcx.anonymize_bound_vars(t)
}
}
13 changes: 13 additions & 0 deletions tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// compile-flags: --crate-type=lib
// check-pass

#![feature(return_position_impl_trait_in_trait)]
#![deny(refining_impl_trait)]

pub trait Tr<T> {
fn foo() -> impl for<'a> Tr<&'a Self>;
}

impl<T> Tr<T> for () {
fn foo() -> impl for<'a> Tr<&'a Self> {}
}

0 comments on commit 50417a5

Please sign in to comment.