diff options
| author | bors <bors@rust-lang.org> | 2018-07-23 21:44:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-07-23 21:44:37 +0000 |
| commit | 6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d (patch) | |
| tree | 25e3c072744828f6dbfceb3a09c0328176e5afbb /src/tools | |
| parent | 00204c2f52ec0280bda17de347c79f88e9c6b479 (diff) | |
| parent | 8ec9d7242c3352fbc617d907bec3632215811356 (diff) | |
| download | rust-6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d.tar.gz rust-6a1c0637ce44aeea6c60527f4c0e7fb33f2bcd0d.zip | |
Auto merge of #52175 - fpoli:testsuite-callsite-span, r=petrochenkov
Match errors using the callsite of macro expansions Fix for issue #51848
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/compiletest/src/json.rs | 32 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest.rs | 6 |
2 files changed, 32 insertions, 6 deletions
diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 165f2914ae2..201a661726e 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -40,6 +40,21 @@ struct DiagnosticSpan { expansion: Option<Box<DiagnosticSpanMacroExpansion>>, } +impl DiagnosticSpan { + /// Returns the deepest source span in the macro call stack with a given file name. + /// This is either the supplied span, or the span for some macro callsite that expanded to it. + fn first_callsite_in_file(&self, file_name: &str) -> &DiagnosticSpan { + if self.file_name == file_name { + self + } else { + self.expansion + .as_ref() + .map(|origin| origin.span.first_callsite_in_file(file_name)) + .unwrap_or(self) + } + } +} + #[derive(Deserialize, Clone)] struct DiagnosticSpanMacroExpansion { /// span where macro was applied to generate this code @@ -115,16 +130,23 @@ fn push_expected_errors( default_spans: &[&DiagnosticSpan], file_name: &str, ) { - let spans_in_this_file: Vec<_> = diagnostic + // In case of macro expansions, we need to get the span of the callsite + let spans_info_in_this_file: Vec<_> = diagnostic .spans .iter() - .filter(|span| Path::new(&span.file_name) == Path::new(&file_name)) + .map(|span| (span.is_primary, span.first_callsite_in_file(file_name))) + .filter(|(_, span)| Path::new(&span.file_name) == Path::new(&file_name)) .collect(); - let primary_spans: Vec<_> = spans_in_this_file.iter() - .cloned() - .filter(|span| span.is_primary) + let spans_in_this_file: Vec<_> = spans_info_in_this_file.iter() + .map(|(_, span)| span) + .collect(); + + let primary_spans: Vec<_> = spans_info_in_this_file.iter() + .filter(|(is_primary, _)| *is_primary) + .map(|(_, span)| span) .take(1) // sometimes we have more than one showing up in the json; pick first + .cloned() .collect(); let primary_spans = if primary_spans.is_empty() { // subdiagnostics often don't have a span of their own; diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index fcc47436225..ad86844cec3 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1194,6 +1194,10 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec("process did not return an error status", proc_res); } + // On Windows, keep all '\' path separators to match the paths reported in the JSON output + // from the compiler + let os_file_name = self.testpaths.file.display().to_string(); + // on windows, translate all '\' path separators to '/' let file_name = format!("{}", self.testpaths.file.display()).replace(r"\", "/"); @@ -1209,7 +1213,7 @@ impl<'test> TestCx<'test> { .any(|ee| ee.kind == Some(ErrorKind::Note)); // Parse the JSON output from the compiler and extract out the messages. - let actual_errors = json::parse_output(&file_name, &proc_res.stderr, proc_res); + let actual_errors = json::parse_output(&os_file_name, &proc_res.stderr, proc_res); let mut unexpected = Vec::new(); let mut found = vec![false; expected_errors.len()]; for actual_error in &actual_errors { |
