Rollup merge of #142377 - Urgau:unremap-rustc-dev, r=jieyouxu
Try unremapping compiler sources See [#t-compiler/help > Span pointing to wrong file location (`rustc-dev` component)](https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/Span.20pointing.20to.20wrong.20file.20location.20.28.60rustc-dev.60.20component.29/with/521087083). This PR is a follow-up to rust-lang/rust#141751 regarding the compiler side. Specifically we now take into account the `CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR` env from rust-lang/rust#141751 when trying to unremap sources from `$sysroot/lib/rustlib/rustc-src/rust` (the `rustc-dev` component install directory). Best reviewed commit by commit. cc ``@samueltardieu`` r? ``@jieyouxu``
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// Decoding metadata from a single crate's metadata
|
// Decoding metadata from a single crate's metadata
|
||||||
|
|
||||||
use std::iter::TrustedLen;
|
use std::iter::TrustedLen;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, OnceLock};
|
use std::sync::{Arc, OnceLock};
|
||||||
use std::{io, iter, mem};
|
use std::{io, iter, mem};
|
||||||
|
|
||||||
@@ -1610,10 +1610,14 @@ impl<'a> CrateMetadataRef<'a> {
|
|||||||
/// Proc macro crates don't currently export spans, so this function does not have
|
/// Proc macro crates don't currently export spans, so this function does not have
|
||||||
/// to work for them.
|
/// to work for them.
|
||||||
fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile {
|
fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile {
|
||||||
fn filter<'a>(sess: &Session, path: Option<&'a Path>) -> Option<&'a Path> {
|
fn filter<'a>(
|
||||||
|
sess: &Session,
|
||||||
|
real_source_base_dir: &Option<PathBuf>,
|
||||||
|
path: Option<&'a Path>,
|
||||||
|
) -> Option<&'a Path> {
|
||||||
path.filter(|_| {
|
path.filter(|_| {
|
||||||
// Only spend time on further checks if we have what to translate *to*.
|
// Only spend time on further checks if we have what to translate *to*.
|
||||||
sess.opts.real_rust_source_base_dir.is_some()
|
real_source_base_dir.is_some()
|
||||||
// Some tests need the translation to be always skipped.
|
// Some tests need the translation to be always skipped.
|
||||||
&& sess.opts.unstable_opts.translate_remapped_path_to_local_path
|
&& sess.opts.unstable_opts.translate_remapped_path_to_local_path
|
||||||
})
|
})
|
||||||
@@ -1625,25 +1629,27 @@ impl<'a> CrateMetadataRef<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
|
let try_to_translate_virtual_to_real =
|
||||||
// Translate the virtual `/rustc/$hash` prefix back to a real directory
|
|virtual_source_base_dir: Option<&str>,
|
||||||
// that should hold actual sources, where possible.
|
real_source_base_dir: &Option<PathBuf>,
|
||||||
//
|
name: &mut rustc_span::FileName| {
|
||||||
// NOTE: if you update this, you might need to also update bootstrap's code for generating
|
let virtual_source_base_dir = [
|
||||||
// the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
|
filter(sess, real_source_base_dir, virtual_source_base_dir.map(Path::new)),
|
||||||
let virtual_rust_source_base_dir = [
|
filter(
|
||||||
filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)),
|
sess,
|
||||||
filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()),
|
real_source_base_dir,
|
||||||
|
sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"try_to_translate_virtual_to_real(name={:?}): \
|
"try_to_translate_virtual_to_real(name={:?}): \
|
||||||
virtual_rust_source_base_dir={:?}, real_rust_source_base_dir={:?}",
|
virtual_source_base_dir={:?}, real_source_base_dir={:?}",
|
||||||
name, virtual_rust_source_base_dir, sess.opts.real_rust_source_base_dir,
|
name, virtual_source_base_dir, real_source_base_dir,
|
||||||
);
|
);
|
||||||
|
|
||||||
for virtual_dir in virtual_rust_source_base_dir.iter().flatten() {
|
for virtual_dir in virtual_source_base_dir.iter().flatten() {
|
||||||
if let Some(real_dir) = &sess.opts.real_rust_source_base_dir
|
if let Some(real_dir) = &real_source_base_dir
|
||||||
&& let rustc_span::FileName::Real(old_name) = name
|
&& let rustc_span::FileName::Real(old_name) = name
|
||||||
&& let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
|
&& let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
|
||||||
old_name
|
old_name
|
||||||
@@ -1677,6 +1683,39 @@ impl<'a> CrateMetadataRef<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let try_to_translate_real_to_virtual =
|
||||||
|
|virtual_source_base_dir: Option<&str>,
|
||||||
|
real_source_base_dir: &Option<PathBuf>,
|
||||||
|
subdir: &str,
|
||||||
|
name: &mut rustc_span::FileName| {
|
||||||
|
if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
|
||||||
|
&& let Some(real_dir) = real_source_base_dir
|
||||||
|
&& let rustc_span::FileName::Real(old_name) = name
|
||||||
|
{
|
||||||
|
let relative_path = match old_name {
|
||||||
|
rustc_span::RealFileName::LocalPath(local) => {
|
||||||
|
local.strip_prefix(real_dir).ok()
|
||||||
|
}
|
||||||
|
rustc_span::RealFileName::Remapped { virtual_name, .. } => {
|
||||||
|
virtual_source_base_dir
|
||||||
|
.and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
debug!(
|
||||||
|
?relative_path,
|
||||||
|
?virtual_dir,
|
||||||
|
?subdir,
|
||||||
|
"simulate_remapped_rust_src_base"
|
||||||
|
);
|
||||||
|
if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) {
|
||||||
|
*old_name = rustc_span::RealFileName::Remapped {
|
||||||
|
local_path: None,
|
||||||
|
virtual_name: virtual_dir.join(subdir).join(rest),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut import_info = self.cdata.source_map_import_info.lock();
|
let mut import_info = self.cdata.source_map_import_info.lock();
|
||||||
for _ in import_info.len()..=(source_file_index as usize) {
|
for _ in import_info.len()..=(source_file_index as usize) {
|
||||||
import_info.push(None);
|
import_info.push(None);
|
||||||
@@ -1713,36 +1752,45 @@ impl<'a> CrateMetadataRef<'a> {
|
|||||||
// This is useful for testing so that tests about the effects of
|
// This is useful for testing so that tests about the effects of
|
||||||
// `try_to_translate_virtual_to_real` don't have to worry about how the
|
// `try_to_translate_virtual_to_real` don't have to worry about how the
|
||||||
// compiler is bootstrapped.
|
// compiler is bootstrapped.
|
||||||
if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
|
try_to_translate_real_to_virtual(
|
||||||
&& let Some(real_dir) = &sess.opts.real_rust_source_base_dir
|
option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"),
|
||||||
&& let rustc_span::FileName::Real(ref mut old_name) = name
|
&sess.opts.real_rust_source_base_dir,
|
||||||
{
|
"library",
|
||||||
let relative_path = match old_name {
|
&mut name,
|
||||||
rustc_span::RealFileName::LocalPath(local) => {
|
);
|
||||||
local.strip_prefix(real_dir).ok()
|
|
||||||
}
|
// If this file is under $sysroot/lib/rustlib/rustc-src/
|
||||||
rustc_span::RealFileName::Remapped { virtual_name, .. } => {
|
// and the user wish to simulate remapping with -Z simulate-remapped-rust-src-base,
|
||||||
option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR")
|
// then we change `name` to a similar state as if the rust was bootstrapped
|
||||||
.and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok())
|
// with `remap-debuginfo = true`.
|
||||||
}
|
try_to_translate_real_to_virtual(
|
||||||
};
|
option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"),
|
||||||
debug!(?relative_path, ?virtual_dir, "simulate_remapped_rust_src_base");
|
&sess.opts.real_rustc_dev_source_base_dir,
|
||||||
for subdir in ["library", "compiler"] {
|
"compiler",
|
||||||
if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok())
|
&mut name,
|
||||||
{
|
);
|
||||||
*old_name = rustc_span::RealFileName::Remapped {
|
|
||||||
local_path: None, // FIXME: maybe we should preserve this?
|
|
||||||
virtual_name: virtual_dir.join(subdir).join(rest),
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this file's path has been remapped to `/rustc/$hash`,
|
// If this file's path has been remapped to `/rustc/$hash`,
|
||||||
// we might be able to reverse that (also see comments above,
|
// we might be able to reverse that.
|
||||||
// on `try_to_translate_virtual_to_real`).
|
//
|
||||||
try_to_translate_virtual_to_real(&mut name);
|
// NOTE: if you update this, you might need to also update bootstrap's code for generating
|
||||||
|
// the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
|
||||||
|
try_to_translate_virtual_to_real(
|
||||||
|
option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"),
|
||||||
|
&sess.opts.real_rust_source_base_dir,
|
||||||
|
&mut name,
|
||||||
|
);
|
||||||
|
|
||||||
|
// If this file's path has been remapped to `/rustc-dev/$hash`,
|
||||||
|
// we might be able to reverse that.
|
||||||
|
//
|
||||||
|
// NOTE: if you update this, you might need to also update bootstrap's code for generating
|
||||||
|
// the `rustc-dev` component in `Src::run` in `src/bootstrap/dist.rs`.
|
||||||
|
try_to_translate_virtual_to_real(
|
||||||
|
option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"),
|
||||||
|
&sess.opts.real_rustc_dev_source_base_dir,
|
||||||
|
&mut name,
|
||||||
|
);
|
||||||
|
|
||||||
let local_version = sess.source_map().new_imported_source_file(
|
let local_version = sess.source_map().new_imported_source_file(
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -1364,6 +1364,7 @@ impl Default for Options {
|
|||||||
cli_forced_local_thinlto_off: false,
|
cli_forced_local_thinlto_off: false,
|
||||||
remap_path_prefix: Vec::new(),
|
remap_path_prefix: Vec::new(),
|
||||||
real_rust_source_base_dir: None,
|
real_rust_source_base_dir: None,
|
||||||
|
real_rustc_dev_source_base_dir: None,
|
||||||
edition: DEFAULT_EDITION,
|
edition: DEFAULT_EDITION,
|
||||||
json_artifact_notifications: false,
|
json_artifact_notifications: false,
|
||||||
json_timings: false,
|
json_timings: false,
|
||||||
@@ -2713,9 +2714,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
|||||||
|
|
||||||
let sysroot = filesearch::materialize_sysroot(sysroot_opt);
|
let sysroot = filesearch::materialize_sysroot(sysroot_opt);
|
||||||
|
|
||||||
let real_rust_source_base_dir = {
|
let real_source_base_dir = |suffix: &str, confirm: &str| {
|
||||||
// This is the location used by the `rust-src` `rustup` component.
|
let mut candidate = sysroot.join(suffix);
|
||||||
let mut candidate = sysroot.join("lib/rustlib/src/rust");
|
|
||||||
if let Ok(metadata) = candidate.symlink_metadata() {
|
if let Ok(metadata) = candidate.symlink_metadata() {
|
||||||
// Replace the symlink bootstrap creates, with its destination.
|
// Replace the symlink bootstrap creates, with its destination.
|
||||||
// We could try to use `fs::canonicalize` instead, but that might
|
// We could try to use `fs::canonicalize` instead, but that might
|
||||||
@@ -2728,9 +2728,17 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only use this directory if it has a file we can expect to always find.
|
// Only use this directory if it has a file we can expect to always find.
|
||||||
candidate.join("library/std/src/lib.rs").is_file().then_some(candidate)
|
candidate.join(confirm).is_file().then_some(candidate)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let real_rust_source_base_dir =
|
||||||
|
// This is the location used by the `rust-src` `rustup` component.
|
||||||
|
real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");
|
||||||
|
|
||||||
|
let real_rustc_dev_source_base_dir =
|
||||||
|
// This is the location used by the `rustc-dev` `rustup` component.
|
||||||
|
real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");
|
||||||
|
|
||||||
let mut search_paths = vec![];
|
let mut search_paths = vec![];
|
||||||
for s in &matches.opt_strs("L") {
|
for s in &matches.opt_strs("L") {
|
||||||
search_paths.push(SearchPath::from_cli_opt(
|
search_paths.push(SearchPath::from_cli_opt(
|
||||||
@@ -2784,6 +2792,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
|
|||||||
cli_forced_local_thinlto_off: disable_local_thinlto,
|
cli_forced_local_thinlto_off: disable_local_thinlto,
|
||||||
remap_path_prefix,
|
remap_path_prefix,
|
||||||
real_rust_source_base_dir,
|
real_rust_source_base_dir,
|
||||||
|
real_rustc_dev_source_base_dir,
|
||||||
edition,
|
edition,
|
||||||
json_artifact_notifications,
|
json_artifact_notifications,
|
||||||
json_timings,
|
json_timings,
|
||||||
|
|||||||
@@ -395,15 +395,25 @@ top_level_options!(
|
|||||||
|
|
||||||
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
|
/// Remap source path prefixes in all output (messages, object files, debug, etc.).
|
||||||
remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH],
|
remap_path_prefix: Vec<(PathBuf, PathBuf)> [TRACKED_NO_CRATE_HASH],
|
||||||
/// Base directory containing the `src/` for the Rust standard library, and
|
|
||||||
/// potentially `rustc` as well, if we can find it. Right now it's always
|
/// Base directory containing the `library/` directory for the Rust standard library.
|
||||||
/// `$sysroot/lib/rustlib/src/rust` (i.e. the `rustup` `rust-src` component).
|
/// Right now it's always `$sysroot/lib/rustlib/src/rust`
|
||||||
|
/// (i.e. the `rustup` `rust-src` component).
|
||||||
///
|
///
|
||||||
/// This directory is what the virtual `/rustc/$hash` is translated back to,
|
/// This directory is what the virtual `/rustc/$hash` is translated back to,
|
||||||
/// if Rust was built with path remapping to `/rustc/$hash` enabled
|
/// if Rust was built with path remapping to `/rustc/$hash` enabled
|
||||||
/// (the `rust.remap-debuginfo` option in `bootstrap.toml`).
|
/// (the `rust.remap-debuginfo` option in `bootstrap.toml`).
|
||||||
real_rust_source_base_dir: Option<PathBuf> [TRACKED_NO_CRATE_HASH],
|
real_rust_source_base_dir: Option<PathBuf> [TRACKED_NO_CRATE_HASH],
|
||||||
|
|
||||||
|
/// Base directory containing the `compiler/` directory for the rustc sources.
|
||||||
|
/// Right now it's always `$sysroot/lib/rustlib/rustc-src/rust`
|
||||||
|
/// (i.e. the `rustup` `rustc-dev` component).
|
||||||
|
///
|
||||||
|
/// This directory is what the virtual `/rustc-dev/$hash` is translated back to,
|
||||||
|
/// if Rust was built with path remapping to `/rustc/$hash` enabled
|
||||||
|
/// (the `rust.remap-debuginfo` option in `bootstrap.toml`).
|
||||||
|
real_rustc_dev_source_base_dir: Option<PathBuf> [TRACKED_NO_CRATE_HASH],
|
||||||
|
|
||||||
edition: Edition [TRACKED],
|
edition: Edition [TRACKED],
|
||||||
|
|
||||||
/// `true` if we're emitting JSON blobs about each artifact produced
|
/// `true` if we're emitting JSON blobs about each artifact produced
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ Compiletest makes the following replacements on the compiler output:
|
|||||||
- The base directory where the test's output goes is replaced with
|
- The base directory where the test's output goes is replaced with
|
||||||
`$TEST_BUILD_DIR`. This only comes up in a few rare circumstances. Example:
|
`$TEST_BUILD_DIR`. This only comes up in a few rare circumstances. Example:
|
||||||
`/path/to/rust/build/x86_64-unknown-linux-gnu/test/ui`
|
`/path/to/rust/build/x86_64-unknown-linux-gnu/test/ui`
|
||||||
|
- The real directory to the standard library source is replaced with `$SRC_DIR_REAL`.
|
||||||
|
- The real directory to the compiler source is replaced with `$COMPILER_DIR_REAL`.
|
||||||
- Tabs are replaced with `\t`.
|
- Tabs are replaced with `\t`.
|
||||||
- Backslashes (`\`) are converted to forward slashes (`/`) within paths (using a
|
- Backslashes (`\`) are converted to forward slashes (`/`) within paths (using a
|
||||||
heuristic). This helps normalize differences with Windows-style paths.
|
heuristic). This helps normalize differences with Windows-style paths.
|
||||||
|
|||||||
@@ -2371,6 +2371,12 @@ impl<'test> TestCx<'test> {
|
|||||||
let rust_src_dir = rust_src_dir.read_link_utf8().unwrap_or(rust_src_dir.to_path_buf());
|
let rust_src_dir = rust_src_dir.read_link_utf8().unwrap_or(rust_src_dir.to_path_buf());
|
||||||
normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL");
|
normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL");
|
||||||
|
|
||||||
|
// Real paths into the compiler
|
||||||
|
let rustc_src_dir = &self.config.sysroot_base.join("lib/rustlib/rustc-src/rust");
|
||||||
|
rustc_src_dir.try_exists().expect(&*format!("{} should exists", rustc_src_dir));
|
||||||
|
let rustc_src_dir = rustc_src_dir.read_link_utf8().unwrap_or(rustc_src_dir.to_path_buf());
|
||||||
|
normalize_path(&rustc_src_dir.join("compiler"), "$COMPILER_DIR_REAL");
|
||||||
|
|
||||||
// eg.
|
// eg.
|
||||||
// /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui/<test_dir>/$name.$revision.$mode/
|
// /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui/<test_dir>/$name.$revision.$mode/
|
||||||
normalize_path(&self.output_base_dir(), "$TEST_BUILD_DIR");
|
normalize_path(&self.output_base_dir(), "$TEST_BUILD_DIR");
|
||||||
|
|||||||
15
tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr
Normal file
15
tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisfied
|
||||||
|
--> $DIR/rustc-dev-remap.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | type Result = NotAValidResultType;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ the trait `VisitorResult` is not implemented for `NotAValidResultType`
|
||||||
|
|
|
||||||
|
= help: the following other types implement trait `VisitorResult`:
|
||||||
|
()
|
||||||
|
ControlFlow<T>
|
||||||
|
note: required by a bound in `rustc_ast::visit::Visitor::Result`
|
||||||
|
--> /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
18
tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr
Normal file
18
tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisfied
|
||||||
|
--> $DIR/rustc-dev-remap.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | type Result = NotAValidResultType;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ the trait `VisitorResult` is not implemented for `NotAValidResultType`
|
||||||
|
|
|
||||||
|
= help: the following other types implement trait `VisitorResult`:
|
||||||
|
()
|
||||||
|
ControlFlow<T>
|
||||||
|
note: required by a bound in `rustc_ast::visit::Visitor::Result`
|
||||||
|
--> $COMPILER_DIR_REAL/rustc_ast/src/visit.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | type Result: VisitorResult = ();
|
||||||
|
| ^^^^^^^^^^^^^ required by this bound in `Visitor::Result`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
30
tests/ui-fulldeps/rustc-dev-remap.rs
Normal file
30
tests/ui-fulldeps/rustc-dev-remap.rs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//@ check-fail
|
||||||
|
//
|
||||||
|
//@ ignore-stage1
|
||||||
|
//@ ignore-cross-compile
|
||||||
|
//@ ignore-remote
|
||||||
|
//
|
||||||
|
//@ revisions: only-remap remap-unremap
|
||||||
|
//@ compile-flags: -Z simulate-remapped-rust-src-base=/rustc-dev/xyz
|
||||||
|
//@ [remap-unremap]compile-flags: -Ztranslate-remapped-path-to-local-path=yes
|
||||||
|
|
||||||
|
// The $SRC_DIR*.rs:LL:COL normalisation doesn't kick in automatically
|
||||||
|
// as the remapped revision will begin with $COMPILER_DIR_REAL,
|
||||||
|
// so we have to do it ourselves.
|
||||||
|
//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:COL"
|
||||||
|
|
||||||
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
|
extern crate rustc_ast;
|
||||||
|
|
||||||
|
use rustc_ast::visit::Visitor;
|
||||||
|
|
||||||
|
struct MyStruct;
|
||||||
|
struct NotAValidResultType;
|
||||||
|
|
||||||
|
impl Visitor<'_> for MyStruct {
|
||||||
|
type Result = NotAValidResultType;
|
||||||
|
//~^ ERROR the trait bound `NotAValidResultType: VisitorResult` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
Reference in New Issue
Block a user