Skip to content

Commit 4e74eb5

Browse files
committed
rustc: Filter out bogus extern crate warnings
Rustdoc has for some time now used the "everybody loops" pass in the compiler to avoid typechecking and otherwise avoid looking at implementation details. In #46115 the placement of this pass was pushed back in the compiler to after macro expansion to ensure that it works with macro-expanded code as well. This in turn caused the regression in #46271. The bug here was that the resolver was producing `def_id` instances for "possibly unused extern crates" which would then later get processed during typeck to actually issue lint warnings. The problem was that *after* resolution these `def_id` nodes were actually removed from the AST by the "everybody loops" pass. This later, when we tried to take a look at `def_id`, caused the compiler to panic. The fix applied here is a bit of a heavy hammer which is to just, in this one case, ignore the `extern crate` lints if the `def_id` looks "bogus" in any way (basically if it looks like the node was removed after resolution). The real underlying bug here is probably that the "everybody loops" AST pass is being stressed to much beyond what it was originally intended to do, but this should at least fix the ICE for now... Closes #46271
1 parent 4fa202d commit 4e74eb5

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

src/librustc_typeck/check_unused.rs

+19
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,25 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
7575
tcx.hir.krate().visit_all_item_likes(&mut visitor);
7676

7777
for &(def_id, span) in tcx.maybe_unused_extern_crates(LOCAL_CRATE).iter() {
78+
// The `def_id` here actually was calculated during resolution (at least
79+
// at the time of this writing) and is being shipped to us via a side
80+
// channel of the tcx. There may have been extra expansion phases,
81+
// however, which ended up removing the `def_id` *after* expansion such
82+
// as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
83+
//
84+
// As a result we need to verify that `def_id` is indeed still valid for
85+
// our AST and actually present in the HIR map. If it's not there then
86+
// there's safely nothing to warn about, and otherwise we carry on with
87+
// our execution.
88+
//
89+
// Note that if we carry through to the `extern_mod_stmt_cnum` query
90+
// below it'll cause a panic because `def_id` is actually bogus at this
91+
// point in time otherwise.
92+
if let Some(id) = tcx.hir.as_local_node_id(def_id) {
93+
if tcx.hir.find(id).is_none() {
94+
continue
95+
}
96+
}
7897
let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
7998
if tcx.is_compiler_builtins(cnum) {
8099
continue

src/test/rustdoc/issue-46271.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// hopefully this doesn't cause an ICE
12+
13+
pub fn foo() {
14+
extern crate std;
15+
}

0 commit comments

Comments
 (0)