diff --git a/src/libsyntax_expand/base.rs b/src/libsyntax_expand/base.rs index c222e7357ac7e..58edf23a5b1e2 100644 --- a/src/libsyntax_expand/base.rs +++ b/src/libsyntax_expand/base.rs @@ -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, span: Span) -> PathBuf { + pub fn resolve_path( + &self, + path: impl Into, + span: Span, + ) -> Result> { let path = path.into(); // Relative paths are resolved relative to the file in which they are found @@ -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) } } } diff --git a/src/libsyntax_expand/expand.rs b/src/libsyntax_expand/expand.rs index f03d464eafb90..fc521e5edc06b 100644 --- a/src/libsyntax_expand/expand.rs +++ b/src/libsyntax_expand/expand.rs @@ -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() diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs index 438e199ebdb8f..f6c58fcdfa1cb 100644 --- a/src/libsyntax_ext/source_util.rs +++ b/src/libsyntax_ext/source_util.rs @@ -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); @@ -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) => { @@ -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))))