diff options
Diffstat (limited to 'src/librustc_passes/ast_validation.rs')
| -rw-r--r-- | src/librustc_passes/ast_validation.rs | 131 |
1 files changed, 19 insertions, 112 deletions
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index d1a801b3006..4cf2a5f3584 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -9,7 +9,6 @@ use std::mem; use syntax::print::pprust; use rustc::lint; -use rustc::lint::builtin::{BuiltinLintDiagnostics, NESTED_IMPL_TRAIT}; use rustc::session::Session; use rustc_data_structures::fx::FxHashMap; use syntax::ast::*; @@ -23,31 +22,6 @@ use syntax::{span_err, struct_span_err, walk_list}; use syntax_pos::{Span, MultiSpan}; use errors::{Applicability, FatalError}; -#[derive(Copy, Clone, Debug)] -struct OuterImplTrait { - span: Span, - - /// rust-lang/rust#57979: a bug in original implementation caused - /// us to fail sometimes to record an outer `impl Trait`. - /// Therefore, in order to reliably issue a warning (rather than - /// an error) in the *precise* places where we are newly injecting - /// the diagnostic, we have to distinguish between the places - /// where the outer `impl Trait` has always been recorded, versus - /// the places where it has only recently started being recorded. - only_recorded_since_pull_request_57730: bool, -} - -impl OuterImplTrait { - /// This controls whether we should downgrade the nested impl - /// trait diagnostic to a warning rather than an error, based on - /// whether the outer impl trait had been improperly skipped in - /// earlier implementations of the analysis on the stable - /// compiler. - fn should_warn_instead_of_error(&self) -> bool { - self.only_recorded_since_pull_request_57730 - } -} - struct AstValidator<'a> { session: &'a Session, has_proc_macro_decls: bool, @@ -55,7 +29,7 @@ struct AstValidator<'a> { /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`. /// Nested `impl Trait` _is_ allowed in associated type position, /// e.g., `impl Iterator<Item = impl Debug>`. - outer_impl_trait: Option<OuterImplTrait>, + outer_impl_trait: Option<Span>, /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item` /// or `Foo::Bar<impl Trait>` @@ -65,26 +39,10 @@ struct AstValidator<'a> { /// certain positions. is_assoc_ty_bound_banned: bool, - /// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy - /// until PRs #57730 and #57981 landed: it would jump directly to - /// walk_ty rather than visit_ty (or skip recurring entirely for - /// impl trait in projections), and thus miss some cases. We track - /// whether we should downgrade to a warning for short-term via - /// these booleans. - warning_period_57979_didnt_record_next_impl_trait: bool, - warning_period_57979_impl_trait_in_proj: bool, - lint_buffer: &'a mut lint::LintBuffer, } impl<'a> AstValidator<'a> { - fn with_impl_trait_in_proj_warning<T>(&mut self, v: bool, f: impl FnOnce(&mut Self) -> T) -> T { - let old = mem::replace(&mut self.warning_period_57979_impl_trait_in_proj, v); - let ret = f(self); - self.warning_period_57979_impl_trait_in_proj = old; - ret - } - fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.is_impl_trait_banned, true); f(self); @@ -97,7 +55,7 @@ impl<'a> AstValidator<'a> { self.is_assoc_ty_bound_banned = old; } - fn with_impl_trait(&mut self, outer: Option<OuterImplTrait>, f: impl FnOnce(&mut Self)) { + fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.outer_impl_trait, outer); f(self); self.outer_impl_trait = old; @@ -105,14 +63,7 @@ impl<'a> AstValidator<'a> { fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) { match constraint.kind { - AssocTyConstraintKind::Equality { ref ty } => { - // rust-lang/rust#57979: bug in old `visit_generic_args` called - // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait` - // if it happened to occur at `ty`. - if let TyKind::ImplTrait(..) = ty.kind { - self.warning_period_57979_didnt_record_next_impl_trait = true; - } - } + AssocTyConstraintKind::Equality { .. } => {} AssocTyConstraintKind::Bound { .. } => { if self.is_assoc_ty_bound_banned { self.err_handler().span_err(constraint.span, @@ -124,37 +75,11 @@ impl<'a> AstValidator<'a> { self.visit_assoc_ty_constraint(constraint); } - fn visit_ty_from_generic_args(&mut self, ty: &'a Ty) { - // rust-lang/rust#57979: bug in old `visit_generic_args` called - // `walk_ty` rather than `visit_ty`, skippping outer `impl Trait` - // if it happened to occur at `ty`. - if let TyKind::ImplTrait(..) = ty.kind { - self.warning_period_57979_didnt_record_next_impl_trait = true; - } - self.visit_ty(ty); - } - - fn outer_impl_trait(&mut self, span: Span) -> OuterImplTrait { - let only_recorded_since_pull_request_57730 = - self.warning_period_57979_didnt_record_next_impl_trait; - - // (This flag is designed to be set to `true`, and then only - // reach the construction point for the outer impl trait once, - // so its safe and easiest to unconditionally reset it to - // false.) - self.warning_period_57979_didnt_record_next_impl_trait = false; - - OuterImplTrait { - span, only_recorded_since_pull_request_57730, - } - } - // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { match t.kind { TyKind::ImplTrait(..) => { - let outer_impl_trait = self.outer_impl_trait(t.span); - self.with_impl_trait(Some(outer_impl_trait), |this| visit::walk_ty(this, t)) + self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) } TyKind::Path(ref qself, ref path) => { // We allow these: @@ -484,32 +409,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } TyKind::ImplTrait(_, ref bounds) => { if self.is_impl_trait_banned { - if self.warning_period_57979_impl_trait_in_proj { - self.lint_buffer.buffer_lint( - NESTED_IMPL_TRAIT, ty.id, ty.span, - "`impl Trait` is not allowed in path parameters"); - } else { - struct_span_err!(self.session, ty.span, E0667, - "`impl Trait` is not allowed in path parameters").emit(); - } + struct_span_err!( + self.session, ty.span, E0667, + "`impl Trait` is not allowed in path parameters" + ) + .emit(); } - if let Some(outer_impl_trait) = self.outer_impl_trait { - if outer_impl_trait.should_warn_instead_of_error() { - self.lint_buffer.buffer_lint_with_diagnostic( - NESTED_IMPL_TRAIT, ty.id, ty.span, - "nested `impl Trait` is not allowed", - BuiltinLintDiagnostics::NestedImplTrait { - outer_impl_trait_span: outer_impl_trait.span, - inner_impl_trait_span: ty.span, - }); - } else { - struct_span_err!(self.session, ty.span, E0666, - "nested `impl Trait` is not allowed") - .span_label(outer_impl_trait.span, "outer `impl Trait`") - .span_label(ty.span, "nested `impl Trait` here") - .emit(); - } + if let Some(outer_impl_trait_sp) = self.outer_impl_trait { + struct_span_err!( + self.session, ty.span, E0666, + "nested `impl Trait` is not allowed" + ) + .span_label(outer_impl_trait_sp, "outer `impl Trait`") + .span_label(ty.span, "nested `impl Trait` here") + .emit(); } if !bounds.iter() @@ -517,7 +431,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.err_handler().span_err(ty.span, "at least one trait must be specified"); } - self.with_impl_trait_in_proj_warning(true, |this| this.walk_ty(ty)); + self.walk_ty(ty); return; } _ => {} @@ -654,11 +568,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ItemKind::Mod(_) => { // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). attr::first_attr_value_str_by_name(&item.attrs, sym::path); - if attr::contains_name(&item.attrs, sym::warn_directory_ownership) { - let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP; - let msg = "cannot declare a new module at this location"; - self.lint_buffer.buffer_lint(lint, item.id, item.span, msg); - } } ItemKind::Union(ref vdata, _) => { if let VariantData::Tuple(..) | VariantData::Unit(..) = vdata { @@ -731,7 +640,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let Some(ref type_) = data.output { // `-> Foo` syntax is essentially an associated type binding, // so it is also allowed to contain nested `impl Trait`. - self.with_impl_trait(None, |this| this.visit_ty_from_generic_args(type_)); + self.with_impl_trait(None, |this| this.visit_ty(type_)); } } } @@ -849,8 +758,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe outer_impl_trait: None, is_impl_trait_banned: false, is_assoc_ty_bound_banned: false, - warning_period_57979_didnt_record_next_impl_trait: false, - warning_period_57979_impl_trait_in_proj: false, lint_buffer: lints, }; visit::walk_crate(&mut validator, krate); |
