add back variance testing mechanism

make it work for traits etc uniformly
This commit is contained in:
Niko Matsakis 2017-04-25 05:45:59 -04:00
parent 4355169f8a
commit 898f978c97
7 changed files with 51 additions and 19 deletions

View File

@ -318,6 +318,11 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
coherence::check_coherence(tcx));
})?;
tcx.sess.track_errors(|| {
time(time_passes, "variance testing", ||
variance::test::test_variance(tcx));
})?;
time(time_passes, "wf checking", || check::check_wf_new(tcx))?;
time(time_passes, "item-types checking", || check::check_item_types(tcx))?;

View File

@ -29,6 +29,9 @@ mod constraints;
/// Code to solve constraints and write out the results.
mod solve;
/// Code to write unit tests of variance.
pub mod test;
/// Code for transforming variances.
mod xform;
@ -89,3 +92,4 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
}
}
}

View File

@ -128,16 +128,6 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
let item_def_id = tcx.hir.local_def_id(item_id);
// For unit testing: check for a special "rustc_variance"
// attribute and report an error with various results if found.
if tcx.has_attr(item_def_id, "rustc_variance") {
span_err!(tcx.sess,
tcx.hir.span(item_id),
E0208,
"{:?}",
item_variances);
}
map.insert(item_def_id, Rc::new(item_variances));
}

View File

@ -0,0 +1,41 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::TyCtxt;
pub fn test_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.hir.krate().visit_all_item_likes(&mut VarianceTest { tcx });
}
struct VarianceTest<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>
}
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for VarianceTest<'a, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) {
let item_def_id = self.tcx.hir.local_def_id(item.id);
// For unit testing: check for a special "rustc_variance"
// attribute and report an error with various results if found.
if self.tcx.has_attr(item_def_id, "rustc_variance") {
let item_variances = self.tcx.variances_of(item_def_id);
span_err!(self.tcx.sess,
item.span,
E0208,
"{:?}",
item_variances);
}
}
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) { }
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
}

View File

@ -60,7 +60,6 @@ struct Test6<'a, 'b:'a> { //~ ERROR [-, o]
#[rustc_variance]
struct Test7<'a> { //~ ERROR [*]
//~^ ERROR parameter `'a` is never used
x: isize
}

View File

@ -16,7 +16,6 @@
#[rustc_variance]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [+, -, o, *]
//~^ ERROR parameter `'d` is never used
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
Test8C(&'b mut &'c str),
@ -24,19 +23,16 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [+, -, o, *]
#[rustc_variance]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, -, +]
//~^ ERROR parameter `'w` is never used
f: Base<'z, 'y, 'x, 'w>
}
#[rustc_variance] // Combine - and + to yield o
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *]
//~^ ERROR parameter `'c` is never used
f: Base<'a, 'a, 'b, 'c>
}
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, -, *]
//~^ ERROR parameter `'c` is never used
f: Base<'a, 'b, 'a, 'c>
}

View File

@ -30,8 +30,7 @@ struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +]
}
#[rustc_variance]
enum TestEnum<U,T:Setter<U>> {//~ ERROR [*, +]
//~^ ERROR parameter `U` is never used
enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +]
Foo(T)
}
@ -51,13 +50,11 @@ trait TestTrait3<U> { //~ ERROR [o, o]
#[rustc_variance]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +]
//~^ ERROR parameter `U` is never used
t: T
}
#[rustc_variance]
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +]
//~^ ERROR parameter `U` is never used
t: T
}