Skip to content

Commit

Permalink
Rollup merge of rust-lang#65603 - mystor:resolve_path_ice, r=petroche…
Browse files Browse the repository at this point in the history
…nkov

Avoid ICE when include! is used by stdin crate

This should hopefully also eliminate the ICE when using `include_bytes!`, `include_str!` and `#[doc(include = "...")]` with a stdio input.

I couldn't see a clear way to write a compile-fail test using compiletest with a stdio input, so I haven't written any tests for this change.

Fixes rust-lang#63900
  • Loading branch information
Centril authored Oct 20, 2019
2 parents f8d1c35 + 9be0bd8 commit c9c32a7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
15 changes: 11 additions & 4 deletions src/libsyntax_expand/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,11 @@ impl<'a> ExtCtxt<'a> {
/// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths.
///
/// Returns an absolute path to the file that `path` refers to.
pub fn resolve_path(&self, path: impl Into<PathBuf>, span: Span) -> PathBuf {
pub fn resolve_path(
&self,
path: impl Into<PathBuf>,
span: Span,
) -> Result<PathBuf, DiagnosticBuilder<'a>> {
let path = path.into();

// Relative paths are resolved relative to the file in which they are found
Expand All @@ -1082,13 +1086,16 @@ impl<'a> ExtCtxt<'a> {
let mut result = match self.source_map().span_to_unmapped_path(callsite) {
FileName::Real(path) => path,
FileName::DocTest(path, _) => path,
other => panic!("cannot resolve relative path in non-file source `{}`", other),
other => return Err(self.struct_span_err(
span,
&format!("cannot resolve relative path in non-file source `{}`", other),
)),
};
result.pop();
result.push(path);
result
Ok(result)
} else {
path
Ok(path)
}
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/libsyntax_expand/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,7 +1418,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
return noop_visit_attribute(at, self);
}

let filename = self.cx.resolve_path(&*file.as_str(), it.span());
let filename = match self.cx.resolve_path(&*file.as_str(), it.span()) {
Ok(filename) => filename,
Err(mut err) => {
err.emit();
continue;
}
};

match self.cx.source_map().load_file(&filename) {
Ok(source_file) => {
let src = source_file.src.as_ref()
Expand Down
24 changes: 21 additions & 3 deletions src/libsyntax_ext/source_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
None => return DummyResult::any(sp),
};
// The file will be added to the code map by the parser
let file = cx.resolve_path(file, sp);
let file = match cx.resolve_path(file, sp) {
Ok(f) => f,
Err(mut err) => {
err.emit();
return DummyResult::any(sp);
},
};
let directory_ownership = DirectoryOwnership::Owned { relative: None };
let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);

Expand Down Expand Up @@ -122,7 +128,13 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
Some(f) => f,
None => return DummyResult::any(sp)
};
let file = cx.resolve_path(file, sp);
let file = match cx.resolve_path(file, sp) {
Ok(f) => f,
Err(mut err) => {
err.emit();
return DummyResult::any(sp);
},
};
match cx.source_map().load_binary_file(&file) {
Ok(bytes) => match std::str::from_utf8(&bytes) {
Ok(src) => {
Expand All @@ -147,7 +159,13 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
Some(f) => f,
None => return DummyResult::any(sp)
};
let file = cx.resolve_path(file, sp);
let file = match cx.resolve_path(file, sp) {
Ok(f) => f,
Err(mut err) => {
err.emit();
return DummyResult::any(sp);
},
};
match cx.source_map().load_binary_file(&file) {
Ok(bytes) => {
base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
Expand Down

0 comments on commit c9c32a7

Please sign in to comment.