mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Rollup merge of #116149 - compiler-errors:anonymize, r=lcnr
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
This commit is contained in:
commit
50417a5457
@ -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::{
|
||||
@ -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,
|
||||
@ -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
tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
Normal file
13
tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
Normal file
@ -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> {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user