Skip to content

Commit a5275ff

Browse files
committed
Don't run everybody_loops for rustdoc
Instead, ignore resolution errors that occur in item bodies. The reason this can't ignore item bodies altogether is because `const fn` could be used in generic types, for example `[T; f()]`
1 parent f6764c4 commit a5275ff

File tree

4 files changed

+50
-29
lines changed

4 files changed

+50
-29
lines changed

src/librustc_interface/passes.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -354,24 +354,13 @@ fn configure_and_expand_inner<'a>(
354354
)
355355
});
356356

357-
// If we're actually rustdoc then there's no need to actually compile
358-
// anything, so switch everything to just looping
359-
let mut should_loop = sess.opts.actually_rustdoc;
360-
if let Some(PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops)) = sess.opts.pretty {
361-
should_loop |= true;
362-
}
363-
if should_loop {
364-
log::debug!("replacing bodies with loop {{}}");
365-
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
366-
}
357+
let crate_types = sess.crate_types();
358+
let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
367359

368360
let has_proc_macro_decls = sess.time("AST_validation", || {
369361
rustc_ast_passes::ast_validation::check_crate(sess, &krate, &mut resolver.lint_buffer())
370362
});
371363

372-
let crate_types = sess.crate_types();
373-
let is_proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
374-
375364
// For backwards compatibility, we don't try to run proc macro injection
376365
// if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being
377366
// specified. This should only affect users who manually invoke 'rustdoc', as
@@ -417,7 +406,19 @@ fn configure_and_expand_inner<'a>(
417406
println!("{}", json::as_json(&krate));
418407
}
419408

420-
resolver.resolve_crate(&krate);
409+
// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items.
410+
// anything, so switch everything to just looping
411+
resolver.resolve_crate(&krate, sess.opts.actually_rustdoc);
412+
413+
//let mut should_loop = sess.opts.actually_rustdoc;
414+
let mut should_loop = false;
415+
if let Some(PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops)) = sess.opts.pretty {
416+
should_loop |= true;
417+
}
418+
if should_loop {
419+
log::debug!("replacing bodies with loop {{}}");
420+
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
421+
}
421422

422423
// Needs to go *after* expansion to be able to check the results of macro expansion.
423424
sess.time("complete_gated_feature_checking", || {

src/librustc_resolve/late.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
394394

395395
/// Fields used to add information to diagnostic errors.
396396
diagnostic_metadata: DiagnosticMetadata<'ast>,
397+
398+
/// Whether to report resolution errors for item bodies.
399+
///
400+
/// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.
401+
ignore_bodies: bool,
397402
}
398403

399404
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
@@ -627,7 +632,10 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
627632
}
628633

629634
impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
630-
fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b, 'ast> {
635+
fn new(
636+
resolver: &'b mut Resolver<'a>,
637+
ignore_bodies: bool,
638+
) -> LateResolutionVisitor<'a, 'b, 'ast> {
631639
// During late resolution we only track the module component of the parent scope,
632640
// although it may be useful to track other components as well for diagnostics.
633641
let graph_root = resolver.graph_root;
@@ -644,6 +652,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
644652
label_ribs: Vec::new(),
645653
current_trait_ref: None,
646654
diagnostic_metadata: DiagnosticMetadata::default(),
655+
ignore_bodies,
647656
}
648657
}
649658

@@ -757,7 +766,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
757766
return if self.is_label_valid_from_rib(i) {
758767
Some(*id)
759768
} else {
760-
self.r.report_error(
769+
self.report_error(
761770
original_span,
762771
ResolutionError::UnreachableLabel {
763772
name: label.name,
@@ -775,7 +784,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
775784
suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label));
776785
}
777786

778-
self.r.report_error(
787+
self.report_error(
779788
original_span,
780789
ResolutionError::UndeclaredLabel { name: label.name, suggestion },
781790
);
@@ -1008,7 +1017,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
10081017
if seen_bindings.contains_key(&ident) {
10091018
let span = seen_bindings.get(&ident).unwrap();
10101019
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, *span);
1011-
self.r.report_error(param.ident.span, err);
1020+
self.report_error(param.ident.span, err);
10121021
}
10131022
seen_bindings.entry(ident).or_insert(param.ident.span);
10141023

@@ -1274,7 +1283,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
12741283
.is_err()
12751284
{
12761285
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
1277-
self.r.report_error(span, err(ident.name, &path_names_to_string(path)));
1286+
self.report_error(span, err(ident.name, &path_names_to_string(path)));
12781287
}
12791288
}
12801289
}
@@ -1390,7 +1399,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13901399
if inconsistent_vars.contains_key(name) {
13911400
v.could_be_path = false;
13921401
}
1393-
self.r.report_error(
1402+
self.report_error(
13941403
*v.origin.iter().next().unwrap(),
13951404
ResolutionError::VariableNotBoundInPattern(v),
13961405
);
@@ -1400,7 +1409,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14001409
let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
14011410
inconsistent_vars.sort();
14021411
for (name, v) in inconsistent_vars {
1403-
self.r.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
1412+
self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
14041413
}
14051414

14061415
// 5) Finally bubble up all the binding maps.
@@ -1550,7 +1559,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15501559
// `Variant(a, a)`:
15511560
_ => IdentifierBoundMoreThanOnceInSamePattern,
15521561
};
1553-
self.r.report_error(ident.span, error(ident.name));
1562+
self.report_error(ident.span, error(ident.name));
15541563
}
15551564

15561565
// Record as bound if it's valid:
@@ -1624,7 +1633,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
16241633
// to something unusable as a pattern (e.g., constructor function),
16251634
// but we still conservatively report an error, see
16261635
// issues/33118#issuecomment-233962221 for one reason why.
1627-
self.r.report_error(
1636+
self.report_error(
16281637
ident.span,
16291638
ResolutionError::BindingShadowsSomethingUnacceptable(
16301639
pat_src.descr(),
@@ -1809,7 +1818,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18091818

18101819
Err(err) => {
18111820
if let Some(err) = report_errors_for_call(self, err) {
1812-
self.r.report_error(err.span, err.node);
1821+
self.report_error(err.span, err.node);
18131822
}
18141823

18151824
PartialRes::new(Res::Err)
@@ -1843,6 +1852,15 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18431852
if let Some(LexicalScopeBinding::Res(res)) = binding { res != Res::Err } else { false }
18441853
}
18451854

1855+
/// A wrapper around [`Resolver::report_error`].
1856+
///
1857+
/// This doesn't emit errors for function bodies if `ignore_bodies` is set.
1858+
fn report_error(&self, span: Span, resolution_error: ResolutionError<'_>) {
1859+
if !self.ignore_bodies || self.diagnostic_metadata.current_function.is_none() {
1860+
self.r.report_error(span, resolution_error);
1861+
}
1862+
}
1863+
18461864
// Resolve in alternative namespaces if resolution in the primary namespace fails.
18471865
fn resolve_qpath_anywhere(
18481866
&mut self,
@@ -2339,8 +2357,8 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
23392357
}
23402358

23412359
impl<'a> Resolver<'a> {
2342-
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
2343-
let mut late_resolution_visitor = LateResolutionVisitor::new(self);
2360+
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate, ignore_bodies: bool) {
2361+
let mut late_resolution_visitor = LateResolutionVisitor::new(self, ignore_bodies);
23442362
visit::walk_crate(&mut late_resolution_visitor, krate);
23452363
for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() {
23462364
self.lint_buffer.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label");

src/librustc_resolve/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,13 +1441,13 @@ impl<'a> Resolver<'a> {
14411441
}
14421442

14431443
/// Entry point to crate resolution.
1444-
pub fn resolve_crate(&mut self, krate: &Crate) {
1444+
pub fn resolve_crate(&mut self, krate: &Crate, ignore_bodies: bool) {
14451445
let _prof_timer = self.session.prof.generic_activity("resolve_crate");
14461446

14471447
ImportResolver { r: self }.finalize_imports();
14481448
self.finalize_macro_resolutions();
14491449

1450-
self.late_resolve_crate(krate);
1450+
self.late_resolve_crate(krate, ignore_bodies);
14511451

14521452
self.check_unused(krate);
14531453
self.report_errors(krate);

src/test/rustdoc/doc-cfg.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,7 @@ pub unsafe fn uses_target_feature() {
5757
// 'This is supported with target feature avx only.'
5858
#[doc(cfg(target_feature = "avx"))]
5959
pub fn uses_cfg_target_feature() {
60-
uses_target_feature();
60+
unsafe {
61+
uses_target_feature();
62+
}
6163
}

0 commit comments

Comments
 (0)