Skip to content

Commit 9e93224

Browse files
committed
Add tests for sub relationship on free/bound regions, revealing a bug.
1 parent 09f04bf commit 9e93224

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/librustc_trans/test.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use middle::subst::Subst;
2323
use middle::ty::{mod, Ty};
2424
use middle::typeck::infer::combine::Combine;
2525
use middle::typeck::infer;
26+
use middle::typeck::infer::sub::Sub;
2627
use middle::typeck::infer::lub::Lub;
2728
use middle::typeck::infer::glb::Glb;
2829
use session::{mod,config};
@@ -339,6 +340,11 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
339340
infer::TypeTrace::dummy()
340341
}
341342

343+
pub fn sub(&self) -> Sub<'a, 'tcx> {
344+
let trace = self.dummy_type_trace();
345+
Sub(self.infcx.combine_fields(true, trace))
346+
}
347+
342348
pub fn lub(&self) -> Lub<'a, 'tcx> {
343349
let trace = self.dummy_type_trace();
344350
Lub(self.infcx.combine_fields(true, trace))
@@ -357,6 +363,33 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
357363
}
358364
}
359365

366+
/// Checks that `t1 <: t2` is true (this may register additional
367+
/// region checks).
368+
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
369+
match self.sub().tys(t1, t2) {
370+
Ok(_) => { }
371+
Err(ref e) => {
372+
panic!("unexpected error computing sub({},{}): {}",
373+
t1.repr(self.infcx.tcx),
374+
t2.repr(self.infcx.tcx),
375+
ty::type_err_to_str(self.infcx.tcx, e));
376+
}
377+
}
378+
}
379+
380+
/// Checks that `t1 <: t2` is false (this may register additional
381+
/// region checks).
382+
pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
383+
match self.sub().tys(t1, t2) {
384+
Err(_) => { }
385+
Ok(_) => {
386+
panic!("unexpected success computing sub({},{})",
387+
t1.repr(self.infcx.tcx),
388+
t2.repr(self.infcx.tcx));
389+
}
390+
}
391+
}
392+
360393
/// Checks that `LUB(t1,t2) == t_lub`
361394
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
362395
match self.lub().tys(t1, t2) {
@@ -419,6 +452,54 @@ fn contravariant_region_ptr_err() {
419452
})
420453
}
421454

455+
#[test]
456+
fn sub_free_bound_false() {
457+
//! Test that:
458+
//!
459+
//! fn(&'a int) <: for<'b> fn(&'b int)
460+
//!
461+
//! does NOT hold.
462+
463+
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
464+
let t_rptr_free1 = env.t_rptr_free(0, 1);
465+
let t_rptr_bound1 = env.t_rptr_late_bound(1);
466+
env.check_not_sub(env.t_fn(&[t_rptr_free1], ty::mk_int()),
467+
env.t_fn(&[t_rptr_bound1], ty::mk_int()));
468+
})
469+
}
470+
471+
#[test]
472+
fn sub_bound_free_true() {
473+
//! Test that:
474+
//!
475+
//! for<'a> fn(&'a int) <: fn(&'b int)
476+
//!
477+
//! DOES hold.
478+
479+
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
480+
let t_rptr_bound1 = env.t_rptr_late_bound(1);
481+
let t_rptr_free1 = env.t_rptr_free(0, 1);
482+
env.check_sub(env.t_fn(&[t_rptr_bound1], ty::mk_int()),
483+
env.t_fn(&[t_rptr_free1], ty::mk_int()));
484+
})
485+
}
486+
487+
#[test]
488+
fn sub_free_bound_false_infer() {
489+
//! Test that:
490+
//!
491+
//! fn(_#1) <: for<'b> fn(&'b int)
492+
//!
493+
//! does NOT hold for any instantiation of `_#1`.
494+
495+
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
496+
let t_infer1 = env.infcx.next_ty_var();
497+
let t_rptr_bound1 = env.t_rptr_late_bound(1);
498+
env.check_not_sub(env.t_fn(&[t_infer1], ty::mk_int()),
499+
env.t_fn(&[t_rptr_bound1], ty::mk_int()));
500+
})
501+
}
502+
422503
#[test]
423504
fn lub_bound_bound() {
424505
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {

0 commit comments

Comments
 (0)