about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2016-01-25 15:17:31 +0200
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2016-01-25 15:17:31 +0200
commite0fd9c3b00a4d2818a1add4840263d936f8748cd (patch)
treed3c694c5a3a451a6983d0e332c8b48bb7bebb79d
parent0486e12ad0661adcfdbd926dea17d7edfda419c1 (diff)
downloadrust-e0fd9c3b00a4d2818a1add4840263d936f8748cd.tar.gz
rust-e0fd9c3b00a4d2818a1add4840263d936f8748cd.zip
remove implicator
it is pre-RFC1214 junk
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/implicator.rs454
-rw-r--r--src/librustc_typeck/check/regionck.rs49
3 files changed, 1 insertions, 503 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 4d772de7835..4f6c1305f76 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -108,7 +108,6 @@ pub mod middle {
     pub mod free_region;
     pub mod intrinsicck;
     pub mod infer;
-    pub mod implicator;
     pub mod lang_items;
     pub mod liveness;
     pub mod mem_categorization;
diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs
deleted file mode 100644
index d25084bbdff..00000000000
--- a/src/librustc/middle/implicator.rs
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2012 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.
-
-// #![warn(deprecated_mode)]
-
-use middle::def_id::DefId;
-use middle::infer::{InferCtxt, GenericKind};
-use middle::subst::Substs;
-use middle::traits;
-use middle::ty::{self, ToPredicate, Ty};
-use middle::ty::fold::{TypeFoldable, TypeFolder};
-
-use syntax::ast;
-use syntax::codemap::Span;
-
-use util::common::ErrorReported;
-use util::nodemap::FnvHashSet;
-
-// Helper functions related to manipulating region types.
-
-#[derive(Debug)]
-pub enum Implication<'tcx> {
-    RegionSubRegion(Option<Ty<'tcx>>, ty::Region, ty::Region),
-    RegionSubGeneric(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
-    Predicate(DefId, ty::Predicate<'tcx>),
-}
-
-struct Implicator<'a, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a,'tcx>,
-    body_id: ast::NodeId,
-    stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
-    span: Span,
-    out: Vec<Implication<'tcx>>,
-    visited: FnvHashSet<Ty<'tcx>>,
-}
-
-/// This routine computes the well-formedness constraints that must hold for the type `ty` to
-/// appear in a context with lifetime `outer_region`
-pub fn implications<'a,'tcx>(
-    infcx: &'a InferCtxt<'a,'tcx>,
-    body_id: ast::NodeId,
-    ty: Ty<'tcx>,
-    outer_region: ty::Region,
-    span: Span)
-    -> Vec<Implication<'tcx>>
-{
-    debug!("implications(body_id={}, ty={:?}, outer_region={:?})",
-           body_id,
-           ty,
-           outer_region);
-
-    let mut stack = Vec::new();
-    stack.push((outer_region, None));
-    let mut wf = Implicator { infcx: infcx,
-                              body_id: body_id,
-                              span: span,
-                              stack: stack,
-                              out: Vec::new(),
-                              visited: FnvHashSet() };
-    wf.accumulate_from_ty(ty);
-    debug!("implications: out={:?}", wf.out);
-    wf.out
-}
-
-impl<'a, 'tcx> Implicator<'a, 'tcx> {
-    fn tcx(&self) -> &'a ty::ctxt<'tcx> {
-        self.infcx.tcx
-    }
-
-    fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
-        debug!("accumulate_from_ty(ty={:?})",
-               ty);
-
-        // When expanding out associated types, we can visit a cyclic
-        // set of types. Issue #23003.
-        if !self.visited.insert(ty) {
-            return;
-        }
-
-        match ty.sty {
-            ty::TyBool |
-            ty::TyChar |
-            ty::TyInt(..) |
-            ty::TyUint(..) |
-            ty::TyFloat(..) |
-            ty::TyBareFn(..) |
-            ty::TyError |
-            ty::TyStr => {
-                // No borrowed content reachable here.
-            }
-
-            ty::TyClosure(_, ref substs) => {
-                // FIXME(#27086). We do not accumulate from substs, since they
-                // don't represent reachable data. This means that, in
-                // practice, some of the lifetime parameters might not
-                // be in scope when the body runs, so long as there is
-                // no reachable data with that lifetime. For better or
-                // worse, this is consistent with fn types, however,
-                // which can also encapsulate data in this fashion
-                // (though it's somewhat harder, and typically
-                // requires virtual dispatch).
-                //
-                // Note that changing this (in a naive way, at least)
-                // causes regressions for what appears to be perfectly
-                // reasonable code like this:
-                //
-                // ```
-                // fn foo<'a>(p: &Data<'a>) {
-                //    bar(|q: &mut Parser| q.read_addr())
-                // }
-                // fn bar(p: Box<FnMut(&mut Parser)+'static>) {
-                // }
-                // ```
-                //
-                // Note that `p` (and `'a`) are not used in the
-                // closure at all, but to meet the requirement that
-                // the closure type `C: 'static` (so it can be coerced
-                // to the object type), we get the requirement that
-                // `'a: 'static` since `'a` appears in the closure
-                // type `C`.
-                //
-                // A smarter fix might "prune" unused `func_substs` --
-                // this would avoid breaking simple examples like
-                // this, but would still break others (which might
-                // indeed be invalid, depending on your POV). Pruning
-                // would be a subtle process, since we have to see
-                // what func/type parameters are used and unused,
-                // taking into consideration UFCS and so forth.
-
-                for &upvar_ty in &substs.upvar_tys {
-                    self.accumulate_from_ty(upvar_ty);
-                }
-            }
-
-            ty::TyTrait(ref t) => {
-                let required_region_bounds =
-                    object_region_bounds(self.tcx(), &t.principal, t.bounds.builtin_bounds);
-                self.accumulate_from_object_ty(ty, t.bounds.region_bound, required_region_bounds)
-            }
-
-            ty::TyEnum(def, substs) |
-            ty::TyStruct(def, substs) => {
-                let item_scheme = def.type_scheme(self.tcx());
-                self.accumulate_from_adt(ty, def.did, &item_scheme.generics, substs)
-            }
-
-            ty::TyArray(t, _) |
-            ty::TySlice(t) |
-            ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) |
-            ty::TyBox(t) => {
-                self.accumulate_from_ty(t)
-            }
-
-            ty::TyRef(r_b, mt) => {
-                self.accumulate_from_rptr(ty, *r_b, mt.ty);
-            }
-
-            ty::TyParam(p) => {
-                self.push_param_constraint_from_top(p);
-            }
-
-            ty::TyProjection(ref data) => {
-                // `<T as TraitRef<..>>::Name`
-
-                self.push_projection_constraint_from_top(data);
-            }
-
-            ty::TyTuple(ref tuptys) => {
-                for &tupty in tuptys {
-                    self.accumulate_from_ty(tupty);
-                }
-            }
-
-            ty::TyInfer(_) => {
-                // This should not happen, BUT:
-                //
-                //   Currently we uncover region relationships on
-                //   entering the fn check. We should do this after
-                //   the fn check, then we can call this case a bug().
-            }
-        }
-    }
-
-    fn accumulate_from_rptr(&mut self,
-                            ty: Ty<'tcx>,
-                            r_b: ty::Region,
-                            ty_b: Ty<'tcx>) {
-        // We are walking down a type like this, and current
-        // position is indicated by caret:
-        //
-        //     &'a &'b ty_b
-        //         ^
-        //
-        // At this point, top of stack will be `'a`. We must
-        // require that `'a <= 'b`.
-
-        self.push_region_constraint_from_top(r_b);
-
-        // Now we push `'b` onto the stack, because it must
-        // constrain any borrowed content we find within `T`.
-
-        self.stack.push((r_b, Some(ty)));
-        self.accumulate_from_ty(ty_b);
-        self.stack.pop().unwrap();
-    }
-
-    /// Pushes a constraint that `r_b` must outlive the top region on the stack.
-    fn push_region_constraint_from_top(&mut self,
-                                       r_b: ty::Region) {
-
-        // Indicates that we have found borrowed content with a lifetime
-        // of at least `r_b`. This adds a constraint that `r_b` must
-        // outlive the region `r_a` on top of the stack.
-        //
-        // As an example, imagine walking a type like:
-        //
-        //     &'a &'b T
-        //         ^
-        //
-        // when we hit the inner pointer (indicated by caret), `'a` will
-        // be on top of stack and `'b` will be the lifetime of the content
-        // we just found. So we add constraint that `'a <= 'b`.
-
-        let &(r_a, opt_ty) = self.stack.last().unwrap();
-        self.push_sub_region_constraint(opt_ty, r_a, r_b);
-    }
-
-    /// Pushes a constraint that `r_a <= r_b`, due to `opt_ty`
-    fn push_sub_region_constraint(&mut self,
-                                  opt_ty: Option<Ty<'tcx>>,
-                                  r_a: ty::Region,
-                                  r_b: ty::Region) {
-        self.out.push(Implication::RegionSubRegion(opt_ty, r_a, r_b));
-    }
-
-    /// Pushes a constraint that `param_ty` must outlive the top region on the stack.
-    fn push_param_constraint_from_top(&mut self,
-                                      param_ty: ty::ParamTy) {
-        let &(region, opt_ty) = self.stack.last().unwrap();
-        self.push_param_constraint(region, opt_ty, param_ty);
-    }
-
-    /// Pushes a constraint that `projection_ty` must outlive the top region on the stack.
-    fn push_projection_constraint_from_top(&mut self,
-                                           projection_ty: &ty::ProjectionTy<'tcx>) {
-        let &(region, opt_ty) = self.stack.last().unwrap();
-        self.out.push(Implication::RegionSubGeneric(
-            opt_ty, region, GenericKind::Projection(projection_ty.clone())));
-    }
-
-    /// Pushes a constraint that `region <= param_ty`, due to `opt_ty`
-    fn push_param_constraint(&mut self,
-                             region: ty::Region,
-                             opt_ty: Option<Ty<'tcx>>,
-                             param_ty: ty::ParamTy) {
-        self.out.push(Implication::RegionSubGeneric(
-            opt_ty, region, GenericKind::Param(param_ty)));
-    }
-
-    fn accumulate_from_adt(&mut self,
-                           ty: Ty<'tcx>,
-                           def_id: DefId,
-                           _generics: &ty::Generics<'tcx>,
-                           substs: &Substs<'tcx>)
-    {
-        let predicates =
-            self.tcx().lookup_predicates(def_id).instantiate(self.tcx(), substs);
-        let predicates = match self.fully_normalize(&predicates) {
-            Ok(predicates) => predicates,
-            Err(ErrorReported) => { return; }
-        };
-
-        for predicate in predicates.predicates.as_slice() {
-            match *predicate {
-                ty::Predicate::Trait(..) => { }
-                ty::Predicate::Equate(..) => { }
-                ty::Predicate::Projection(..) => { }
-                ty::Predicate::RegionOutlives(ref data) => {
-                    match self.tcx().no_late_bound_regions(data) {
-                        None => { }
-                        Some(ty::OutlivesPredicate(r_a, r_b)) => {
-                            self.push_sub_region_constraint(Some(ty), r_b, r_a);
-                        }
-                    }
-                }
-                ty::Predicate::TypeOutlives(ref data) => {
-                    match self.tcx().no_late_bound_regions(data) {
-                        None => { }
-                        Some(ty::OutlivesPredicate(ty_a, r_b)) => {
-                            self.stack.push((r_b, Some(ty)));
-                            self.accumulate_from_ty(ty_a);
-                            self.stack.pop().unwrap();
-                        }
-                    }
-                }
-                ty::Predicate::ObjectSafe(_) |
-                ty::Predicate::WellFormed(_) => {
-                }
-            }
-        }
-
-        let obligations = predicates.predicates
-                                    .into_iter()
-                                    .map(|pred| Implication::Predicate(def_id, pred));
-        self.out.extend(obligations);
-
-        let variances = self.tcx().item_variances(def_id);
-        self.accumulate_from_substs(substs, Some(&variances));
-    }
-
-    fn accumulate_from_substs(&mut self,
-                              substs: &Substs<'tcx>,
-                              variances: Option<&ty::ItemVariances>)
-    {
-        let mut tmp_variances = None;
-        let variances = variances.unwrap_or_else(|| {
-            tmp_variances = Some(ty::ItemVariances {
-                types: substs.types.map(|_| ty::Variance::Invariant),
-                regions: substs.regions().map(|_| ty::Variance::Invariant),
-            });
-            tmp_variances.as_ref().unwrap()
-        });
-
-        for (&region, &variance) in substs.regions().iter().zip(&variances.regions) {
-            match variance {
-                ty::Contravariant | ty::Invariant => {
-                    // If any data with this lifetime is reachable
-                    // within, it must be at least contravariant.
-                    self.push_region_constraint_from_top(region)
-                }
-                ty::Covariant | ty::Bivariant => { }
-            }
-        }
-
-        for (&ty, &variance) in substs.types.iter().zip(&variances.types) {
-            match variance {
-                ty::Covariant | ty::Invariant => {
-                    // If any data of this type is reachable within,
-                    // it must be at least covariant.
-                    self.accumulate_from_ty(ty);
-                }
-                ty::Contravariant | ty::Bivariant => { }
-            }
-        }
-    }
-
-    fn accumulate_from_object_ty(&mut self,
-                                 ty: Ty<'tcx>,
-                                 region_bound: ty::Region,
-                                 required_region_bounds: Vec<ty::Region>)
-    {
-        // Imagine a type like this:
-        //
-        //     trait Foo { }
-        //     trait Bar<'c> : 'c { }
-        //
-        //     &'b (Foo+'c+Bar<'d>)
-        //         ^
-        //
-        // In this case, the following relationships must hold:
-        //
-        //     'b <= 'c
-        //     'd <= 'c
-        //
-        // The first conditions is due to the normal region pointer
-        // rules, which say that a reference cannot outlive its
-        // referent.
-        //
-        // The final condition may be a bit surprising. In particular,
-        // you may expect that it would have been `'c <= 'd`, since
-        // usually lifetimes of outer things are conservative
-        // approximations for inner things. However, it works somewhat
-        // differently with trait objects: here the idea is that if the
-        // user specifies a region bound (`'c`, in this case) it is the
-        // "master bound" that *implies* that bounds from other traits are
-        // all met. (Remember that *all bounds* in a type like
-        // `Foo+Bar+Zed` must be met, not just one, hence if we write
-        // `Foo<'x>+Bar<'y>`, we know that the type outlives *both* 'x and
-        // 'y.)
-        //
-        // Note: in fact we only permit builtin traits, not `Bar<'d>`, I
-        // am looking forward to the future here.
-
-        // The content of this object type must outlive
-        // `bounds.region_bound`:
-        let r_c = region_bound;
-        self.push_region_constraint_from_top(r_c);
-
-        // And then, in turn, to be well-formed, the
-        // `region_bound` that user specified must imply the
-        // region bounds required from all of the trait types:
-        for &r_d in &required_region_bounds {
-            // Each of these is an instance of the `'c <= 'b`
-            // constraint above
-            self.out.push(Implication::RegionSubRegion(Some(ty), r_d, r_c));
-        }
-    }
-
-    fn fully_normalize<T>(&self, value: &T) -> Result<T,ErrorReported>
-        where T : TypeFoldable<'tcx>
-    {
-        let value =
-            traits::fully_normalize(self.infcx,
-                                    traits::ObligationCause::misc(self.span, self.body_id),
-                                    value);
-        match value {
-            Ok(value) => Ok(value),
-            Err(errors) => {
-                // I don't like reporting these errors here, but I
-                // don't know where else to report them just now. And
-                // I don't really expect errors to arise here
-                // frequently. I guess the best option would be to
-                // propagate them out.
-                traits::report_fulfillment_errors(self.infcx, &errors);
-                Err(ErrorReported)
-            }
-        }
-    }
-}
-
-/// Given an object type like `SomeTrait+Send`, computes the lifetime
-/// bounds that must hold on the elided self type. These are derived
-/// from the declarations of `SomeTrait`, `Send`, and friends -- if
-/// they declare `trait SomeTrait : 'static`, for example, then
-/// `'static` would appear in the list. The hard work is done by
-/// `ty::required_region_bounds`, see that for more information.
-pub fn object_region_bounds<'tcx>(
-    tcx: &ty::ctxt<'tcx>,
-    principal: &ty::PolyTraitRef<'tcx>,
-    others: ty::BuiltinBounds)
-    -> Vec<ty::Region>
-{
-    // Since we don't actually *know* the self type for an object,
-    // this "open(err)" serves as a kind of dummy standin -- basically
-    // a skolemized type.
-    let open_ty = tcx.mk_infer(ty::FreshTy(0));
-
-    // Note that we preserve the overall binding levels here.
-    assert!(!open_ty.has_escaping_regions());
-    let substs = tcx.mk_substs(principal.0.substs.with_self_ty(open_ty));
-    let trait_refs = vec!(ty::Binder(ty::TraitRef::new(principal.0.def_id, substs)));
-
-    let mut predicates = others.to_predicates(tcx, open_ty);
-    predicates.extend(trait_refs.iter().map(|t| t.to_predicate()));
-
-    tcx.required_region_bounds(open_ty, predicates)
-}
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 47cd31d9898..56b02412c31 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -86,7 +86,6 @@ use astconv::AstConv;
 use check::dropck;
 use check::FnCtxt;
 use middle::free_region::FreeRegionMap;
-use middle::implicator::{self, Implication};
 use middle::mem_categorization as mc;
 use middle::mem_categorization::Categorization;
 use middle::region::{self, CodeExtent};
@@ -365,12 +364,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
                    r_o, r_o.cause);
             let sup_type = self.resolve_type(r_o.sup_type);
             let origin = self.code_to_origin(r_o.cause.span, sup_type, &r_o.cause.code);
-
-            if r_o.sub_region != ty::ReEmpty {
-                type_must_outlive(self, origin, sup_type, r_o.sub_region);
-            } else {
-                self.visit_old_school_wf(node_id, sup_type, origin);
-            }
+            type_must_outlive(self, origin, sup_type, r_o.sub_region);
         }
 
         // Processing the region obligations should not cause the list to grow further:
@@ -378,47 +372,6 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
                    self.fcx.inh.infcx.fulfillment_cx.borrow().region_obligations(node_id).len());
     }
 
-    fn visit_old_school_wf(&mut self,
-                           body_id: ast::NodeId,
-                           ty: Ty<'tcx>,
-                           origin: infer::SubregionOrigin<'tcx>) {
-        // As a weird kind of hack, we use a region of empty as a signal
-        // to mean "old-school WF rules". The only reason the old-school
-        // WF rules are not encoded using WF is that this leads to errors,
-        // and we want to phase those in gradually.
-
-        // FIXME(#27579) remove this weird special case once we phase in new WF rules completely
-        let implications = implicator::implications(self.infcx(),
-                                                    body_id,
-                                                    ty,
-                                                    ty::ReEmpty,
-                                                    origin.span());
-        let origin_for_ty = |ty: Option<Ty<'tcx>>| match ty {
-            None => origin.clone(),
-            Some(ty) => infer::ReferenceOutlivesReferent(ty, origin.span()),
-        };
-        for implication in implications {
-            match implication {
-                Implication::RegionSubRegion(ty, r1, r2) => {
-                    self.fcx.mk_subr(origin_for_ty(ty), r1, r2);
-                }
-                Implication::RegionSubGeneric(ty, r1, GenericKind::Param(param_ty)) => {
-                    param_ty_must_outlive(self, origin_for_ty(ty), r1, param_ty);
-                }
-                Implication::RegionSubGeneric(ty, r1, GenericKind::Projection(proj_ty)) => {
-                    projection_must_outlive(self, origin_for_ty(ty), r1, proj_ty);
-                }
-                Implication::Predicate(def_id, predicate) => {
-                    let cause = traits::ObligationCause::new(origin.span(),
-                                                             body_id,
-                                                             traits::ItemObligation(def_id));
-                    let obligation = traits::Obligation::new(cause, predicate);
-                    self.fcx.register_predicate(obligation);
-                }
-            }
-        }
-    }
-
     fn code_to_origin(&self,
                       span: Span,
                       sup_type: Ty<'tcx>,