Skip to content

Commit

Permalink
Auto merge of #78779 - LeSeulArtichaut:ty-visitor-return, r=oli-obk
Browse files Browse the repository at this point in the history
Introduce `TypeVisitor::BreakTy`

Implements MCP rust-lang/compiler-team#383.
r? `@ghost`
cc `@lcnr` `@oli-obk`

~~Blocked on FCP in rust-lang/compiler-team#383.~~
  • Loading branch information
bors committed Nov 17, 2020
2 parents efcb3b3 + f6e6a15 commit e0ef0fc
Show file tree
Hide file tree
Showing 32 changed files with 232 additions and 213 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<()> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if let Some((kind, def_id)) = TyCategory::from_ty(t) {
let span = self.tcx.def_span(def_id);
// Avoid cluttering the output when the "found" and error span overlap:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
struct TraitObjectVisitor(Vec<DefId>);

impl TypeVisitor<'_> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<()> {
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Dynamic(preds, RegionKind::ReStatic) => {
if let Some(def_id) = preds.principal_def_id() {
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! See the Book for more information.
pub use self::freshen::TypeFreshener;
pub use self::LateBoundRegionConversionTime::*;
pub use self::RegionVariableOrigin::*;
Expand Down Expand Up @@ -1334,9 +1332,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
where
T: TypeFoldable<'tcx>,
{
let mut r = resolve::UnresolvedTypeFinder::new(self);
value.visit_with(&mut r);
r.first_unresolved
value.visit_with(&mut resolve::UnresolvedTypeFinder::new(self)).break_value()
}

pub fn probe_const_var(
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_infer/src/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,15 +741,18 @@ struct ScopeInstantiator<'me, 'tcx> {
}

impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ControlFlow<()> {
fn visit_binder<T: TypeFoldable<'tcx>>(
&mut self,
t: &ty::Binder<T>,
) -> ControlFlow<Self::BreakTy> {
self.target_index.shift_in(1);
t.super_visit_with(self);
self.target_index.shift_out(1);

ControlFlow::CONTINUE
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<()> {
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
let ScopeInstantiator { bound_region_scope, next_region, .. } = self;

match r {
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_infer/src/infer/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,17 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
/// involve some hashing and so forth).
pub struct UnresolvedTypeFinder<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,

/// Used to find the type parameter name and location for error reporting.
pub first_unresolved: Option<(Ty<'tcx>, Option<Span>)>,
}

impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
UnresolvedTypeFinder { infcx, first_unresolved: None }
UnresolvedTypeFinder { infcx }
}
}

impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<()> {
type BreakTy = (Ty<'tcx>, Option<Span>);
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
let t = self.infcx.shallow_resolve(t);
if t.has_infer_types() {
if let ty::Infer(infer_ty) = *t.kind() {
Expand All @@ -144,8 +142,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
} else {
None
};
self.first_unresolved = Some((t, ty_var_span));
ControlFlow::BREAK
ControlFlow::Break((t, ty_var_span))
} else {
// Otherwise, visit its contents.
t.super_visit_with(self)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx
}
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.predicate.visit_with(visitor)
}
}
14 changes: 5 additions & 9 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1131,16 +1131,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
struct ProhibitOpaqueTypes<'a, 'tcx> {
cx: &'a LateContext<'tcx>,
ty: Option<Ty<'tcx>>,
};

impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<()> {
type BreakTy = Ty<'tcx>;

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match ty.kind() {
ty::Opaque(..) => {
self.ty = Some(ty);
ControlFlow::BREAK
}
ty::Opaque(..) => ControlFlow::Break(ty),
// Consider opaque types within projections FFI-safe if they do not normalize
// to more opaque types.
ty::Projection(..) => {
Expand All @@ -1159,9 +1157,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
}
}

let mut visitor = ProhibitOpaqueTypes { cx: self.cx, ty: None };
ty.visit_with(&mut visitor);
if let Some(ty) = visitor.ty {
if let Some(ty) = ty.visit_with(&mut ProhibitOpaqueTypes { cx: self.cx }).break_value() {
self.emit_ffi_unsafe_type_lint(ty, sp, "opaque types have no C equivalent", None);
true
} else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_macros/src/type_foldable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
&self,
__folder: &mut __F
) -> ::std::ops::ControlFlow<()> {
) -> ::std::ops::ControlFlow<__F::BreakTy> {
match *self { #body_visit }
::std::ops::ControlFlow::CONTINUE
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#![feature(half_open_range_patterns)]
#![feature(exclusive_range_pattern)]
#![feature(control_flow_enum)]
#![feature(associated_type_defaults)]
#![recursion_limit = "512"]

#[macro_use]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ macro_rules! TrivialTypeFoldableImpls {
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
_: &mut F)
-> ::std::ops::ControlFlow<()>
-> ::std::ops::ControlFlow<F::BreakTy>
{
::std::ops::ControlFlow::CONTINUE
}
Expand Down Expand Up @@ -105,7 +105,7 @@ macro_rules! EnumTypeFoldableImpl {
fn super_visit_with<V: $crate::ty::fold::TypeVisitor<$tcx>>(
&self,
visitor: &mut V,
) -> ::std::ops::ControlFlow<()> {
) -> ::std::ops::ControlFlow<V::BreakTy> {
EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output())
}
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2464,7 +2464,10 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
}
}

fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<()> {
fn super_visit_with<Vs: TypeVisitor<'tcx>>(
&self,
visitor: &mut Vs,
) -> ControlFlow<Vs::BreakTy> {
self.base.visit_with(visitor)
// Note: there's nothing in `self.proj` to visit.
}
Expand Down
25 changes: 14 additions & 11 deletions compiler/rustc_middle/src/mir/type_foldable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
Terminator { source_info: self.source_info, kind }
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::mir::TerminatorKind::*;

match self.kind {
Expand Down Expand Up @@ -144,7 +144,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
self
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
Expand All @@ -154,7 +154,7 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.local.visit_with(visitor)?;
self.projection.visit_with(visitor)
}
Expand All @@ -165,7 +165,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}
Expand Down Expand Up @@ -211,7 +211,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
}
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
use crate::mir::Rvalue::*;
match *self {
Use(ref op) => op.visit_with(visitor),
Expand Down Expand Up @@ -266,7 +266,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
}
}

fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
match *self {
Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
Operand::Constant(ref c) => c.visit_with(visitor),
Expand All @@ -290,7 +290,10 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
}
}

fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<()> {
fn super_visit_with<Vs: TypeVisitor<'tcx>>(
&self,
visitor: &mut Vs,
) -> ControlFlow<Vs::BreakTy> {
use crate::mir::ProjectionElem::*;

match self {
Expand All @@ -305,7 +308,7 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
self
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
Expand All @@ -314,7 +317,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
self
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
Expand All @@ -323,7 +326,7 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
self
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
ControlFlow::CONTINUE
}
}
Expand All @@ -336,7 +339,7 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
literal: self.literal.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<()> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.literal.visit_with(visitor)
}
}
Loading

0 comments on commit e0ef0fc

Please sign in to comment.