Skip to content

Commit d43d922

Browse files
authored
Rollup merge of rust-lang#56679 - euclio:external-doc-parse, r=estebank
overhaul external doc attribute diagnostics This PR improves the error handling and spans for the external doc attribute. Many cases that silently failed before now emit errors, spans are tightened, and the errors have help and suggestions. I tried to address all the cases that users ran into in the tracking issue. cc rust-lang#44732 r? @QuietMisdreavus
2 parents 5168289 + 7f7045f commit d43d922

File tree

4 files changed

+119
-18
lines changed

4 files changed

+119
-18
lines changed

src/libsyntax/ext/expand.rs

+56-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use ast::{self, Block, Ident, NodeId, PatKind, Path};
11+
use ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path};
1212
use ast::{MacStmtStyle, StmtKind, ItemKind};
1313
use attr::{self, HasAttrs};
1414
use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
@@ -1535,21 +1535,65 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
15351535
let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
15361536
items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item)));
15371537
}
1538-
Err(ref e) if e.kind() == ErrorKind::InvalidData => {
1539-
self.cx.span_err(
1540-
at.span,
1541-
&format!("{} wasn't a utf-8 file", filename.display()),
1542-
);
1543-
}
15441538
Err(e) => {
1545-
self.cx.span_err(
1546-
at.span,
1547-
&format!("couldn't read {}: {}", filename.display(), e),
1548-
);
1539+
let lit = it
1540+
.meta_item()
1541+
.and_then(|item| item.name_value_literal())
1542+
.unwrap();
1543+
1544+
if e.kind() == ErrorKind::InvalidData {
1545+
self.cx
1546+
.struct_span_err(
1547+
lit.span,
1548+
&format!("{} wasn't a utf-8 file", filename.display()),
1549+
)
1550+
.span_label(lit.span, "contains invalid utf-8")
1551+
.emit();
1552+
} else {
1553+
let mut err = self.cx.struct_span_err(
1554+
lit.span,
1555+
&format!("couldn't read {}: {}", filename.display(), e),
1556+
);
1557+
err.span_label(lit.span, "couldn't read file");
1558+
1559+
if e.kind() == ErrorKind::NotFound {
1560+
err.help("external doc paths are relative to the crate root");
1561+
}
1562+
1563+
err.emit();
1564+
}
15491565
}
15501566
}
15511567
} else {
1552-
items.push(noop_fold_meta_list_item(it, self));
1568+
let mut err = self.cx.struct_span_err(
1569+
it.span,
1570+
&format!("expected path to external documentation"),
1571+
);
1572+
1573+
// Check if the user erroneously used `doc(include(...))` syntax.
1574+
let literal = it.meta_item_list().and_then(|list| {
1575+
if list.len() == 1 {
1576+
list[0].literal().map(|literal| &literal.node)
1577+
} else {
1578+
None
1579+
}
1580+
});
1581+
1582+
let (path, applicability) = match &literal {
1583+
Some(LitKind::Str(path, ..)) => {
1584+
(path.to_string(), Applicability::MachineApplicable)
1585+
}
1586+
_ => (String::from("<path>"), Applicability::HasPlaceholders),
1587+
};
1588+
1589+
err.span_suggestion_with_applicability(
1590+
it.span,
1591+
"provide a file path with `=`",
1592+
format!("include = \"{}\"", path),
1593+
applicability,
1594+
);
1595+
1596+
err.emit();
15531597
}
15541598
}
15551599

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
�(

src/test/ui/extern/external-doc-error.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,31 @@
22

33
#![feature(external_doc)]
44

5-
#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
6-
pub struct SomeStruct;
5+
#[doc(include = "not-a-file.md")]
6+
pub struct SomeStruct; //~^ ERROR couldn't read
7+
//~| HELP external doc paths are relative to the crate root
8+
9+
#[doc(include = "auxiliary/invalid-utf8.txt")]
10+
pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file
11+
12+
#[doc(include)]
13+
pub struct MissingPath; //~^ ERROR expected path
14+
//~| HELP provide a file path with `=`
15+
//~| SUGGESTION include = "<path>"
16+
17+
#[doc(include("../README.md"))]
18+
pub struct InvalidPathSyntax; //~^ ERROR expected path
19+
//~| HELP provide a file path with `=`
20+
//~| SUGGESTION include = "../README.md"
21+
22+
#[doc(include = 123)]
23+
pub struct InvalidPathType; //~^ ERROR expected path
24+
//~| HELP provide a file path with `=`
25+
//~| SUGGESTION include = "<path>"
26+
27+
#[doc(include(123))]
28+
pub struct InvalidPathSyntaxAndType; //~^ ERROR expected path
29+
//~| HELP provide a file path with `=`
30+
//~| SUGGESTION include = "<path>"
731

832
fn main() {}
+36-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,40 @@
11
error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2)
2-
--> $DIR/external-doc-error.rs:5:1
2+
--> $DIR/external-doc-error.rs:5:17
33
|
4-
LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | #[doc(include = "not-a-file.md")]
5+
| ^^^^^^^^^^^^^^^ couldn't read file
6+
|
7+
= help: external doc paths are relative to the crate root
8+
9+
error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file
10+
--> $DIR/external-doc-error.rs:9:17
11+
|
12+
LL | #[doc(include = "auxiliary/invalid-utf8.txt")]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8
14+
15+
error: expected path to external documentation
16+
--> $DIR/external-doc-error.rs:12:7
17+
|
18+
LL | #[doc(include)]
19+
| ^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
20+
21+
error: expected path to external documentation
22+
--> $DIR/external-doc-error.rs:17:7
23+
|
24+
LL | #[doc(include("../README.md"))]
25+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"`
26+
27+
error: expected path to external documentation
28+
--> $DIR/external-doc-error.rs:22:7
29+
|
30+
LL | #[doc(include = 123)]
31+
| ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
32+
33+
error: expected path to external documentation
34+
--> $DIR/external-doc-error.rs:27:7
35+
|
36+
LL | #[doc(include(123))]
37+
| ^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
638

7-
error: aborting due to previous error
39+
error: aborting due to 6 previous errors
840

0 commit comments

Comments
 (0)