about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax_expand/base.rs15
-rw-r--r--src/libsyntax_expand/expand.rs9
-rw-r--r--src/libsyntax_ext/source_util.rs24
3 files changed, 40 insertions, 8 deletions
diff --git a/src/libsyntax_expand/base.rs b/src/libsyntax_expand/base.rs
index c222e7357ac..58edf23a5b1 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<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
@@ -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 f03d464eafb..fc521e5edc0 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 438e199ebdb..f6c58fcdfa1 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))))