Skip to content

Commit 532fd39

Browse files
Make bound_context more like neighboring functions
1 parent 76ce7a0 commit 532fd39

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

src/librustc_passes/ast_validation.rs

+18-21
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use syntax::{span_err, struct_span_err, walk_list};
2424

2525
use rustc_error_codes::*;
2626

27+
/// A syntactic context that disallows certain kinds of bounds (e.g., `?Trait` or `?const Trait`).
2728
#[derive(Clone, Copy)]
2829
enum BoundContext {
2930
ImplTrait,
@@ -50,10 +51,11 @@ struct AstValidator<'a> {
5051
/// e.g., `impl Iterator<Item = impl Debug>`.
5152
outer_impl_trait: Option<Span>,
5253

53-
/// Tracks the context in which a bound can appear.
54+
/// Keeps track of the `BoundContext` as we recurse.
5455
///
55-
/// This is used to forbid `?const Trait` bounds in certain contexts.
56-
bound_context_stack: Vec<Option<BoundContext>>,
56+
/// This is used to forbid `?const Trait` bounds in, e.g.,
57+
/// `impl Iterator<Item = Box<dyn ?const Trait>`.
58+
bound_context: Option<BoundContext>,
5759

5860
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
5961
/// or `Foo::Bar<impl Trait>`
@@ -80,21 +82,19 @@ impl<'a> AstValidator<'a> {
8082
}
8183

8284
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
83-
self.bound_context_stack.push(outer.map(|_| BoundContext::ImplTrait));
8485
let old = mem::replace(&mut self.outer_impl_trait, outer);
85-
f(self);
86+
if outer.is_some() {
87+
self.with_bound_context(BoundContext::ImplTrait, |this| f(this));
88+
} else {
89+
f(self)
90+
}
8691
self.outer_impl_trait = old;
87-
self.bound_context_stack.pop();
8892
}
8993

90-
fn with_bound_context(&mut self, ctx: Option<BoundContext>, f: impl FnOnce(&mut Self)) {
91-
self.bound_context_stack.push(ctx);
94+
fn with_bound_context(&mut self, ctx: BoundContext, f: impl FnOnce(&mut Self)) {
95+
let old = self.bound_context.replace(ctx);
9296
f(self);
93-
self.bound_context_stack.pop();
94-
}
95-
96-
fn innermost_bound_context(&mut self) -> Option<BoundContext> {
97-
self.bound_context_stack.iter().rev().find(|x| x.is_some()).copied().flatten()
97+
self.bound_context = old;
9898
}
9999

100100
fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) {
@@ -119,9 +119,7 @@ impl<'a> AstValidator<'a> {
119119
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
120120
}
121121
TyKind::TraitObject(..) => {
122-
self.with_bound_context(Some(BoundContext::TraitObject), |this| {
123-
visit::walk_ty(this, t)
124-
});
122+
self.with_bound_context(BoundContext::TraitObject, |this| visit::walk_ty(this, t));
125123
}
126124
TyKind::Path(ref qself, ref path) => {
127125
// We allow these:
@@ -231,8 +229,7 @@ impl<'a> AstValidator<'a> {
231229
}
232230
}
233231

234-
// FIXME(ecstaticmorse): Instead, use the `bound_context_stack` to check this in
235-
// `visit_param_bound`.
232+
// FIXME(ecstaticmorse): Instead, use `bound_context` to check this in `visit_param_bound`.
236233
fn no_questions_in_bounds(&self, bounds: &GenericBounds, where_: &str, is_trait: bool) {
237234
for bound in bounds {
238235
if let GenericBound::Trait(ref poly, TraitBoundModifier::Maybe) = *bound {
@@ -725,7 +722,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
725722
self.visit_vis(&item.vis);
726723
self.visit_ident(item.ident);
727724
self.visit_generics(generics);
728-
self.with_bound_context(Some(BoundContext::TraitBounds), |this| {
725+
self.with_bound_context(BoundContext::TraitBounds, |this| {
729726
walk_list!(this, visit_param_bound, bounds);
730727
});
731728
walk_list!(self, visit_trait_item, trait_items);
@@ -884,7 +881,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
884881
.span_err(bound.span(), "`?const` and `?` are mutually exclusive");
885882
}
886883

887-
if let Some(ctx) = self.innermost_bound_context() {
884+
if let Some(ctx) = self.bound_context {
888885
let msg = format!("`?const` is not permitted in {}", ctx.description());
889886
self.err_handler().span_err(bound.span(), &msg);
890887
}
@@ -1006,7 +1003,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe
10061003
session,
10071004
has_proc_macro_decls: false,
10081005
outer_impl_trait: None,
1009-
bound_context_stack: Vec::new(),
1006+
bound_context: None,
10101007
is_impl_trait_banned: false,
10111008
is_assoc_ty_bound_banned: false,
10121009
lint_buffer: lints,

0 commit comments

Comments
 (0)