Skip to content

Commit

Permalink
Auto merge of #77490 - Mark-Simulacrum:beta-backports, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
[beta] backports

This backports a number of PRs to beta, not all of which have been approved (yet).

 * Switch to environment files to change the environment on GHA #77418
 * cache types during normalization #76928
 * Fixing memory exhaustion when formatting short code suggestion #76598
 * Issue 72408 nested closures exponential #72412

r? `@Mark-Simulacrum`
  • Loading branch information
bors committed Oct 3, 2020
2 parents 6d3dc31 + bf38fa5 commit d6646f6
Show file tree
Hide file tree
Showing 33 changed files with 410 additions and 94 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3424,6 +3424,7 @@ dependencies = [
name = "rustc_data_structures"
version = "0.0.0"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if",
"crossbeam-utils 0.7.2",
Expand Down Expand Up @@ -3599,6 +3600,7 @@ dependencies = [
name = "rustc_infer"
version = "0.0.0"
dependencies = [
"arrayvec",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -3738,6 +3740,7 @@ dependencies = [
name = "rustc_middle"
version = "0.0.0"
dependencies = [
"arrayvec",
"bitflags",
"byteorder",
"chalk-ir",
Expand Down
4 changes: 2 additions & 2 deletions src/ci/shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function ciCommandAddPath {
if isAzurePipelines; then
echo "##vso[task.prependpath]${path}"
elif isGitHubActions; then
echo "::add-path::${path}"
echo "${path}" >> "${GITHUB_PATH}"
else
echo "ciCommandAddPath only works inside CI!"
exit 1
Expand All @@ -122,7 +122,7 @@ function ciCommandSetEnv {
if isAzurePipelines; then
echo "##vso[task.setvariable variable=${name}]${value}"
elif isGitHubActions; then
echo "::set-env name=${name}::${value}"
echo "${name}=${value}" >> "${GITHUB_ENV}"
else
echo "ciCommandSetEnv only works inside CI!"
exit 1
Expand Down
1 change: 1 addition & 0 deletions src/librustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ path = "lib.rs"
doctest = false

[dependencies]
arrayvec = { version = "0.5.1", default-features = false }
ena = "0.14"
indexmap = "1.5.1"
tracing = "0.1"
Expand Down
12 changes: 7 additions & 5 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,26 @@ pub mod sorted_map;
pub mod stable_set;
#[macro_use]
pub mod stable_hasher;
mod atomic_ref;
pub mod fingerprint;
pub mod profiling;
pub mod sharded;
pub mod stack;
pub mod sync;
pub mod thin_vec;
pub mod tiny_list;
pub mod transitive_relation;
pub use ena::undo_log;
pub use ena::unify;
mod atomic_ref;
pub mod fingerprint;
pub mod profiling;
pub mod vec_linked_list;
pub mod work_queue;
pub use atomic_ref::AtomicRef;
pub mod frozen;
pub mod mini_map;
pub mod tagged_ptr;
pub mod temp_dir;

pub use ena::undo_log;
pub use ena::unify;

pub struct OnDrop<F: Fn()>(pub F);

impl<F: Fn()> OnDrop<F> {
Expand Down
61 changes: 61 additions & 0 deletions src/librustc_data_structures/mini_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use crate::fx::FxHashMap;
use arrayvec::ArrayVec;

use std::hash::Hash;

/// Small-storage-optimized implementation of a map
/// made specifically for caching results.
///
/// Stores elements in a small array up to a certain length
/// and switches to `HashMap` when that length is exceeded.
pub enum MiniMap<K, V> {
Array(ArrayVec<[(K, V); 8]>),
Map(FxHashMap<K, V>),
}

impl<K: Eq + Hash, V> MiniMap<K, V> {
/// Creates an empty `MiniMap`.
pub fn new() -> Self {
MiniMap::Array(ArrayVec::new())
}

/// Inserts or updates value in the map.
pub fn insert(&mut self, key: K, value: V) {
match self {
MiniMap::Array(array) => {
for pair in array.iter_mut() {
if pair.0 == key {
pair.1 = value;
return;
}
}
if let Err(error) = array.try_push((key, value)) {
let mut map: FxHashMap<K, V> = array.drain(..).collect();
let (key, value) = error.element();
map.insert(key, value);
*self = MiniMap::Map(map);
}
}
MiniMap::Map(map) => {
map.insert(key, value);
}
}
}

/// Return value by key if any.
pub fn get(&self, key: &K) -> Option<&V> {
match self {
MiniMap::Array(array) => {
for pair in array {
if pair.0 == *key {
return Some(&pair.1);
}
}
return None;
}
MiniMap::Map(map) => {
return map.get(key);
}
}
}
}
6 changes: 3 additions & 3 deletions src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,15 +959,15 @@ impl EmitterWriter {
'_',
line_offset + pos,
width_offset + depth,
code_offset + annotation.start_col - left,
(code_offset + annotation.start_col).saturating_sub(left),
style,
);
}
_ if self.teach => {
buffer.set_style_range(
line_offset,
code_offset + annotation.start_col - left,
code_offset + annotation.end_col - left,
(code_offset + annotation.start_col).saturating_sub(left),
(code_offset + annotation.end_col).saturating_sub(left),
style,
annotation.is_primary,
);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_index/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ path = "lib.rs"
doctest = false

[dependencies]
arrayvec = "0.5.1"
arrayvec = { version = "0.5.1", default-features = false }
rustc_serialize = { path = "../librustc_serialize" }
rustc_macros = { path = "../librustc_macros" }
1 change: 1 addition & 0 deletions src/librustc_infer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ rustc_serialize = { path = "../librustc_serialize" }
rustc_span = { path = "../librustc_span" }
rustc_target = { path = "../librustc_target" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
arrayvec = { version = "0.5.1", default-features = false }
rustc_ast = { path = "../librustc_ast" }
14 changes: 12 additions & 2 deletions src/librustc_infer/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use super::{InferCtxt, MiscVariable, TypeTrace};
use crate::traits::{Obligation, PredicateObligations};

use rustc_ast as ast;
use rustc_data_structures::mini_map::MiniMap;
use rustc_hir::def_id::DefId;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
Expand Down Expand Up @@ -379,6 +380,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
needs_wf: false,
root_ty: ty,
param_env: self.param_env,
cache: MiniMap::new(),
};

let ty = match generalize.relate(ty, ty) {
Expand Down Expand Up @@ -438,6 +440,8 @@ struct Generalizer<'cx, 'tcx> {
root_ty: Ty<'tcx>,

param_env: ty::ParamEnv<'tcx>,

cache: MiniMap<Ty<'tcx>, RelateResult<'tcx, Ty<'tcx>>>,
}

/// Result from a generalization operation. This includes
Expand Down Expand Up @@ -535,13 +539,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==

if let Some(result) = self.cache.get(&t) {
return result.clone();
}
debug!("generalize: t={:?}", t);

// Check to see whether the type we are generalizing references
// any other type variable related to `vid` via
// subtyping. This is basically our "occurs check", preventing
// us from creating infinitely sized types.
match t.kind {
let result = match t.kind {
ty::Infer(ty::TyVar(vid)) => {
let vid = self.infcx.inner.borrow_mut().type_variables().root_var(vid);
let sub_vid = self.infcx.inner.borrow_mut().type_variables().sub_root_var(vid);
Expand Down Expand Up @@ -598,7 +605,10 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
Ok(t)
}
_ => relate::super_relate_tys(self, t, t),
}
};

self.cache.insert(t, result.clone());
return result;
}

fn regions(
Expand Down
40 changes: 28 additions & 12 deletions src/librustc_infer/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::infer::{GenericKind, VerifyBound};
use rustc_data_structures::captures::Captures;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
use rustc_middle::ty::walk::MiniSet;
use rustc_middle::ty::{self, Ty, TyCtxt};

/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
Expand Down Expand Up @@ -31,16 +32,23 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
/// Returns a "verify bound" that encodes what we know about
/// `generic` and the regions it outlives.
pub fn generic_bound(&self, generic: GenericKind<'tcx>) -> VerifyBound<'tcx> {
let mut visited = MiniSet::new();
match generic {
GenericKind::Param(param_ty) => self.param_bound(param_ty),
GenericKind::Projection(projection_ty) => self.projection_bound(projection_ty),
GenericKind::Projection(projection_ty) => {
self.projection_bound(projection_ty, &mut visited)
}
}
}

fn type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
fn type_bound(
&self,
ty: Ty<'tcx>,
visited: &mut MiniSet<GenericArg<'tcx>>,
) -> VerifyBound<'tcx> {
match ty.kind {
ty::Param(p) => self.param_bound(p),
ty::Projection(data) => self.projection_bound(data),
ty::Projection(data) => self.projection_bound(data, visited),
ty::FnDef(_, substs) => {
// HACK(eddyb) ignore lifetimes found shallowly in `substs`.
// This is inconsistent with `ty::Adt` (including all substs),
Expand All @@ -50,9 +58,9 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
let mut bounds = substs
.iter()
.filter_map(|child| match child.unpack() {
GenericArgKind::Type(ty) => Some(self.type_bound(ty)),
GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)),
GenericArgKind::Lifetime(_) => None,
GenericArgKind::Const(_) => Some(self.recursive_bound(child)),
GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)),
})
.filter(|bound| {
// Remove bounds that must hold, since they are not interesting.
Expand All @@ -66,7 +74,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
),
}
}
_ => self.recursive_bound(ty.into()),
_ => self.recursive_bound(ty.into(), visited),
}
}

Expand Down Expand Up @@ -137,7 +145,11 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
self.declared_projection_bounds_from_trait(projection_ty)
}

pub fn projection_bound(&self, projection_ty: ty::ProjectionTy<'tcx>) -> VerifyBound<'tcx> {
pub fn projection_bound(
&self,
projection_ty: ty::ProjectionTy<'tcx>,
visited: &mut MiniSet<GenericArg<'tcx>>,
) -> VerifyBound<'tcx> {
debug!("projection_bound(projection_ty={:?})", projection_ty);

let projection_ty_as_ty =
Expand Down Expand Up @@ -166,21 +178,25 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {

// see the extensive comment in projection_must_outlive
let ty = self.tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs);
let recursive_bound = self.recursive_bound(ty.into());
let recursive_bound = self.recursive_bound(ty.into(), visited);

VerifyBound::AnyBound(env_bounds.chain(trait_bounds).collect()).or(recursive_bound)
}

fn recursive_bound(&self, parent: GenericArg<'tcx>) -> VerifyBound<'tcx> {
fn recursive_bound(
&self,
parent: GenericArg<'tcx>,
visited: &mut MiniSet<GenericArg<'tcx>>,
) -> VerifyBound<'tcx> {
let mut bounds = parent
.walk_shallow()
.walk_shallow(visited)
.filter_map(|child| match child.unpack() {
GenericArgKind::Type(ty) => Some(self.type_bound(ty)),
GenericArgKind::Type(ty) => Some(self.type_bound(ty, visited)),
GenericArgKind::Lifetime(lt) => {
// Ignore late-bound regions.
if !lt.is_late_bound() { Some(VerifyBound::OutlivedBy(lt)) } else { None }
}
GenericArgKind::Const(_) => Some(self.recursive_bound(child)),
GenericArgKind::Const(_) => Some(self.recursive_bound(child, visited)),
})
.filter(|bound| {
// Remove bounds that must hold, since they are not interesting.
Expand Down
1 change: 1 addition & 0 deletions src/librustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ rustc_span = { path = "../librustc_span" }
byteorder = { version = "1.3" }
chalk-ir = "0.14.0"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
arrayvec = { version = "0.5.1", default-features = false }
measureme = "0.7.1"
rustc_session = { path = "../librustc_session" }
Loading

0 comments on commit d6646f6

Please sign in to comment.