Skip to content

Commit 0197366

Browse files
committed
Auto merge of rust-lang#127808 - oli-obk:tainting_visitors2, r=<try>
Make ErrorGuaranteed discoverable outside types, consts, and lifetimes types like `PatKind` could contain `ErrorGuaranteed`, but not return them via `tainted_by_errors` or `error_reported` (see rust-lang#127687 (comment)). Now this happens, but it's a bit fragile as you can see with the `TypeSuperVisitable for Ty` impl. We will catch any problems around Ty, Region or Const at runtime with an assert, and everything using derives will not have such issues, as it will just invoke the `TypeVisitable for ErrorGuaranteed` impl
2 parents 5572759 + 149fb97 commit 0197366

File tree

2 files changed

+29
-32
lines changed

2 files changed

+29
-32
lines changed

compiler/rustc_middle/src/ty/structural_impls.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ TrivialTypeTraversalImpls! {
257257
crate::ty::adjustment::PointerCoercion,
258258
::rustc_span::Span,
259259
::rustc_span::symbol::Ident,
260-
::rustc_errors::ErrorGuaranteed,
261260
ty::BoundVar,
262261
ty::ValTree<'tcx>,
263262
}
@@ -443,13 +442,14 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
443442
pat.visit_with(visitor)
444443
}
445444

445+
ty::Error(guar) => guar.visit_with(visitor),
446+
446447
ty::Bool
447448
| ty::Char
448449
| ty::Str
449450
| ty::Int(_)
450451
| ty::Uint(_)
451452
| ty::Float(_)
452-
| ty::Error(_)
453453
| ty::Infer(_)
454454
| ty::Bound(..)
455455
| ty::Placeholder(..)
@@ -602,6 +602,21 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
602602
}
603603
}
604604

605+
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
606+
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
607+
visitor.visit_error(*self)
608+
}
609+
}
610+
611+
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
612+
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
613+
self,
614+
_folder: &mut F,
615+
) -> Result<Self, F::Error> {
616+
Ok(self)
617+
}
618+
}
619+
605620
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst {
606621
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
607622
self,
@@ -617,12 +632,6 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
617632
}
618633
}
619634

620-
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
621-
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
622-
self.args.visit_with(visitor)
623-
}
624-
}
625-
626635
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
627636
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
628637
visitor.visit_ty(self.ty)

compiler/rustc_type_ir/src/visit.rs

+12-24
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ pub trait TypeVisitor<I: Interner>: Sized {
101101

102102
// The default region visitor is a no-op because `Region` is non-recursive
103103
// and has no `super_visit_with` method to call.
104-
fn visit_region(&mut self, _r: I::Region) -> Self::Result {
105-
Self::Result::output()
104+
fn visit_region(&mut self, r: I::Region) -> Self::Result {
105+
if let ty::ReError(guar) = r.kind() {
106+
self.visit_error(guar)
107+
} else {
108+
Self::Result::output()
109+
}
106110
}
107111

108112
fn visit_const(&mut self, c: I::Const) -> Self::Result {
@@ -116,6 +120,10 @@ pub trait TypeVisitor<I: Interner>: Sized {
116120
fn visit_clauses(&mut self, p: I::Clauses) -> Self::Result {
117121
p.super_visit_with(self)
118122
}
123+
124+
fn visit_error(&mut self, _guar: I::ErrorGuaranteed) -> Self::Result {
125+
Self::Result::output()
126+
}
119127
}
120128

121129
///////////////////////////////////////////////////////////////////////////
@@ -547,27 +555,7 @@ struct HasErrorVisitor;
547555
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
548556
type Result = ControlFlow<I::ErrorGuaranteed>;
549557

550-
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> Self::Result {
551-
if let ty::Error(guar) = t.kind() {
552-
ControlFlow::Break(guar)
553-
} else {
554-
t.super_visit_with(self)
555-
}
556-
}
557-
558-
fn visit_const(&mut self, c: <I as Interner>::Const) -> Self::Result {
559-
if let ty::ConstKind::Error(guar) = c.kind() {
560-
ControlFlow::Break(guar)
561-
} else {
562-
c.super_visit_with(self)
563-
}
564-
}
565-
566-
fn visit_region(&mut self, r: <I as Interner>::Region) -> Self::Result {
567-
if let ty::ReError(guar) = r.kind() {
568-
ControlFlow::Break(guar)
569-
} else {
570-
ControlFlow::Continue(())
571-
}
558+
fn visit_error(&mut self, guar: <I as Interner>::ErrorGuaranteed) -> Self::Result {
559+
ControlFlow::Break(guar)
572560
}
573561
}

0 commit comments

Comments
 (0)