Skip to content

Commit 514dfdb

Browse files
committed
Add tests for sub relationship on free/bound regions, revealing a bug.
1 parent 6bdce25 commit 514dfdb

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/librustc_driver/test.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_typeck::middle::infer::combine::Combine;
2525
use rustc_typeck::middle::infer;
2626
use rustc_typeck::middle::infer::lub::Lub;
2727
use rustc_typeck::middle::infer::glb::Glb;
28+
use rustc_typeck::middle::infer::sub::Sub;
2829
use rustc_typeck::util::ppaux::{ty_to_string, Repr, UserString};
2930
use rustc::session::{mod,config};
3031
use syntax::{abi, ast, ast_map, ast_util};
@@ -341,6 +342,11 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
341342
infer::TypeTrace::dummy()
342343
}
343344

345+
pub fn sub(&self) -> Sub<'a, 'tcx> {
346+
let trace = self.dummy_type_trace();
347+
Sub(self.infcx.combine_fields(true, trace))
348+
}
349+
344350
pub fn lub(&self) -> Lub<'a, 'tcx> {
345351
let trace = self.dummy_type_trace();
346352
Lub(self.infcx.combine_fields(true, trace))
@@ -359,6 +365,33 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
359365
}
360366
}
361367

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

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

0 commit comments

Comments
 (0)