Skip to content

Commit 2df18ed

Browse files
committed
Auto merge of #42182 - nikomatsakis:beta, r=brson
Beta backports Backports of: - #41913 (or some of it) - #41937 - #41716 - #41563
2 parents 139d12f + 0566d02 commit 2df18ed

16 files changed

+452
-113
lines changed

src/bootstrap/native.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ pub fn openssl(build: &Build, target: &str) {
306306
println!("Configuring openssl for {}", target);
307307
build.run_quiet(&mut configure);
308308
println!("Building openssl for {}", target);
309-
build.run_quiet(Command::new("make").current_dir(&obj));
309+
build.run_quiet(Command::new("make").arg("-j1").current_dir(&obj));
310310
println!("Installing openssl for {}", target);
311311
build.run_quiet(Command::new("make").arg("install").current_dir(&obj));
312312

src/librustc/infer/combine.rs

+168-41
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@ use super::sub::Sub;
3939
use super::InferCtxt;
4040
use super::{MiscVariable, TypeTrace};
4141

42+
use hir::def_id::DefId;
4243
use ty::{IntType, UintType};
4344
use ty::{self, Ty, TyCtxt};
4445
use ty::error::TypeError;
45-
use ty::fold::TypeFoldable;
46-
use ty::relate::{RelateResult, TypeRelation};
47-
use traits::PredicateObligations;
46+
use ty::relate::{self, Relate, RelateResult, TypeRelation};
47+
use ty::subst::Substs;
48+
use traits::{Obligation, PredicateObligations};
4849

4950
use syntax::ast;
5051
use syntax_pos::Span;
@@ -207,11 +208,16 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
207208
// `'?2` and `?3` are fresh region/type inference
208209
// variables. (Down below, we will relate `a_ty <: b_ty`,
209210
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
210-
let b_ty = self.generalize(a_ty, b_vid, dir == EqTo)?;
211+
let Generalization { ty: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?;
211212
debug!("instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})",
212213
a_ty, dir, b_vid, b_ty);
213214
self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty);
214215

216+
if needs_wf {
217+
self.obligations.push(Obligation::new(self.trace.cause.clone(),
218+
ty::Predicate::WellFormed(b_ty)));
219+
}
220+
215221
// Finally, relate `b_ty` to `a_ty`, as described in previous comment.
216222
//
217223
// FIXME(#16847): This code is non-ideal because all these subtype
@@ -230,50 +236,148 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
230236

231237
/// Attempts to generalize `ty` for the type variable `for_vid`.
232238
/// This checks for cycle -- that is, whether the type `ty`
233-
/// references `for_vid`. If `is_eq_relation` is false, it will
234-
/// also replace all regions/unbound-type-variables with fresh
235-
/// variables. Returns `TyError` in the case of a cycle, `Ok`
236-
/// otherwise.
239+
/// references `for_vid`. The `dir` is the "direction" for which we
240+
/// a performing the generalization (i.e., are we producing a type
241+
/// that can be used as a supertype etc).
237242
///
238243
/// Preconditions:
239244
///
240245
/// - `for_vid` is a "root vid"
241246
fn generalize(&self,
242247
ty: Ty<'tcx>,
243248
for_vid: ty::TyVid,
244-
is_eq_relation: bool)
245-
-> RelateResult<'tcx, Ty<'tcx>>
249+
dir: RelationDir)
250+
-> RelateResult<'tcx, Generalization<'tcx>>
246251
{
252+
// Determine the ambient variance within which `ty` appears.
253+
// The surrounding equation is:
254+
//
255+
// ty [op] ty2
256+
//
257+
// where `op` is either `==`, `<:`, or `:>`. This maps quite
258+
// naturally.
259+
let ambient_variance = match dir {
260+
RelationDir::EqTo => ty::Invariant,
261+
RelationDir::SubtypeOf => ty::Covariant,
262+
RelationDir::SupertypeOf => ty::Contravariant,
263+
};
264+
247265
let mut generalize = Generalizer {
248266
infcx: self.infcx,
249267
span: self.trace.cause.span,
250268
for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
251-
is_eq_relation: is_eq_relation,
252-
cycle_detected: false
269+
ambient_variance: ambient_variance,
270+
needs_wf: false,
253271
};
254-
let u = ty.fold_with(&mut generalize);
255-
if generalize.cycle_detected {
256-
Err(TypeError::CyclicTy)
257-
} else {
258-
Ok(u)
259-
}
272+
273+
let ty = generalize.relate(&ty, &ty)?;
274+
let needs_wf = generalize.needs_wf;
275+
Ok(Generalization { ty, needs_wf })
260276
}
261277
}
262278

263279
struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
264280
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
265281
span: Span,
266282
for_vid_sub_root: ty::TyVid,
267-
is_eq_relation: bool,
268-
cycle_detected: bool,
283+
ambient_variance: ty::Variance,
284+
needs_wf: bool, // see the field `needs_wf` in `Generalization`
269285
}
270286

271-
impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
272-
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
287+
/// Result from a generalization operation. This includes
288+
/// not only the generalized type, but also a bool flag
289+
/// indicating whether further WF checks are needed.q
290+
struct Generalization<'tcx> {
291+
ty: Ty<'tcx>,
292+
293+
/// If true, then the generalized type may not be well-formed,
294+
/// even if the source type is well-formed, so we should add an
295+
/// additional check to enforce that it is. This arises in
296+
/// particular around 'bivariant' type parameters that are only
297+
/// constrained by a where-clause. As an example, imagine a type:
298+
///
299+
/// struct Foo<A, B> where A: Iterator<Item=B> {
300+
/// data: A
301+
/// }
302+
///
303+
/// here, `A` will be covariant, but `B` is
304+
/// unconstrained. However, whatever it is, for `Foo` to be WF, it
305+
/// must be equal to `A::Item`. If we have an input `Foo<?A, ?B>`,
306+
/// then after generalization we will wind up with a type like
307+
/// `Foo<?C, ?D>`. When we enforce that `Foo<?A, ?B> <: Foo<?C,
308+
/// ?D>` (or `>:`), we will wind up with the requirement that `?A
309+
/// <: ?C`, but no particular relationship between `?B` and `?D`
310+
/// (after all, we do not know the variance of the normalized form
311+
/// of `A::Item` with respect to `A`). If we do nothing else, this
312+
/// may mean that `?D` goes unconstrained (as in #41677). So, in
313+
/// this scenario where we create a new type variable in a
314+
/// bivariant context, we set the `needs_wf` flag to true. This
315+
/// will force the calling code to check that `WF(Foo<?C, ?D>)`
316+
/// holds, which in turn implies that `?C::Item == ?D`. So once
317+
/// `?C` is constrained, that should suffice to restrict `?D`.
318+
needs_wf: bool,
319+
}
320+
321+
impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
322+
fn tcx(&self) -> TyCtxt<'cx, 'gcx, 'tcx> {
273323
self.infcx.tcx
274324
}
275325

276-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
326+
fn tag(&self) -> &'static str {
327+
"Generalizer"
328+
}
329+
330+
fn a_is_expected(&self) -> bool {
331+
true
332+
}
333+
334+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
335+
-> RelateResult<'tcx, ty::Binder<T>>
336+
where T: Relate<'tcx>
337+
{
338+
Ok(ty::Binder(self.relate(a.skip_binder(), b.skip_binder())?))
339+
}
340+
341+
fn relate_item_substs(&mut self,
342+
item_def_id: DefId,
343+
a_subst: &'tcx Substs<'tcx>,
344+
b_subst: &'tcx Substs<'tcx>)
345+
-> RelateResult<'tcx, &'tcx Substs<'tcx>>
346+
{
347+
if self.ambient_variance == ty::Variance::Invariant {
348+
// Avoid fetching the variance if we are in an invariant
349+
// context; no need, and it can induce dependency cycles
350+
// (e.g. #41849).
351+
relate::relate_substs(self, None, a_subst, b_subst)
352+
} else {
353+
let variances;
354+
let opt_variances = if self.tcx().variance_computed.get() {
355+
variances = self.tcx().item_variances(item_def_id);
356+
Some(&*variances)
357+
} else {
358+
None
359+
};
360+
relate::relate_substs(self, opt_variances, a_subst, b_subst)
361+
}
362+
}
363+
364+
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
365+
variance: ty::Variance,
366+
a: &T,
367+
b: &T)
368+
-> RelateResult<'tcx, T>
369+
{
370+
let old_ambient_variance = self.ambient_variance;
371+
self.ambient_variance = self.ambient_variance.xform(variance);
372+
373+
let result = self.relate(a, b);
374+
self.ambient_variance = old_ambient_variance;
375+
result
376+
}
377+
378+
fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
379+
assert_eq!(t, t2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
380+
277381
// Check to see whether the type we are genealizing references
278382
// any other type variable related to `vid` via
279383
// subtyping. This is basically our "occurs check", preventing
@@ -286,41 +390,63 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
286390
if sub_vid == self.for_vid_sub_root {
287391
// If sub-roots are equal, then `for_vid` and
288392
// `vid` are related via subtyping.
289-
self.cycle_detected = true;
290-
self.tcx().types.err
393+
return Err(TypeError::CyclicTy);
291394
} else {
292395
match variables.probe_root(vid) {
293396
Some(u) => {
294397
drop(variables);
295-
self.fold_ty(u)
398+
self.relate(&u, &u)
296399
}
297400
None => {
298-
if !self.is_eq_relation {
299-
let origin = variables.origin(vid);
300-
let new_var_id = variables.new_var(false, origin, None);
301-
let u = self.tcx().mk_var(new_var_id);
302-
debug!("generalize: replacing original vid={:?} with new={:?}",
303-
vid, u);
304-
u
305-
} else {
306-
t
401+
match self.ambient_variance {
402+
// Invariant: no need to make a fresh type variable.
403+
ty::Invariant => return Ok(t),
404+
405+
// Bivariant: make a fresh var, but we
406+
// may need a WF predicate. See
407+
// comment on `needs_wf` field for
408+
// more info.
409+
ty::Bivariant => self.needs_wf = true,
410+
411+
// Co/contravariant: this will be
412+
// sufficiently constrained later on.
413+
ty::Covariant | ty::Contravariant => (),
307414
}
415+
416+
let origin = variables.origin(vid);
417+
let new_var_id = variables.new_var(false, origin, None);
418+
let u = self.tcx().mk_var(new_var_id);
419+
debug!("generalize: replacing original vid={:?} with new={:?}",
420+
vid, u);
421+
return Ok(u);
308422
}
309423
}
310424
}
311425
}
426+
ty::TyInfer(ty::IntVar(_)) |
427+
ty::TyInfer(ty::FloatVar(_)) => {
428+
// No matter what mode we are in,
429+
// integer/floating-point types must be equal to be
430+
// relatable.
431+
Ok(t)
432+
}
312433
_ => {
313-
t.super_fold_with(self)
434+
relate::super_relate_tys(self, t, t)
314435
}
315436
}
316437
}
317438

318-
fn fold_region(&mut self, r: &'tcx ty::Region) -> &'tcx ty::Region {
439+
fn regions(&mut self, r: &'tcx ty::Region, r2: &'tcx ty::Region)
440+
-> RelateResult<'tcx, &'tcx ty::Region> {
441+
assert_eq!(r, r2); // we are abusing TypeRelation here; both LHS and RHS ought to be ==
442+
319443
match *r {
320444
// Never make variables for regions bound within the type itself,
321445
// nor for erased regions.
322446
ty::ReLateBound(..) |
323-
ty::ReErased => { return r; }
447+
ty::ReErased => {
448+
return Ok(r);
449+
}
324450

325451
// Early-bound regions should really have been substituted away before
326452
// we get to this point.
@@ -342,15 +468,16 @@ impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx
342468
ty::ReScope(..) |
343469
ty::ReVar(..) |
344470
ty::ReFree(..) => {
345-
if self.is_eq_relation {
346-
return r;
471+
match self.ambient_variance {
472+
ty::Invariant => return Ok(r),
473+
ty::Bivariant | ty::Covariant | ty::Contravariant => (),
347474
}
348475
}
349476
}
350477

351478
// FIXME: This is non-ideal because we don't give a
352479
// very descriptive origin for this region variable.
353-
self.infcx.next_region_var(MiscVariable(self.span))
480+
Ok(self.infcx.next_region_var(MiscVariable(self.span)))
354481
}
355482
}
356483

src/librustc/infer/equate.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
use super::combine::{CombineFields, RelationDir};
1212
use super::{Subtype};
1313

14+
use hir::def_id::DefId;
15+
1416
use ty::{self, Ty, TyCtxt};
1517
use ty::TyVar;
16-
use ty::relate::{Relate, RelateResult, TypeRelation};
18+
use ty::subst::Substs;
19+
use ty::relate::{self, Relate, RelateResult, TypeRelation};
1720

1821
/// Ensures `a` is made equal to `b`. Returns `a` on success.
1922
pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
@@ -38,6 +41,22 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
3841

3942
fn a_is_expected(&self) -> bool { self.a_is_expected }
4043

44+
fn relate_item_substs(&mut self,
45+
_item_def_id: DefId,
46+
a_subst: &'tcx Substs<'tcx>,
47+
b_subst: &'tcx Substs<'tcx>)
48+
-> RelateResult<'tcx, &'tcx Substs<'tcx>>
49+
{
50+
// NB: Once we are equating types, we don't care about
51+
// variance, so don't try to lookup the variance here. This
52+
// also avoids some cycles (e.g. #41849) since looking up
53+
// variance requires computing types which can require
54+
// performing trait matching (which then performs equality
55+
// unification).
56+
57+
relate::relate_substs(self, None, a_subst, b_subst)
58+
}
59+
4160
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
4261
_: ty::Variance,
4362
a: &T,

0 commit comments

Comments
 (0)