Rollup merge of #103488 - oli-obk:impl_trait_for_tait, r=lcnr
Allow opaque types in trait impl headers and rely on coherence to reject unsound cases r? ````@lcnr```` fixes #99840
This commit is contained in:
commit
53eab246db
75 changed files with 545 additions and 313 deletions
|
@ -244,6 +244,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
|
|||
self.tcx
|
||||
}
|
||||
|
||||
fn intercrate(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.param_env
|
||||
}
|
||||
|
@ -256,6 +260,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
|
|||
true
|
||||
}
|
||||
|
||||
fn mark_ambiguous(&mut self) {
|
||||
bug!()
|
||||
}
|
||||
|
||||
fn relate_with_variance<T: Relate<'tcx>>(
|
||||
&mut self,
|
||||
_: ty::Variance,
|
||||
|
|
|
@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::{struct_span_err, DelayDm};
|
||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::util::IgnoreRegions;
|
||||
use rustc_middle::ty::{
|
||||
|
@ -47,58 +46,6 @@ fn do_orphan_check_impl<'tcx>(
|
|||
let sp = tcx.def_span(def_id);
|
||||
let tr = impl_.of_trait.as_ref().unwrap();
|
||||
|
||||
// Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
|
||||
// and #84660 where it would otherwise allow unsoundness.
|
||||
if trait_ref.has_opaque_types() {
|
||||
trace!("{:#?}", item);
|
||||
// First we find the opaque type in question.
|
||||
for ty in trait_ref.substs {
|
||||
for ty in ty.walk() {
|
||||
let ty::subst::GenericArgKind::Type(ty) = ty.unpack() else { continue };
|
||||
let ty::Opaque(def_id, _) = *ty.kind() else { continue };
|
||||
trace!(?def_id);
|
||||
|
||||
// Then we search for mentions of the opaque type's type alias in the HIR
|
||||
struct SpanFinder<'tcx> {
|
||||
sp: Span,
|
||||
def_id: DefId,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
impl<'v, 'tcx> hir::intravisit::Visitor<'v> for SpanFinder<'tcx> {
|
||||
#[instrument(level = "trace", skip(self, _id))]
|
||||
fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) {
|
||||
// You can't mention an opaque type directly, so we look for type aliases
|
||||
if let hir::def::Res::Def(hir::def::DefKind::TyAlias, def_id) = path.res {
|
||||
// And check if that type alias's type contains the opaque type we're looking for
|
||||
for arg in self.tcx.type_of(def_id).walk() {
|
||||
if let GenericArgKind::Type(ty) = arg.unpack() {
|
||||
if let ty::Opaque(def_id, _) = *ty.kind() {
|
||||
if def_id == self.def_id {
|
||||
// Finally we update the span to the mention of the type alias
|
||||
self.sp = path.span;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::intravisit::walk_path(self, path)
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = SpanFinder { sp, def_id, tcx };
|
||||
hir::intravisit::walk_item(&mut visitor, item);
|
||||
let reported = tcx
|
||||
.sess
|
||||
.struct_span_err(visitor.sp, "cannot implement trait on type alias impl trait")
|
||||
.span_note(tcx.def_span(def_id), "type alias impl trait defined here")
|
||||
.emit();
|
||||
return Err(reported);
|
||||
}
|
||||
}
|
||||
span_bug!(sp, "opaque type not found, but `has_opaque_types` is set")
|
||||
}
|
||||
|
||||
match traits::orphan_check(tcx, item.owner_id.to_def_id()) {
|
||||
Ok(()) => {}
|
||||
Err(err) => emit_orphan_check_error(
|
||||
|
|
|
@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>(
|
|||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::Ambiguous
|
||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
|||
| ty::PredicateKind::Coerce(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::Ambiguous
|
||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue