diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 690ed9decb9..6505803eba8 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -233,8 +233,6 @@ fn configure_and_expand_inner<'a>( resolver_arenas: &'a ResolverArenas<'a>, metadata_loader: &'a MetadataLoaderDyn, ) -> Result<(ast::Crate, Resolver<'a>)> { - use rustc_resolve::IgnoreState; - log::trace!("configure_and_expand_inner"); pre_expansion_lint(sess, lint_store, &krate); @@ -413,10 +411,7 @@ fn configure_and_expand_inner<'a>( println!("{}", json::as_json(&krate)); } - // If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items. - let ignore_bodies = - if sess.opts.actually_rustdoc { IgnoreState::Ignore } else { IgnoreState::Report }; - resolver.resolve_crate(&krate, ignore_bodies); + resolver.resolve_crate(&krate); // Needs to go *after* expansion to be able to check the results of macro expansion. sess.time("complete_gated_feature_checking", || { diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 637326bb88d..528444b0e98 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -376,19 +376,6 @@ struct DiagnosticMetadata<'ast> { current_let_binding: Option<(Span, Option, Option)>, } -/// Keeps track of whether errors should be reported. -/// -/// Used by rustdoc to ignore errors in function bodies. -/// This is just a fancy boolean so it can have doc-comments. -#[derive(Copy, Clone, Debug)] -pub enum IgnoreState { - /// We are at global scope or in a trait implementation, so all errors should be reported. - Report, - /// We are in a function body, so errors shouldn't be reported. - Ignore, - // Note that we don't need to worry about macros, which must always be resolved (or we wouldn't have gotten to the late pass). -} - struct LateResolutionVisitor<'a, 'b, 'ast> { r: &'b mut Resolver<'a>, @@ -408,12 +395,12 @@ struct LateResolutionVisitor<'a, 'b, 'ast> { /// Fields used to add information to diagnostic errors. diagnostic_metadata: DiagnosticMetadata<'ast>, - /// State used to know whether to ignore resolution errors for item bodies. + /// State used to know whether to ignore resolution errors for function bodies. /// /// In particular, rustdoc uses this to avoid giving errors for `cfg()` items. /// In most cases this will be `None`, in which case errors will always be reported. /// If it is `Some(_)`, then it will be updated when entering a nested function or trait body. - ignore_bodies: Option, + in_func_body: bool, } /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes. @@ -517,10 +504,10 @@ fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) { visit::walk_fn_ret_ty(this, &declaration.output); - let previous_ignore = this.ignore_bodies.take(); - // Ignore errors in function bodies if originally passed `ignore_state: true` + let previous_state = this.in_func_body; + // Ignore errors in function bodies if this is rustdoc // Be sure not to set this until the function signature has been resolved. - this.ignore_bodies = previous_ignore.and(Some(IgnoreState::Ignore)); + this.in_func_body = true; // Resolve the function body, potentially inside the body of an async closure match fn_kind { FnKind::Fn(.., body) => walk_list!(this, visit_block, body), @@ -528,7 +515,7 @@ fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) { }; debug!("(resolving function) leaving function"); - this.ignore_bodies = previous_ignore; + this.in_func_body = previous_state; }) }); self.diagnostic_metadata.current_function = previous_value; @@ -652,10 +639,7 @@ fn visit_generic_arg(&mut self, arg: &'ast GenericArg) { } impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { - fn new( - resolver: &'b mut Resolver<'a>, - ignore_bodies: IgnoreState, - ) -> LateResolutionVisitor<'a, 'b, 'ast> { + fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b, 'ast> { // During late resolution we only track the module component of the parent scope, // although it may be useful to track other components as well for diagnostics. let graph_root = resolver.graph_root; @@ -672,11 +656,8 @@ fn new( label_ribs: Vec::new(), current_trait_ref: None, diagnostic_metadata: DiagnosticMetadata::default(), - ignore_bodies: match ignore_bodies { - // errors at module scope should always be reported - IgnoreState::Ignore => Some(IgnoreState::Report), - IgnoreState::Report => None, - }, + // errors at module scope should always be reported + in_func_body: false, } } @@ -1194,9 +1175,9 @@ fn resolve_implementation( impl_items: &'ast [P], ) { debug!("resolve_implementation"); - let old_ignore = self.ignore_bodies.take(); + let old_ignore = self.in_func_body; // Never ignore errors in trait implementations. - self.ignore_bodies = old_ignore.and(Some(IgnoreState::Report)); + self.in_func_body = false; // If applicable, create a rib for the type parameters. self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { // Dummy self type for better errors if `Self` is used in the trait path. @@ -1292,7 +1273,7 @@ fn resolve_implementation( }); }); }); - self.ignore_bodies = old_ignore; + self.in_func_body = old_ignore; } fn check_trait_item(&mut self, ident: Ident, ns: Namespace, span: Span, err: F) @@ -1900,7 +1881,7 @@ fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool /// A wrapper around [`Resolver::report_error`]. /// - /// This doesn't emit errors for function bodies if `ignore_bodies` is set. + /// This doesn't emit errors for function bodies if this is r fn report_error(&self, span: Span, resolution_error: ResolutionError<'_>) { if self.should_report_errs() { self.r.report_error(span, resolution_error); @@ -1908,12 +1889,9 @@ fn report_error(&self, span: Span, resolution_error: ResolutionError<'_>) { } #[inline] + /// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items. fn should_report_errs(&self) -> bool { - debug!("should_report_errs(state={:?})", self.ignore_bodies); - match self.ignore_bodies { - None | Some(IgnoreState::Report) => true, - Some(IgnoreState::Ignore) => false, - } + !(self.r.session.opts.actually_rustdoc && self.in_func_body) } // Resolve in alternative namespaces if resolution in the primary namespace fails. @@ -2412,8 +2390,8 @@ fn find_transitive_imports( } impl<'a> Resolver<'a> { - pub(crate) fn late_resolve_crate(&mut self, krate: &Crate, ignore_bodies: IgnoreState) { - let mut late_resolution_visitor = LateResolutionVisitor::new(self, ignore_bodies); + pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) { + let mut late_resolution_visitor = LateResolutionVisitor::new(self); visit::walk_crate(&mut late_resolution_visitor, krate); for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() { self.lint_buffer.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label"); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 23bd0028bd1..a265c15c18b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -15,7 +15,6 @@ #![feature(or_patterns)] #![recursion_limit = "256"] -pub use late::IgnoreState; pub use rustc_hir::def::{Namespace, PerNS}; use Determinacy::*; @@ -1442,13 +1441,13 @@ fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId { } /// Entry point to crate resolution. - pub fn resolve_crate(&mut self, krate: &Crate, ignore_bodies: IgnoreState) { + pub fn resolve_crate(&mut self, krate: &Crate) { let _prof_timer = self.session.prof.generic_activity("resolve_crate"); ImportResolver { r: self }.finalize_imports(); self.finalize_macro_resolutions(); - self.late_resolve_crate(krate, ignore_bodies); + self.late_resolve_crate(krate); self.check_unused(krate); self.report_errors(krate);