Auto merge of #63498 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum
1.37.0 stable
This promotes beta to stable and backports a few PRs:
- Avoid ICE when referencing desugared local binding in borrow error (#63051)
- Don't access a static just for its size and alignment (#62982) via 331e09b143aebfcf82dc1f9b69b31ee0083cbf0b
diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
index 18385f0..ab99057 100644
--- a/src/ci/azure-pipelines/steps/run.yml
+++ b/src/ci/azure-pipelines/steps/run.yml
@@ -30,6 +30,10 @@
- bash: printenv | sort
displayName: Show environment variables
+# Log the date, even on failure. Attempting to debug SSL certificate errors.
+- bash: date
+ displayName: Print out date (before build)
+
- bash: |
set -e
df -h
@@ -198,3 +202,8 @@
condition: variables['AWS_SECRET_ACCESS_KEY']
continueOnError: true
displayName: Upload CPU usage statistics
+
+# Log the date, even on failure. Attempting to debug SSL certificate errors.
+- bash: date
+ continueOnError: true
+ displayName: Print out date (after build)
diff --git a/src/ci/run.sh b/src/ci/run.sh
index e5e0e6c..f19bd4e 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -45,7 +45,7 @@
#
# 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" = "1" ]; then
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp"
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index f23cffe..b9cd1f0 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -1116,19 +1116,18 @@
bug!("try_report_cannot_return_reference_to_local: not a local")
};
match self.body.local_kind(local) {
- LocalKind::ReturnPointer | LocalKind::Temp => {
- (
- "temporary value".to_string(),
- "temporary value created here".to_string(),
- )
- }
- LocalKind::Arg => {
- (
- "function parameter".to_string(),
- "function parameter borrowed here".to_string(),
- )
- },
- LocalKind::Var => bug!("local variable without a name"),
+ LocalKind::ReturnPointer | LocalKind::Temp => (
+ "temporary value".to_string(),
+ "temporary value created here".to_string(),
+ ),
+ LocalKind::Arg => (
+ "function parameter".to_string(),
+ "function parameter borrowed here".to_string(),
+ ),
+ LocalKind::Var => (
+ "local binding".to_string(),
+ "local binding introduced here".to_string(),
+ ),
}
};
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index 4eb95f2..9126393 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -54,6 +54,11 @@
k: K,
vacant: impl FnOnce() -> Result<V, E>
) -> Result<&mut V, E>;
+
+ /// Read-only lookup.
+ fn get(&self, k: K) -> Option<&V> {
+ self.get_or(k, || Err(())).ok()
+ }
}
/// Methods of this trait signifies a point where CTFE evaluation would fail
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index c3eec67..56a0e14 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -492,13 +492,18 @@
id: AllocId,
liveness: AllocCheck,
) -> InterpResult<'static, (Size, Align)> {
- if let Ok(alloc) = self.get(id) {
+ // # Regular allocations
+ // Don't use `self.get` here as that will
+ // a) cause cycles in case `id` refers to a static
+ // b) duplicate a static's allocation in miri
+ if let Some((_, alloc)) = self.alloc_map.get(id) {
return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
}
- // can't do this in the match argument, we may get cycle errors since the lock would get
- // dropped after the match.
+
+ // # Statics and function pointers
+ // Can't do this in the match argument, we may get cycle errors since the lock would
+ // be held throughout the match.
let alloc = self.tcx.alloc_map.lock().get(id);
- // Could also be a fn ptr or extern static
match alloc {
Some(GlobalAlloc::Function(..)) => {
if let AllocCheck::Dereferencable = liveness {
@@ -507,28 +512,26 @@
} else {
Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
}
- }
- // `self.get` would also work, but can cause cycles if a static refers to itself
+ },
Some(GlobalAlloc::Static(did)) => {
- // The only way `get` couldn't have worked here is if this is an extern static
- assert!(self.tcx.is_foreign_item(did));
- // Use size and align of the type
+ // Use size and align of the type.
let ty = self.tcx.type_of(did);
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
Ok((layout.size, layout.align.abi))
- }
- _ => {
- if let Ok(alloc) = self.get(id) {
- Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align))
- }
- else if let AllocCheck::MaybeDead = liveness {
- // Deallocated pointers are allowed, we should be able to find
- // them in the map.
- Ok(*self.dead_alloc_map.get(&id)
- .expect("deallocated pointers should all be recorded in `dead_alloc_map`"))
- } else {
- err!(DanglingPointerDeref)
- }
+ },
+ Some(GlobalAlloc::Memory(alloc)) =>
+ // Need to duplicate the logic here, because the global allocations have
+ // different associated types than the interpreter-local ones.
+ Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
+ // The rest must be dead.
+ None => if let AllocCheck::MaybeDead = liveness {
+ // Deallocated pointers are allowed, we should be able to find
+ // them in the map.
+ Ok(*self.dead_alloc_map.get(&id)
+ .expect("deallocated pointers should all be recorded in \
+ `dead_alloc_map`"))
+ } else {
+ err!(DanglingPointerDeref)
},
}
}
diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.rs b/src/test/ui/borrowck/return-local-binding-from-desugaring.rs
new file mode 100644
index 0000000..b2dcd54
--- /dev/null
+++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.rs
@@ -0,0 +1,33 @@
+// To avoid leaking the names of local bindings from expressions like for loops, #60984
+// explicitly ignored them, but an assertion that `LocalKind::Var` *must* have a name would
+// trigger an ICE. Before this change, this file's output would be:
+// ```
+// error[E0515]: cannot return value referencing local variable `__next`
+// --> return-local-binding-from-desugaring.rs:LL:CC
+// |
+// LL | for ref x in xs {
+// | ----- `__next` is borrowed here
+// ...
+// LL | result
+// | ^^^^^^ returns a value referencing data owned by the current function
+// ```
+// FIXME: ideally `LocalKind` would carry more information to more accurately explain the problem.
+
+use std::collections::HashMap;
+use std::hash::Hash;
+
+fn group_by<I, F, T>(xs: &mut I, f: F) -> HashMap<T, Vec<&I::Item>>
+where
+ I: Iterator,
+ F: Fn(&I::Item) -> T,
+ T: Eq + Hash,
+{
+ let mut result = HashMap::new();
+ for ref x in xs {
+ let key = f(x);
+ result.entry(key).or_insert(Vec::new()).push(x);
+ }
+ result //~ ERROR cannot return value referencing local binding
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr b/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr
new file mode 100644
index 0000000..293dbe6
--- /dev/null
+++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr
@@ -0,0 +1,12 @@
+error[E0515]: cannot return value referencing local binding
+ --> $DIR/return-local-binding-from-desugaring.rs:30:5
+ |
+LL | for ref x in xs {
+ | -- local binding introduced here
+...
+LL | result
+ | ^^^^^^ returns a value referencing data owned by the current function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/consts/static-cycle-error.rs b/src/test/ui/consts/static-cycle-error.rs
new file mode 100644
index 0000000..8e69d3e
--- /dev/null
+++ b/src/test/ui/consts/static-cycle-error.rs
@@ -0,0 +1,11 @@
+// compile-pass
+
+struct Foo {
+ foo: Option<&'static Foo>
+}
+
+static FOO: Foo = Foo {
+ foo: Some(&FOO),
+};
+
+fn main() {}