Skip to content

Commit

Permalink
Rollup merge of rust-lang#56679 - euclio:external-doc-parse, r=estebank
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pietroalbini committed Dec 12, 2018
2 parents d862bc3 + 7f7045f commit c2655e1
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 18 deletions.
68 changes: 56 additions & 12 deletions src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ast::{self, Block, Ident, NodeId, PatKind, Path};
use ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path};
use ast::{MacStmtStyle, StmtKind, ItemKind};
use attr::{self, HasAttrs};
use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
Expand Down Expand Up @@ -1535,21 +1535,65 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item)));
}
Err(ref e) if e.kind() == ErrorKind::InvalidData => {
self.cx.span_err(
at.span,
&format!("{} wasn't a utf-8 file", filename.display()),
);
}
Err(e) => {
self.cx.span_err(
at.span,
&format!("couldn't read {}: {}", filename.display(), e),
);
let lit = it
.meta_item()
.and_then(|item| item.name_value_literal())
.unwrap();

if e.kind() == ErrorKind::InvalidData {
self.cx
.struct_span_err(
lit.span,
&format!("{} wasn't a utf-8 file", filename.display()),
)
.span_label(lit.span, "contains invalid utf-8")
.emit();
} else {
let mut err = self.cx.struct_span_err(
lit.span,
&format!("couldn't read {}: {}", filename.display(), e),
);
err.span_label(lit.span, "couldn't read file");

if e.kind() == ErrorKind::NotFound {
err.help("external doc paths are relative to the crate root");
}

err.emit();
}
}
}
} else {
items.push(noop_fold_meta_list_item(it, self));
let mut err = self.cx.struct_span_err(
it.span,
&format!("expected path to external documentation"),
);

// Check if the user erroneously used `doc(include(...))` syntax.
let literal = it.meta_item_list().and_then(|list| {
if list.len() == 1 {
list[0].literal().map(|literal| &literal.node)
} else {
None
}
});

let (path, applicability) = match &literal {
Some(LitKind::Str(path, ..)) => {
(path.to_string(), Applicability::MachineApplicable)
}
_ => (String::from("<path>"), Applicability::HasPlaceholders),
};

err.span_suggestion_with_applicability(
it.span,
"provide a file path with `=`",
format!("include = \"{}\"", path),
applicability,
);

err.emit();
}
}

Expand Down
1 change: 1 addition & 0 deletions src/test/ui/extern/auxiliary/invalid-utf8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�(
28 changes: 26 additions & 2 deletions src/test/ui/extern/external-doc-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,31 @@

#![feature(external_doc)]

#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
pub struct SomeStruct;
#[doc(include = "not-a-file.md")]
pub struct SomeStruct; //~^ ERROR couldn't read
//~| HELP external doc paths are relative to the crate root

#[doc(include = "auxiliary/invalid-utf8.txt")]
pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file

#[doc(include)]
pub struct MissingPath; //~^ ERROR expected path
//~| HELP provide a file path with `=`
//~| SUGGESTION include = "<path>"

#[doc(include("../README.md"))]
pub struct InvalidPathSyntax; //~^ ERROR expected path
//~| HELP provide a file path with `=`
//~| SUGGESTION include = "../README.md"

#[doc(include = 123)]
pub struct InvalidPathType; //~^ ERROR expected path
//~| HELP provide a file path with `=`
//~| SUGGESTION include = "<path>"

#[doc(include(123))]
pub struct InvalidPathSyntaxAndType; //~^ ERROR expected path
//~| HELP provide a file path with `=`
//~| SUGGESTION include = "<path>"

fn main() {}
40 changes: 36 additions & 4 deletions src/test/ui/extern/external-doc-error.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2)
--> $DIR/external-doc-error.rs:5:1
--> $DIR/external-doc-error.rs:5:17
|
LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #[doc(include = "not-a-file.md")]
| ^^^^^^^^^^^^^^^ couldn't read file
|
= help: external doc paths are relative to the crate root

error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file
--> $DIR/external-doc-error.rs:9:17
|
LL | #[doc(include = "auxiliary/invalid-utf8.txt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8

error: expected path to external documentation
--> $DIR/external-doc-error.rs:12:7
|
LL | #[doc(include)]
| ^^^^^^^ help: provide a file path with `=`: `include = "<path>"`

error: expected path to external documentation
--> $DIR/external-doc-error.rs:17:7
|
LL | #[doc(include("../README.md"))]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"`

error: expected path to external documentation
--> $DIR/external-doc-error.rs:22:7
|
LL | #[doc(include = 123)]
| ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`

error: expected path to external documentation
--> $DIR/external-doc-error.rs:27:7
|
LL | #[doc(include(123))]
| ^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`

error: aborting due to previous error
error: aborting due to 6 previous errors

0 comments on commit c2655e1

Please sign in to comment.