diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index aac244ad6cf22..91e6188a8c63c 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -250,6 +250,13 @@ impl<'a, 'ra, 'tcx> AsMut> for UnusedImportCheckVisitor<'a, } impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> { + // Don't walk into attributes because imports can appear + // inside (e.g #[doc = {use std::{io,fmt};}]). They have + // a different owner, so they will cause an ICE if we visit + // them. Note that this doc attribute is not valid and will + // be rejected during AST lowering. + fn visit_attribute(&mut self, _: &'a rustc_ast::Attribute) {} + fn visit_item(&mut self, item: &'a ast::Item) { self.item_span = item.span_with_attributes(); match &item.kind { diff --git a/tests/ui/attributes/use-tree-in-docs.rs b/tests/ui/attributes/use-tree-in-docs.rs new file mode 100644 index 0000000000000..69e1121464558 --- /dev/null +++ b/tests/ui/attributes/use-tree-in-docs.rs @@ -0,0 +1,7 @@ +// Don't ICE when use tree appears in docs. (#163355) +#![feature(generic_assert)] +#[doc = assert !(b)] +//~^ ERROR attribute value must be a literal +use std as x; + +fn main(){} diff --git a/tests/ui/attributes/use-tree-in-docs.stderr b/tests/ui/attributes/use-tree-in-docs.stderr new file mode 100644 index 0000000000000..fb03874a714c7 --- /dev/null +++ b/tests/ui/attributes/use-tree-in-docs.stderr @@ -0,0 +1,8 @@ +error: attribute value must be a literal + --> $DIR/use-tree-in-docs.rs:3:9 + | +LL | #[doc = assert !(b)] + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error +