mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 19:17:43 +00:00
Auto merge of #72883 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum
[stable] 1.44 release This includes a release notes update as usual and a backport of #72767. r? @ghost
This commit is contained in:
commit
49cae55760
162
RELEASES.md
162
RELEASES.md
@ -1,3 +1,165 @@
|
|||||||
|
Version 1.44.0 (2020-06-04)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
Language
|
||||||
|
--------
|
||||||
|
- [You can now use `async/.await` with `#[no_std]` enabled.][69033]
|
||||||
|
- [Added the `unused_braces` lint.][70081]
|
||||||
|
|
||||||
|
**Syntax-only changes**
|
||||||
|
|
||||||
|
- [Expansion-driven outline module parsing][69838]
|
||||||
|
```rust
|
||||||
|
#[cfg(FALSE)]
|
||||||
|
mod foo {
|
||||||
|
mod bar {
|
||||||
|
mod baz; // `foo/bar/baz.rs` doesn't exist, but no error!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
These are still rejected semantically, so you will likely receive an error but
|
||||||
|
these changes can be seen and parsed by macros and conditional compilation.
|
||||||
|
|
||||||
|
Compiler
|
||||||
|
--------
|
||||||
|
- [Rustc now respects the `-C codegen-units` flag in incremental mode.][70156]
|
||||||
|
Additionally when in incremental mode rustc defaults to 256 codegen units.
|
||||||
|
- [Refactored `catch_unwind`, to have zero-cost unless unwinding is enabled and
|
||||||
|
a panic is thrown.][67502]
|
||||||
|
- [Added tier 3\* support for the `aarch64-unknown-none` and
|
||||||
|
`aarch64-unknown-none-softfloat` targets.][68334]
|
||||||
|
- [Added tier 3 support for `arm64-apple-tvos` and
|
||||||
|
`x86_64-apple-tvos` targets.][68191]
|
||||||
|
|
||||||
|
|
||||||
|
Libraries
|
||||||
|
---------
|
||||||
|
- [Special cased `vec![]` to map directly to `Vec::new()`.][70632] This allows
|
||||||
|
`vec![]` to be able to be used in `const` contexts.
|
||||||
|
- [`convert::Infallible` now implements `Hash`.][70281]
|
||||||
|
- [`OsString` now implements `DerefMut` and `IndexMut` returning
|
||||||
|
a `&mut OsStr`.][70048]
|
||||||
|
- [Unicode 13 is now supported.][69929]
|
||||||
|
- [`String` now implements `From<&mut str>`.][69661]
|
||||||
|
- [`IoSlice` now implements `Copy`.][69403]
|
||||||
|
- [`Vec<T>` now implements `From<[T; N]>`.][68692] Where `N` is less than 32.
|
||||||
|
- [`proc_macro::LexError` now implements `fmt::Display` and `Error`.][68899]
|
||||||
|
- [`from_le_bytes`, `to_le_bytes`, `from_be_bytes`, `to_be_bytes`,
|
||||||
|
`from_ne_bytes`, and `to_ne_bytes` methods are now `const` for all
|
||||||
|
integer types.][69373]
|
||||||
|
|
||||||
|
Stabilized APIs
|
||||||
|
---------------
|
||||||
|
- [`PathBuf::with_capacity`]
|
||||||
|
- [`PathBuf::capacity`]
|
||||||
|
- [`PathBuf::clear`]
|
||||||
|
- [`PathBuf::reserve`]
|
||||||
|
- [`PathBuf::reserve_exact`]
|
||||||
|
- [`PathBuf::shrink_to_fit`]
|
||||||
|
- [`f32::to_int_unchecked`]
|
||||||
|
- [`f64::to_int_unchecked`]
|
||||||
|
- [`Layout::align_to`]
|
||||||
|
- [`Layout::pad_to_align`]
|
||||||
|
- [`Layout::array`]
|
||||||
|
- [`Layout::extend`]
|
||||||
|
|
||||||
|
Cargo
|
||||||
|
-----
|
||||||
|
- [Added the `cargo tree` command which will print a tree graph of
|
||||||
|
your dependencies.][cargo/8062] E.g.
|
||||||
|
```
|
||||||
|
mdbook v0.3.2 (/Users/src/rust/mdbook)
|
||||||
|
├── ammonia v3.0.0
|
||||||
|
│ ├── html5ever v0.24.0
|
||||||
|
│ │ ├── log v0.4.8
|
||||||
|
│ │ │ └── cfg-if v0.1.9
|
||||||
|
│ │ ├── mac v0.1.1
|
||||||
|
│ │ └── markup5ever v0.9.0
|
||||||
|
│ │ ├── log v0.4.8 (*)
|
||||||
|
│ │ ├── phf v0.7.24
|
||||||
|
│ │ │ └── phf_shared v0.7.24
|
||||||
|
│ │ │ ├── siphasher v0.2.3
|
||||||
|
│ │ │ └── unicase v1.4.2
|
||||||
|
│ │ │ [build-dependencies]
|
||||||
|
│ │ │ └── version_check v0.1.5
|
||||||
|
...
|
||||||
|
```
|
||||||
|
You can also display dependencies on multiple versions of the same crate with
|
||||||
|
`cargo tree -d` (short for `cargo tree --duplicates`).
|
||||||
|
|
||||||
|
Misc
|
||||||
|
----
|
||||||
|
- [Rustdoc now allows you to specify `--crate-version` to have rustdoc include
|
||||||
|
the version in the sidebar.][69494]
|
||||||
|
|
||||||
|
Compatibility Notes
|
||||||
|
-------------------
|
||||||
|
- [Rustc now correctly generates static libraries on Windows GNU targets with
|
||||||
|
the `.a` extension, rather than the previous `.lib`.][70937]
|
||||||
|
- [Removed the `-C no_integrated_as` flag from rustc.][70345]
|
||||||
|
- [The `file_name` property in JSON output of macro errors now points the actual
|
||||||
|
source file rather than the previous format of `<NAME macros>`.][70969]
|
||||||
|
**Note:** this may not point a file that actually exists on the user's system.
|
||||||
|
- [The minimum required external LLVM version has been bumped to LLVM 8.][71147]
|
||||||
|
- [`mem::{zeroed, uninitialised}` will now panic when used with types that do
|
||||||
|
not allow zero initialization such as `NonZeroU8`.][66059] This was
|
||||||
|
previously a warning.
|
||||||
|
- [In 1.45.0 (the next release) converting a `f64` to `u32` using the `as`
|
||||||
|
operator has been defined as a saturating operation.][71269] This was previously
|
||||||
|
undefined behaviour, you can use the `{f64, f32}::to_int_unchecked` methods to
|
||||||
|
continue using the current behaviour which may desirable in rare performance
|
||||||
|
sensitive situations.
|
||||||
|
|
||||||
|
Internal Only
|
||||||
|
-------------
|
||||||
|
These changes provide no direct user facing benefits, but represent significant
|
||||||
|
improvements to the internals and overall performance of rustc and
|
||||||
|
related tools.
|
||||||
|
|
||||||
|
- [dep_graph Avoid allocating a set on when the number reads are small.][69778]
|
||||||
|
- [Replace big JS dict with JSON parsing.][71250]
|
||||||
|
|
||||||
|
[69373]: https://github.com/rust-lang/rust/pull/69373/
|
||||||
|
[66059]: https://github.com/rust-lang/rust/pull/66059/
|
||||||
|
[68191]: https://github.com/rust-lang/rust/pull/68191/
|
||||||
|
[68899]: https://github.com/rust-lang/rust/pull/68899/
|
||||||
|
[71147]: https://github.com/rust-lang/rust/pull/71147/
|
||||||
|
[71250]: https://github.com/rust-lang/rust/pull/71250/
|
||||||
|
[70937]: https://github.com/rust-lang/rust/pull/70937/
|
||||||
|
[70969]: https://github.com/rust-lang/rust/pull/70969/
|
||||||
|
[70632]: https://github.com/rust-lang/rust/pull/70632/
|
||||||
|
[70281]: https://github.com/rust-lang/rust/pull/70281/
|
||||||
|
[70345]: https://github.com/rust-lang/rust/pull/70345/
|
||||||
|
[70048]: https://github.com/rust-lang/rust/pull/70048/
|
||||||
|
[70081]: https://github.com/rust-lang/rust/pull/70081/
|
||||||
|
[70156]: https://github.com/rust-lang/rust/pull/70156/
|
||||||
|
[71269]: https://github.com/rust-lang/rust/pull/71269/
|
||||||
|
[69838]: https://github.com/rust-lang/rust/pull/69838/
|
||||||
|
[69929]: https://github.com/rust-lang/rust/pull/69929/
|
||||||
|
[69661]: https://github.com/rust-lang/rust/pull/69661/
|
||||||
|
[69778]: https://github.com/rust-lang/rust/pull/69778/
|
||||||
|
[69494]: https://github.com/rust-lang/rust/pull/69494/
|
||||||
|
[69403]: https://github.com/rust-lang/rust/pull/69403/
|
||||||
|
[69033]: https://github.com/rust-lang/rust/pull/69033/
|
||||||
|
[68692]: https://github.com/rust-lang/rust/pull/68692/
|
||||||
|
[68334]: https://github.com/rust-lang/rust/pull/68334/
|
||||||
|
[67502]: https://github.com/rust-lang/rust/pull/67502/
|
||||||
|
[cargo/8062]: https://github.com/rust-lang/cargo/pull/8062/
|
||||||
|
[`PathBuf::with_capacity`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.with_capacity
|
||||||
|
[`PathBuf::capacity`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.capacity
|
||||||
|
[`PathBuf::clear`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.clear
|
||||||
|
[`PathBuf::reserve`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.reserve
|
||||||
|
[`PathBuf::reserve_exact`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.reserve_exact
|
||||||
|
[`PathBuf::shrink_to_fit`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.shrink_to_fit
|
||||||
|
[`f32::to_int_unchecked`]: https://doc.rust-lang.org/std/primitive.f32.html#method.to_int_unchecked
|
||||||
|
[`f64::to_int_unchecked`]: https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked
|
||||||
|
[`Layout::align_to`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.align_to
|
||||||
|
[`Layout::pad_to_align`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.pad_to_align
|
||||||
|
[`Layout::array`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.array
|
||||||
|
[`Layout::extend`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.extend
|
||||||
|
|
||||||
|
|
||||||
Version 1.43.1 (2020-05-07)
|
Version 1.43.1 (2020-05-07)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ fi
|
|||||||
#
|
#
|
||||||
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
||||||
# either automatically or manually.
|
# either automatically or manually.
|
||||||
export RUST_RELEASE_CHANNEL=beta
|
export RUST_RELEASE_CHANNEL=stable
|
||||||
|
|
||||||
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
|
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
|
||||||
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
|
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
|
||||||
|
@ -1086,7 +1086,7 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
if !path.is_absolute() {
|
if !path.is_absolute() {
|
||||||
let callsite = span.source_callsite();
|
let callsite = span.source_callsite();
|
||||||
let mut result = match self.source_map().span_to_unmapped_path(callsite) {
|
let mut result = match self.source_map().span_to_unmapped_path(callsite) {
|
||||||
FileName::Real(path) => path,
|
FileName::Real(name) => name.into_local_path(),
|
||||||
FileName::DocTest(path, _) => path,
|
FileName::DocTest(path, _) => path,
|
||||||
other => {
|
other => {
|
||||||
return Err(self.struct_span_err(
|
return Err(self.struct_span_err(
|
||||||
|
@ -340,7 +340,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
let mut module = ModuleData {
|
let mut module = ModuleData {
|
||||||
mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
|
mod_path: vec![Ident::from_str(&self.cx.ecfg.crate_name)],
|
||||||
directory: match self.cx.source_map().span_to_unmapped_path(krate.span) {
|
directory: match self.cx.source_map().span_to_unmapped_path(krate.span) {
|
||||||
FileName::Real(path) => path,
|
FileName::Real(name) => name.into_local_path(),
|
||||||
other => PathBuf::from(other.to_string()),
|
other => PathBuf::from(other.to_string()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -71,7 +71,7 @@ crate fn parse_external_mod(
|
|||||||
// Extract the directory path for submodules of `module`.
|
// Extract the directory path for submodules of `module`.
|
||||||
let path = sess.source_map().span_to_unmapped_path(module.inner);
|
let path = sess.source_map().span_to_unmapped_path(module.inner);
|
||||||
let mut path = match path {
|
let mut path = match path {
|
||||||
FileName::Real(path) => path,
|
FileName::Real(name) => name.into_local_path(),
|
||||||
other => PathBuf::from(other.to_string()),
|
other => PathBuf::from(other.to_string()),
|
||||||
};
|
};
|
||||||
path.pop();
|
path.pop();
|
||||||
@ -189,7 +189,8 @@ fn error_cannot_declare_mod_here<'a, T>(
|
|||||||
let mut err =
|
let mut err =
|
||||||
sess.span_diagnostic.struct_span_err(span, "cannot declare a new module at this location");
|
sess.span_diagnostic.struct_span_err(span, "cannot declare a new module at this location");
|
||||||
if !span.is_dummy() {
|
if !span.is_dummy() {
|
||||||
if let FileName::Real(src_path) = sess.source_map().span_to_filename(span) {
|
if let FileName::Real(src_name) = sess.source_map().span_to_filename(span) {
|
||||||
|
let src_path = src_name.into_local_path();
|
||||||
if let Some(stem) = src_path.file_stem() {
|
if let Some(stem) = src_path.file_stem() {
|
||||||
let mut dest_path = src_path.clone();
|
let mut dest_path = src_path.clone();
|
||||||
dest_path.set_file_name(stem);
|
dest_path.set_file_name(stem);
|
||||||
|
@ -596,7 +596,8 @@ impl server::SourceFile for Rustc<'_> {
|
|||||||
}
|
}
|
||||||
fn path(&mut self, file: &Self::SourceFile) -> String {
|
fn path(&mut self, file: &Self::SourceFile) -> String {
|
||||||
match file.name {
|
match file.name {
|
||||||
FileName::Real(ref path) => path
|
FileName::Real(ref name) => name
|
||||||
|
.local_path()
|
||||||
.to_str()
|
.to_str()
|
||||||
.expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
|
.expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
@ -35,7 +35,7 @@ use rustc_session::output::{filename_for_input, filename_for_metadata};
|
|||||||
use rustc_session::search_paths::PathKind;
|
use rustc_session::search_paths::PathKind;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::FileName;
|
use rustc_span::{FileName, RealFileName};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use rustc_typeck as typeck;
|
use rustc_typeck as typeck;
|
||||||
|
|
||||||
@ -570,13 +570,16 @@ fn write_out_deps(
|
|||||||
for cnum in resolver.cstore().crates_untracked() {
|
for cnum in resolver.cstore().crates_untracked() {
|
||||||
let source = resolver.cstore().crate_source_untracked(cnum);
|
let source = resolver.cstore().crate_source_untracked(cnum);
|
||||||
if let Some((path, _)) = source.dylib {
|
if let Some((path, _)) = source.dylib {
|
||||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
let file_name = FileName::Real(RealFileName::Named(path));
|
||||||
|
files.push(escape_dep_filename(&file_name));
|
||||||
}
|
}
|
||||||
if let Some((path, _)) = source.rlib {
|
if let Some((path, _)) = source.rlib {
|
||||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
let file_name = FileName::Real(RealFileName::Named(path));
|
||||||
|
files.push(escape_dep_filename(&file_name));
|
||||||
}
|
}
|
||||||
if let Some((path, _)) = source.rmeta {
|
if let Some((path, _)) = source.rmeta {
|
||||||
files.push(escape_dep_filename(&FileName::Real(path)));
|
let file_name = FileName::Real(RealFileName::Named(path));
|
||||||
|
files.push(escape_dep_filename(&file_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1485,15 +1485,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
|
|
||||||
if let Some(virtual_dir) = virtual_rust_source_base_dir {
|
if let Some(virtual_dir) = virtual_rust_source_base_dir {
|
||||||
if let Some(real_dir) = &sess.real_rust_source_base_dir {
|
if let Some(real_dir) = &sess.real_rust_source_base_dir {
|
||||||
if let rustc_span::FileName::Real(path) = name {
|
if let rustc_span::FileName::Real(old_name) = name {
|
||||||
if let Ok(rest) = path.strip_prefix(virtual_dir) {
|
if let rustc_span::RealFileName::Named(one_path) = old_name {
|
||||||
|
if let Ok(rest) = one_path.strip_prefix(virtual_dir) {
|
||||||
|
let virtual_name = one_path.clone();
|
||||||
let new_path = real_dir.join(rest);
|
let new_path = real_dir.join(rest);
|
||||||
debug!(
|
debug!(
|
||||||
"try_to_translate_virtual_to_real: `{}` -> `{}`",
|
"try_to_translate_virtual_to_real: `{}` -> `{}`",
|
||||||
path.display(),
|
virtual_name.display(),
|
||||||
new_path.display(),
|
new_path.display(),
|
||||||
);
|
);
|
||||||
*path = new_path;
|
let new_name = rustc_span::RealFileName::Devirtualized {
|
||||||
|
local_path: new_path,
|
||||||
|
virtual_name,
|
||||||
|
};
|
||||||
|
*old_name = new_name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,6 +398,7 @@ impl<'tcx> EncodeContext<'tcx> {
|
|||||||
// any relative paths are potentially relative to a
|
// any relative paths are potentially relative to a
|
||||||
// wrong directory.
|
// wrong directory.
|
||||||
FileName::Real(ref name) => {
|
FileName::Real(ref name) => {
|
||||||
|
let name = name.stable_name();
|
||||||
let mut adapted = (**source_file).clone();
|
let mut adapted = (**source_file).clone();
|
||||||
adapted.name = Path::new(&working_dir).join(name).into();
|
adapted.name = Path::new(&working_dir).join(name).into();
|
||||||
adapted.name_hash = {
|
adapted.name_hash = {
|
||||||
|
@ -16,12 +16,13 @@ impl<'a> SpanUtils<'a> {
|
|||||||
|
|
||||||
pub fn make_filename_string(&self, file: &SourceFile) -> String {
|
pub fn make_filename_string(&self, file: &SourceFile) -> String {
|
||||||
match &file.name {
|
match &file.name {
|
||||||
FileName::Real(path) if !file.name_was_remapped => {
|
FileName::Real(name) if !file.name_was_remapped => {
|
||||||
|
let path = name.local_path();
|
||||||
if path.is_absolute() {
|
if path.is_absolute() {
|
||||||
self.sess
|
self.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.path_mapping()
|
.path_mapping()
|
||||||
.map_prefix(path.clone())
|
.map_prefix(path.into())
|
||||||
.0
|
.0
|
||||||
.display()
|
.display()
|
||||||
.to_string()
|
.to_string()
|
||||||
|
@ -49,7 +49,7 @@ use std::cmp::{self, Ordering};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::{Add, Sub};
|
use std::ops::{Add, Sub};
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use md5::Md5;
|
use md5::Md5;
|
||||||
@ -77,11 +77,61 @@ impl Globals {
|
|||||||
|
|
||||||
scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
|
scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
|
||||||
|
|
||||||
|
// FIXME: Perhaps this should not implement Rustc{Decodable, Encodable}
|
||||||
|
//
|
||||||
|
// FIXME: We should use this enum or something like it to get rid of the
|
||||||
|
// use of magic `/rust/1.x/...` paths across the board.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
|
||||||
|
#[derive(HashStable_Generic)]
|
||||||
|
pub enum RealFileName {
|
||||||
|
Named(PathBuf),
|
||||||
|
/// For de-virtualized paths (namely paths into libstd that have been mapped
|
||||||
|
/// to the appropriate spot on the local host's file system),
|
||||||
|
Devirtualized {
|
||||||
|
/// `local_path` is the (host-dependent) local path to the file.
|
||||||
|
local_path: PathBuf,
|
||||||
|
/// `virtual_name` is the stable path rustc will store internally within
|
||||||
|
/// build artifacts.
|
||||||
|
virtual_name: PathBuf,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RealFileName {
|
||||||
|
/// Returns the path suitable for reading from the file system on the local host.
|
||||||
|
/// Avoid embedding this in build artifacts; see `stable_name` for that.
|
||||||
|
pub fn local_path(&self) -> &Path {
|
||||||
|
match self {
|
||||||
|
RealFileName::Named(p)
|
||||||
|
| RealFileName::Devirtualized { local_path: p, virtual_name: _ } => &p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path suitable for reading from the file system on the local host.
|
||||||
|
/// Avoid embedding this in build artifacts; see `stable_name` for that.
|
||||||
|
pub fn into_local_path(self) -> PathBuf {
|
||||||
|
match self {
|
||||||
|
RealFileName::Named(p)
|
||||||
|
| RealFileName::Devirtualized { local_path: p, virtual_name: _ } => p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path suitable for embedding into build artifacts. Note that
|
||||||
|
/// a virtualized path will not correspond to a valid file system path; see
|
||||||
|
/// `local_path` for something that is more likely to return paths into the
|
||||||
|
/// local host file system.
|
||||||
|
pub fn stable_name(&self) -> &Path {
|
||||||
|
match self {
|
||||||
|
RealFileName::Named(p)
|
||||||
|
| RealFileName::Devirtualized { local_path: _, virtual_name: p } => &p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Differentiates between real files and common virtual files.
|
/// Differentiates between real files and common virtual files.
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
|
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)]
|
||||||
#[derive(HashStable_Generic)]
|
#[derive(HashStable_Generic)]
|
||||||
pub enum FileName {
|
pub enum FileName {
|
||||||
Real(PathBuf),
|
Real(RealFileName),
|
||||||
/// Call to `quote!`.
|
/// Call to `quote!`.
|
||||||
QuoteExpansion(u64),
|
QuoteExpansion(u64),
|
||||||
/// Command line.
|
/// Command line.
|
||||||
@ -103,7 +153,13 @@ impl std::fmt::Display for FileName {
|
|||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
use FileName::*;
|
use FileName::*;
|
||||||
match *self {
|
match *self {
|
||||||
Real(ref path) => write!(fmt, "{}", path.display()),
|
Real(RealFileName::Named(ref path)) => write!(fmt, "{}", path.display()),
|
||||||
|
// FIXME: might be nice to display both compoments of Devirtualized.
|
||||||
|
// But for now (to backport fix for issue #70924), best to not
|
||||||
|
// perturb diagnostics so its obvious test suite still works.
|
||||||
|
Real(RealFileName::Devirtualized { ref local_path, virtual_name: _ }) => {
|
||||||
|
write!(fmt, "{}", local_path.display())
|
||||||
|
}
|
||||||
QuoteExpansion(_) => write!(fmt, "<quote expansion>"),
|
QuoteExpansion(_) => write!(fmt, "<quote expansion>"),
|
||||||
MacroExpansion(_) => write!(fmt, "<macro expansion>"),
|
MacroExpansion(_) => write!(fmt, "<macro expansion>"),
|
||||||
Anon(_) => write!(fmt, "<anon>"),
|
Anon(_) => write!(fmt, "<anon>"),
|
||||||
@ -119,7 +175,7 @@ impl std::fmt::Display for FileName {
|
|||||||
impl From<PathBuf> for FileName {
|
impl From<PathBuf> for FileName {
|
||||||
fn from(p: PathBuf) -> Self {
|
fn from(p: PathBuf) -> Self {
|
||||||
assert!(!p.to_string_lossy().ends_with('>'));
|
assert!(!p.to_string_lossy().ends_with('>'));
|
||||||
FileName::Real(p)
|
FileName::Real(RealFileName::Named(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ impl FileLoader for RealFileLoader {
|
|||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct StableSourceFileId(u128);
|
pub struct StableSourceFileId(u128);
|
||||||
|
|
||||||
|
// FIXME: we need a more globally consistent approach to the problem solved by
|
||||||
|
// StableSourceFileId, perhaps built atop source_file.name_hash.
|
||||||
impl StableSourceFileId {
|
impl StableSourceFileId {
|
||||||
pub fn new(source_file: &SourceFile) -> StableSourceFileId {
|
pub fn new(source_file: &SourceFile) -> StableSourceFileId {
|
||||||
StableSourceFileId::new_from_pieces(
|
StableSourceFileId::new_from_pieces(
|
||||||
@ -107,14 +109,21 @@ impl StableSourceFileId {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_pieces(
|
fn new_from_pieces(
|
||||||
name: &FileName,
|
name: &FileName,
|
||||||
name_was_remapped: bool,
|
name_was_remapped: bool,
|
||||||
unmapped_path: Option<&FileName>,
|
unmapped_path: Option<&FileName>,
|
||||||
) -> StableSourceFileId {
|
) -> StableSourceFileId {
|
||||||
let mut hasher = StableHasher::new();
|
let mut hasher = StableHasher::new();
|
||||||
|
|
||||||
|
if let FileName::Real(real_name) = name {
|
||||||
|
// rust-lang/rust#70924: Use the stable (virtualized) name when
|
||||||
|
// available. (We do not want artifacts from transient file system
|
||||||
|
// paths for libstd to leak into our build artifacts.)
|
||||||
|
real_name.stable_name().hash(&mut hasher)
|
||||||
|
} else {
|
||||||
name.hash(&mut hasher);
|
name.hash(&mut hasher);
|
||||||
|
}
|
||||||
name_was_remapped.hash(&mut hasher);
|
name_was_remapped.hash(&mut hasher);
|
||||||
unmapped_path.hash(&mut hasher);
|
unmapped_path.hash(&mut hasher);
|
||||||
|
|
||||||
@ -247,7 +256,7 @@ impl SourceMap {
|
|||||||
|
|
||||||
fn try_new_source_file(
|
fn try_new_source_file(
|
||||||
&self,
|
&self,
|
||||||
filename: FileName,
|
mut filename: FileName,
|
||||||
src: String,
|
src: String,
|
||||||
) -> Result<Lrc<SourceFile>, OffsetOverflowError> {
|
) -> Result<Lrc<SourceFile>, OffsetOverflowError> {
|
||||||
// The path is used to determine the directory for loading submodules and
|
// The path is used to determine the directory for loading submodules and
|
||||||
@ -257,13 +266,22 @@ impl SourceMap {
|
|||||||
// be empty, so the working directory will be used.
|
// be empty, so the working directory will be used.
|
||||||
let unmapped_path = filename.clone();
|
let unmapped_path = filename.clone();
|
||||||
|
|
||||||
let (filename, was_remapped) = match filename {
|
let was_remapped;
|
||||||
FileName::Real(filename) => {
|
if let FileName::Real(real_filename) = &mut filename {
|
||||||
let (filename, was_remapped) = self.path_mapping.map_prefix(filename);
|
match real_filename {
|
||||||
(FileName::Real(filename), was_remapped)
|
RealFileName::Named(path_to_be_remapped)
|
||||||
|
| RealFileName::Devirtualized {
|
||||||
|
local_path: path_to_be_remapped,
|
||||||
|
virtual_name: _,
|
||||||
|
} => {
|
||||||
|
let mapped = self.path_mapping.map_prefix(path_to_be_remapped.clone());
|
||||||
|
was_remapped = mapped.1;
|
||||||
|
*path_to_be_remapped = mapped.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
was_remapped = false;
|
||||||
}
|
}
|
||||||
other => (other, false),
|
|
||||||
};
|
|
||||||
|
|
||||||
let file_id =
|
let file_id =
|
||||||
StableSourceFileId::new_from_pieces(&filename, was_remapped, Some(&unmapped_path));
|
StableSourceFileId::new_from_pieces(&filename, was_remapped, Some(&unmapped_path));
|
||||||
@ -1001,7 +1019,7 @@ impl SourceMap {
|
|||||||
}
|
}
|
||||||
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
|
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
|
||||||
source_file.add_external_src(|| match source_file.name {
|
source_file.add_external_src(|| match source_file.name {
|
||||||
FileName::Real(ref name) => self.file_loader.read_file(name).ok(),
|
FileName::Real(ref name) => self.file_loader.read_file(name.local_path()).ok(),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ pub fn run(
|
|||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let src_root = match krate.src {
|
let src_root = match krate.src {
|
||||||
FileName::Real(ref p) => match p.parent() {
|
FileName::Real(ref p) => match p.local_path().parent() {
|
||||||
Some(p) => p.to_path_buf(),
|
Some(p) => p.to_path_buf(),
|
||||||
None => PathBuf::new(),
|
None => PathBuf::new(),
|
||||||
},
|
},
|
||||||
@ -1650,9 +1650,10 @@ impl Context {
|
|||||||
|
|
||||||
// We can safely ignore synthetic `SourceFile`s.
|
// We can safely ignore synthetic `SourceFile`s.
|
||||||
let file = match item.source.filename {
|
let file = match item.source.filename {
|
||||||
FileName::Real(ref path) => path,
|
FileName::Real(ref path) => path.local_path().to_path_buf(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
let file = &file;
|
||||||
|
|
||||||
let (krate, path) = if item.source.cnum == LOCAL_CRATE {
|
let (krate, path) = if item.source.cnum == LOCAL_CRATE {
|
||||||
if let Some(path) = self.shared.local_sources.get(file) {
|
if let Some(path) = self.shared.local_sources.get(file) {
|
||||||
|
@ -173,7 +173,7 @@ impl Cache {
|
|||||||
// Cache where all our extern crates are located
|
// Cache where all our extern crates are located
|
||||||
for &(n, ref e) in &krate.externs {
|
for &(n, ref e) in &krate.externs {
|
||||||
let src_root = match e.src {
|
let src_root = match e.src {
|
||||||
FileName::Real(ref p) => match p.parent() {
|
FileName::Real(ref p) => match p.local_path().parent() {
|
||||||
Some(p) => p.to_path_buf(),
|
Some(p) => p.to_path_buf(),
|
||||||
None => PathBuf::new(),
|
None => PathBuf::new(),
|
||||||
},
|
},
|
||||||
|
@ -67,10 +67,10 @@ impl<'a> SourceCollector<'a> {
|
|||||||
/// Renders the given filename into its corresponding HTML source file.
|
/// Renders the given filename into its corresponding HTML source file.
|
||||||
fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
|
fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
|
||||||
let p = match *filename {
|
let p = match *filename {
|
||||||
FileName::Real(ref file) => file,
|
FileName::Real(ref file) => file.local_path().to_path_buf(),
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
if self.scx.local_sources.contains_key(&**p) {
|
if self.scx.local_sources.contains_key(&*p) {
|
||||||
// We've already emitted this source
|
// We've already emitted this source
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -663,7 +663,7 @@ impl Collector {
|
|||||||
let filename = source_map.span_to_filename(self.position);
|
let filename = source_map.span_to_filename(self.position);
|
||||||
if let FileName::Real(ref filename) = filename {
|
if let FileName::Real(ref filename) = filename {
|
||||||
if let Ok(cur_dir) = env::current_dir() {
|
if let Ok(cur_dir) = env::current_dir() {
|
||||||
if let Ok(path) = filename.strip_prefix(&cur_dir) {
|
if let Ok(path) = filename.local_path().strip_prefix(&cur_dir) {
|
||||||
return path.to_owned().into();
|
return path.to_owned().into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -693,7 +693,7 @@ impl Tester for Collector {
|
|||||||
// FIXME(#44940): if doctests ever support path remapping, then this filename
|
// FIXME(#44940): if doctests ever support path remapping, then this filename
|
||||||
// needs to be the result of `SourceMap::span_to_unmapped_path`.
|
// needs to be the result of `SourceMap::span_to_unmapped_path`.
|
||||||
let path = match &filename {
|
let path = match &filename {
|
||||||
FileName::Real(path) => path.clone(),
|
FileName::Real(path) => path.local_path().to_path_buf(),
|
||||||
_ => PathBuf::from(r"doctest.rs"),
|
_ => PathBuf::from(r"doctest.rs"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user