mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-14 00:45:06 +00:00
New upstream version 1.28.0+dfsg1
This commit is contained in:
parent
94b46f3498
commit
74d2073768
24
RELEASES.md
24
RELEASES.md
@ -52,6 +52,16 @@ Stabilized APIs
|
||||
---------------
|
||||
- [`Iterator::step_by`]
|
||||
- [`Path::ancestors`]
|
||||
- [`SystemTime::UNIX_EPOCH`]
|
||||
- [`alloc::GlobalAlloc`]
|
||||
- [`alloc::Layout`]
|
||||
- [`alloc::LayoutErr`]
|
||||
- [`alloc::System`]
|
||||
- [`alloc::alloc`]
|
||||
- [`alloc::alloc_zeroed`]
|
||||
- [`alloc::dealloc`]
|
||||
- [`alloc::realloc`]
|
||||
- [`alloc::handle_alloc_error`]
|
||||
- [`btree_map::Entry::or_default`]
|
||||
- [`fmt::Alignment`]
|
||||
- [`hash_map::Entry::or_default`]
|
||||
@ -122,6 +132,16 @@ Compatibility Notes
|
||||
[cargo/5584]: https://github.com/rust-lang/cargo/pull/5584/
|
||||
[`Iterator::step_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.step_by
|
||||
[`Path::ancestors`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.ancestors
|
||||
[`SystemTime::UNIX_EPOCH`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#associatedconstant.UNIX_EPOCH
|
||||
[`alloc::GlobalAlloc`]: https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html
|
||||
[`alloc::Layout`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html
|
||||
[`alloc::LayoutErr`]: https://doc.rust-lang.org/std/alloc/struct.LayoutErr.html
|
||||
[`alloc::System`]: https://doc.rust-lang.org/std/alloc/struct.System.html
|
||||
[`alloc::alloc`]: https://doc.rust-lang.org/std/alloc/fn.alloc.html
|
||||
[`alloc::alloc_zeroed`]: https://doc.rust-lang.org/std/alloc/fn.alloc_zeroed.html
|
||||
[`alloc::dealloc`]: https://doc.rust-lang.org/std/alloc/fn.dealloc.html
|
||||
[`alloc::realloc`]: https://doc.rust-lang.org/std/alloc/fn.realloc.html
|
||||
[`alloc::handle_alloc_error`]: https://doc.rust-lang.org/std/alloc/fn.handle_alloc_error.html
|
||||
[`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
|
||||
[`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html
|
||||
[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default
|
||||
@ -3162,7 +3182,7 @@ Stabilized APIs
|
||||
* [`UnixDatagram::shutdown`](http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.shutdown)
|
||||
* RawFd impls for `UnixDatagram`
|
||||
* `{BTree,Hash}Map::values_mut`
|
||||
* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/beta/std/primitive.slice.html#method.binary_search_by_key)
|
||||
* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by_key)
|
||||
|
||||
Libraries
|
||||
---------
|
||||
@ -4080,7 +4100,7 @@ Compatibility Notes
|
||||
[1.6bh]: https://github.com/rust-lang/rust/pull/29811
|
||||
[1.6c]: https://github.com/rust-lang/cargo/pull/2192
|
||||
[1.6cc]: https://github.com/rust-lang/cargo/pull/2131
|
||||
[1.6co]: http://doc.rust-lang.org/beta/core/index.html
|
||||
[1.6co]: http://doc.rust-lang.org/core/index.html
|
||||
[1.6dv]: https://github.com/rust-lang/rust/pull/30000
|
||||
[1.6f]: https://github.com/rust-lang/rust/pull/29129
|
||||
[1.6m]: https://github.com/rust-lang/rust/pull/29828
|
||||
|
@ -1 +1 @@
|
||||
0aaa819fea00a6bf2b1303b9eb47f142f099cf5a
|
||||
9634041f0e8c0f3191d2867311276f19d0a42564
|
@ -46,7 +46,7 @@ fi
|
||||
#
|
||||
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
||||
# either automatically or manually.
|
||||
export RUST_RELEASE_CHANNEL=beta
|
||||
export RUST_RELEASE_CHANNEL=stable
|
||||
if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
|
||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
|
||||
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
|
||||
|
@ -1483,10 +1483,12 @@ fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<as
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs `f` in a suitable thread for running `rustc`; returns a
|
||||
/// `Result` with either the return value of `f` or -- if a panic
|
||||
/// occurs -- the panic value.
|
||||
pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
|
||||
/// Runs `f` in a suitable thread for running `rustc`; returns a `Result` with either the return
|
||||
/// value of `f` or -- if a panic occurs -- the panic value.
|
||||
///
|
||||
/// This version applies the given name to the thread. This is used by rustdoc to ensure consistent
|
||||
/// doctest output across platforms and executions.
|
||||
pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<Any + Send>>
|
||||
where F: FnOnce() -> R + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
@ -1530,7 +1532,7 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
|
||||
|
||||
// The or condition is added from backward compatibility.
|
||||
if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() {
|
||||
let mut cfg = thread::Builder::new().name("rustc".to_string());
|
||||
let mut cfg = thread::Builder::new().name(name);
|
||||
|
||||
// FIXME: Hacks on hacks. If the env is trying to override the stack size
|
||||
// then *don't* set it explicitly.
|
||||
@ -1546,6 +1548,16 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs `f` in a suitable thread for running `rustc`; returns a
|
||||
/// `Result` with either the return value of `f` or -- if a panic
|
||||
/// occurs -- the panic value.
|
||||
pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<dyn Any + Send>>
|
||||
where F: FnOnce() -> R + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
in_named_rustc_thread("rustc".to_string(), f)
|
||||
}
|
||||
|
||||
/// Get a list of extra command-line flags provided by the user, as strings.
|
||||
///
|
||||
/// This function is used during ICEs to show more information useful for
|
||||
|
@ -165,18 +165,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
op,
|
||||
is_assign);
|
||||
|
||||
let lhs_needs = match is_assign {
|
||||
IsAssign::Yes => Needs::MutPlace,
|
||||
IsAssign::No => Needs::None
|
||||
let lhs_ty = match is_assign {
|
||||
IsAssign::No => {
|
||||
// Find a suitable supertype of the LHS expression's type, by coercing to
|
||||
// a type variable, to pass as the `Self` to the trait, avoiding invariant
|
||||
// trait matching creating lifetime constraints that are too strict.
|
||||
// E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
|
||||
// in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
|
||||
let lhs_ty = self.check_expr_with_needs(lhs_expr, Needs::None);
|
||||
let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
|
||||
self.demand_coerce(lhs_expr, lhs_ty, fresh_var, AllowTwoPhase::No)
|
||||
}
|
||||
IsAssign::Yes => {
|
||||
// rust-lang/rust#52126: We have to use strict
|
||||
// equivalence on the LHS of an assign-op like `+=`;
|
||||
// overwritten or mutably-borrowed places cannot be
|
||||
// coerced to a supertype.
|
||||
self.check_expr_with_needs(lhs_expr, Needs::MutPlace)
|
||||
}
|
||||
};
|
||||
// Find a suitable supertype of the LHS expression's type, by coercing to
|
||||
// a type variable, to pass as the `Self` to the trait, avoiding invariant
|
||||
// trait matching creating lifetime constraints that are too strict.
|
||||
// E.g. adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result
|
||||
// in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`.
|
||||
let lhs_ty = self.check_expr_with_needs(lhs_expr, lhs_needs);
|
||||
let fresh_var = self.next_ty_var(TypeVariableOrigin::MiscVariable(lhs_expr.span));
|
||||
let lhs_ty = self.demand_coerce(lhs_expr, lhs_ty, fresh_var, AllowTwoPhase::No);
|
||||
let lhs_ty = self.resolve_type_vars_with_obligations(lhs_ty);
|
||||
|
||||
// NB: As we have not yet type-checked the RHS, we don't have the
|
||||
|
@ -214,7 +214,7 @@ pub fn run_core(search_paths: SearchPaths,
|
||||
} else {
|
||||
vec![]
|
||||
},
|
||||
lint_cap: Some(lint::Forbid),
|
||||
lint_cap: Some(lint::Allow),
|
||||
cg,
|
||||
externs,
|
||||
target_triple: triple.unwrap_or(host_triple),
|
||||
|
@ -232,31 +232,35 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
|
||||
..config::basic_options().clone()
|
||||
};
|
||||
|
||||
let (libdir, outdir) = driver::spawn_thread_pool(sessopts, |sessopts| {
|
||||
// Shuffle around a few input and output handles here. We're going to pass
|
||||
// an explicit handle into rustc to collect output messages, but we also
|
||||
// want to catch the error message that rustc prints when it fails.
|
||||
//
|
||||
// We take our thread-local stderr (likely set by the test runner) and replace
|
||||
// it with a sink that is also passed to rustc itself. When this function
|
||||
// returns the output of the sink is copied onto the output of our own thread.
|
||||
//
|
||||
// The basic idea is to not use a default Handler for rustc, and then also
|
||||
// not print things by default to the actual stderr.
|
||||
struct Sink(Arc<Mutex<Vec<u8>>>);
|
||||
impl Write for Sink {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
Write::write(&mut *self.0.lock().unwrap(), data)
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
// Shuffle around a few input and output handles here. We're going to pass
|
||||
// an explicit handle into rustc to collect output messages, but we also
|
||||
// want to catch the error message that rustc prints when it fails.
|
||||
//
|
||||
// We take our thread-local stderr (likely set by the test runner) and replace
|
||||
// it with a sink that is also passed to rustc itself. When this function
|
||||
// returns the output of the sink is copied onto the output of our own thread.
|
||||
//
|
||||
// The basic idea is to not use a default Handler for rustc, and then also
|
||||
// not print things by default to the actual stderr.
|
||||
struct Sink(Arc<Mutex<Vec<u8>>>);
|
||||
impl Write for Sink {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
Write::write(&mut *self.0.lock().unwrap(), data)
|
||||
}
|
||||
struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
|
||||
impl Drop for Bomb {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.1.write_all(&self.0.lock().unwrap());
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> { Ok(()) }
|
||||
}
|
||||
struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
|
||||
impl Drop for Bomb {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.1.write_all(&self.0.lock().unwrap());
|
||||
}
|
||||
let data = Arc::new(Mutex::new(Vec::new()));
|
||||
}
|
||||
let data = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let old = io::set_panic(Some(box Sink(data.clone())));
|
||||
let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
|
||||
|
||||
let (libdir, outdir, compile_result) = driver::spawn_thread_pool(sessopts, |sessopts| {
|
||||
let codemap = Lrc::new(CodeMap::new_doctest(
|
||||
sessopts.file_path_mapping(), filename.clone(), line as isize - line_offset as isize
|
||||
));
|
||||
@ -264,8 +268,6 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
|
||||
Some(codemap.clone()),
|
||||
false,
|
||||
false);
|
||||
let old = io::set_panic(Some(box Sink(data.clone())));
|
||||
let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
|
||||
|
||||
// Compile the code
|
||||
let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter);
|
||||
@ -310,29 +312,29 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
|
||||
Err(_) | Ok(Err(CompileIncomplete::Errored(_))) => Err(())
|
||||
};
|
||||
|
||||
match (compile_result, compile_fail) {
|
||||
(Ok(()), true) => {
|
||||
panic!("test compiled while it wasn't supposed to")
|
||||
}
|
||||
(Ok(()), false) => {}
|
||||
(Err(()), true) => {
|
||||
if error_codes.len() > 0 {
|
||||
let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
|
||||
error_codes.retain(|err| !out.contains(err));
|
||||
}
|
||||
}
|
||||
(Err(()), false) => {
|
||||
panic!("couldn't compile the test")
|
||||
}
|
||||
}
|
||||
|
||||
if error_codes.len() > 0 {
|
||||
panic!("Some expected error codes were not found: {:?}", error_codes);
|
||||
}
|
||||
|
||||
(libdir, outdir)
|
||||
(libdir, outdir, compile_result)
|
||||
});
|
||||
|
||||
match (compile_result, compile_fail) {
|
||||
(Ok(()), true) => {
|
||||
panic!("test compiled while it wasn't supposed to")
|
||||
}
|
||||
(Ok(()), false) => {}
|
||||
(Err(()), true) => {
|
||||
if error_codes.len() > 0 {
|
||||
let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
|
||||
error_codes.retain(|err| !out.contains(err));
|
||||
}
|
||||
}
|
||||
(Err(()), false) => {
|
||||
panic!("couldn't compile the test")
|
||||
}
|
||||
}
|
||||
|
||||
if error_codes.len() > 0 {
|
||||
panic!("Some expected error codes were not found: {:?}", error_codes);
|
||||
}
|
||||
|
||||
if no_run { return }
|
||||
|
||||
// Run the code!
|
||||
@ -546,7 +548,7 @@ impl Collector {
|
||||
debug!("Creating test {}: {}", name, test);
|
||||
self.tests.push(testing::TestDescAndFn {
|
||||
desc: testing::TestDesc {
|
||||
name: testing::DynTestName(name),
|
||||
name: testing::DynTestName(name.clone()),
|
||||
ignore: should_ignore,
|
||||
// compiler failures are test failures
|
||||
should_panic: testing::ShouldPanic::No,
|
||||
@ -556,7 +558,7 @@ impl Collector {
|
||||
let panic = io::set_panic(None);
|
||||
let print = io::set_print(None);
|
||||
match {
|
||||
rustc_driver::in_rustc_thread(move || with_globals(move || {
|
||||
rustc_driver::in_named_rustc_thread(name, move || with_globals(move || {
|
||||
io::set_panic(panic);
|
||||
io::set_print(print);
|
||||
run_test(&test,
|
||||
|
@ -331,9 +331,7 @@
|
||||
// `force_alloc_system` is *only* intended as a workaround for local rebuilds
|
||||
// with a rustc without jemalloc.
|
||||
// FIXME(#44236) shouldn't need MSVC logic
|
||||
#![cfg_attr(all(not(target_env = "msvc"),
|
||||
any(all(stage0, not(test)), feature = "force_alloc_system")),
|
||||
feature(global_allocator))]
|
||||
#![cfg_attr(all(not(target_env = "msvc"), stage0, not(test)), feature(global_allocator))]
|
||||
#[cfg(all(not(target_env = "msvc"),
|
||||
any(all(stage0, not(test)), feature = "force_alloc_system")))]
|
||||
#[global_allocator]
|
||||
|
@ -12,8 +12,8 @@
|
||||
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
|
||||
# `0.x.0` for Cargo where they were released on `date`.
|
||||
|
||||
date: 2018-06-21
|
||||
rustc: 1.27.0
|
||||
date: 2018-07-20
|
||||
rustc: 1.27.2
|
||||
cargo: 0.28.0
|
||||
|
||||
# When making a stable release the process currently looks like:
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-test
|
||||
|
||||
#![deny(intra_doc_link_resolution_failure)]
|
||||
|
||||
/// [v2] //~ ERROR
|
||||
|
29
src/test/rustdoc-ui/failed-doctest-output.rs
Normal file
29
src/test/rustdoc-ui/failed-doctest-output.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Issue #51162: A failed doctest was not printing its stdout/stderr
|
||||
// FIXME: if/when the output of the test harness can be tested on its own, this test should be
|
||||
// adapted to use that, and that normalize line can go away
|
||||
|
||||
// compile-flags:--test
|
||||
// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
|
||||
// failure-status: 101
|
||||
|
||||
// doctest fails at runtime
|
||||
/// ```
|
||||
/// panic!("oh no");
|
||||
/// ```
|
||||
pub struct SomeStruct;
|
||||
|
||||
// doctest fails at compile time
|
||||
/// ```
|
||||
/// no
|
||||
/// ```
|
||||
pub struct OtherStruct;
|
32
src/test/rustdoc-ui/failed-doctest-output.stdout
Normal file
32
src/test/rustdoc-ui/failed-doctest-output.stdout
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
running 2 tests
|
||||
test $DIR/failed-doctest-output.rs - OtherStruct (line 26) ... FAILED
|
||||
test $DIR/failed-doctest-output.rs - SomeStruct (line 20) ... FAILED
|
||||
|
||||
failures:
|
||||
|
||||
---- $DIR/failed-doctest-output.rs - OtherStruct (line 26) stdout ----
|
||||
error[E0425]: cannot find value `no` in this scope
|
||||
--> $DIR/failed-doctest-output.rs:27:1
|
||||
|
|
||||
3 | no
|
||||
| ^^ not found in this scope
|
||||
|
||||
thread '$DIR/failed-doctest-output.rs - OtherStruct (line 26)' panicked at 'couldn't compile the test', librustdoc/test.rs:330:13
|
||||
note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
||||
|
||||
---- $DIR/failed-doctest-output.rs - SomeStruct (line 20) stdout ----
|
||||
thread '$DIR/failed-doctest-output.rs - SomeStruct (line 20)' panicked at 'test executable failed:
|
||||
|
||||
thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
|
||||
note: Run with `RUST_BACKTRACE=1` for a backtrace.
|
||||
|
||||
', librustdoc/test.rs:365:17
|
||||
|
||||
|
||||
failures:
|
||||
$DIR/failed-doctest-output.rs - OtherStruct (line 26)
|
||||
$DIR/failed-doctest-output.rs - SomeStruct (line 20)
|
||||
|
||||
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-test
|
||||
|
||||
// compile-pass
|
||||
|
||||
//! Test with [Foo::baz], [Bar::foo], ...
|
||||
|
15
src/test/ui/issue-52126-assign-op-invariance.nll.stderr
Normal file
15
src/test/ui/issue-52126-assign-op-invariance.nll.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0597]: `line` does not live long enough
|
||||
--> $DIR/issue-52126-assign-op-invariance.rs:44:28
|
||||
|
|
||||
LL | let v: Vec<&str> = line.split_whitespace().collect();
|
||||
| ^^^^ borrowed value does not live long enough
|
||||
LL | //~^ ERROR `line` does not live long enough
|
||||
LL | println!("accumulator before add_assign {:?}", acc.map);
|
||||
| ------- borrow later used here
|
||||
...
|
||||
LL | }
|
||||
| - borrowed value only lives until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
59
src/test/ui/issue-52126-assign-op-invariance.rs
Normal file
59
src/test/ui/issue-52126-assign-op-invariance.rs
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Issue 52126: With respect to variance, the assign-op's like += were
|
||||
// accidentally lumped together with other binary op's. In both cases
|
||||
// we were coercing the LHS of the op to the expected supertype.
|
||||
//
|
||||
// The problem is that since the LHS of += is modified, we need the
|
||||
// parameter to be invariant with respect to the overall type, not
|
||||
// covariant.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
pub fn main() {
|
||||
panics();
|
||||
}
|
||||
|
||||
pub struct Counter<'l> {
|
||||
map: HashMap<&'l str, usize>,
|
||||
}
|
||||
|
||||
impl<'l> AddAssign for Counter<'l>
|
||||
{
|
||||
fn add_assign(&mut self, rhs: Counter<'l>) {
|
||||
rhs.map.into_iter().for_each(|(key, val)| {
|
||||
let count = self.map.entry(key).or_insert(0);
|
||||
*count += val;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// often times crashes, if not prints invalid strings
|
||||
pub fn panics() {
|
||||
let mut acc = Counter{map: HashMap::new()};
|
||||
for line in vec!["123456789".to_string(), "12345678".to_string()] {
|
||||
let v: Vec<&str> = line.split_whitespace().collect();
|
||||
//~^ ERROR `line` does not live long enough
|
||||
println!("accumulator before add_assign {:?}", acc.map);
|
||||
let mut map = HashMap::new();
|
||||
for str_ref in v {
|
||||
let e = map.entry(str_ref);
|
||||
println!("entry: {:?}", e);
|
||||
let count = e.or_insert(0);
|
||||
*count += 1;
|
||||
}
|
||||
let cnt2 = Counter{map};
|
||||
acc += cnt2;
|
||||
println!("accumulator after add_assign {:?}", acc.map);
|
||||
// line gets dropped here but references are kept in acc.map
|
||||
}
|
||||
}
|
14
src/test/ui/issue-52126-assign-op-invariance.stderr
Normal file
14
src/test/ui/issue-52126-assign-op-invariance.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0597]: `line` does not live long enough
|
||||
--> $DIR/issue-52126-assign-op-invariance.rs:44:28
|
||||
|
|
||||
LL | let v: Vec<&str> = line.split_whitespace().collect();
|
||||
| ^^^^ borrowed value does not live long enough
|
||||
...
|
||||
LL | }
|
||||
| - `line` dropped here while still borrowed
|
||||
LL | }
|
||||
| - borrowed value needs to live until here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0597`.
|
@ -11,7 +11,7 @@
|
||||
// Test that MIR borrowck and NLL analysis can handle constants of
|
||||
// arbitrary types without ICEs.
|
||||
|
||||
// compile-flags:-Zborrowck=mir -Zverbose
|
||||
// compile-flags:-Zborrowck=mir
|
||||
// compile-pass
|
||||
|
||||
const HI: &str = "hi";
|
||||
|
@ -15,7 +15,7 @@ use std::io::BufReader;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use common;
|
||||
use common::Config;
|
||||
use common::{Config, Mode};
|
||||
use util;
|
||||
|
||||
use extract_gdb_version;
|
||||
@ -396,6 +396,13 @@ impl TestProps {
|
||||
}
|
||||
});
|
||||
|
||||
if self.failure_status == -1 {
|
||||
self.failure_status = match config.mode {
|
||||
Mode::RunFail => 101,
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
|
||||
for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
|
||||
if let Ok(val) = env::var(key) {
|
||||
if self.exec_env.iter().find(|&&(ref x, _)| x == key).is_none() {
|
||||
|
Loading…
Reference in New Issue
Block a user