]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/qualify_consts.rs
Merge branch 'refactor-select' of https://github.com/aravind-pg/rust into update...
[rust.git] / src / librustc_mir / transform / qualify_consts.rs
index 2b9ee223b01a478295f2c38c9a41f8151d195b3b..8f5831270d6e5afa94af754ef71f2f7e24914c61 100644 (file)
@@ -36,7 +36,7 @@
 use syntax_pos::{Span, DUMMY_SP};
 
 use std::fmt;
-use std::rc::Rc;
+use rustc_data_structures::sync::Lrc;
 use std::usize;
 
 use transform::{MirPass, MirSource};
@@ -319,7 +319,7 @@ fn assign(&mut self, dest: &Place<'tcx>, location: Location) {
     }
 
     /// Qualify a whole const, static initializer or const fn.
-    fn qualify_const(&mut self) -> (Qualif, Rc<IdxSetBuf<Local>>) {
+    fn qualify_const(&mut self) -> (Qualif, Lrc<IdxSetBuf<Local>>) {
         debug!("qualifying {} {:?}", self.mode, self.def_id);
 
         let mir = self.mir;
@@ -436,7 +436,7 @@ fn qualify_const(&mut self) -> (Qualif, Rc<IdxSetBuf<Local>>) {
             }
         }
 
-        (self.qualif, Rc::new(promoted_temps))
+        (self.qualif, Lrc::new(promoted_temps))
     }
 }
 
@@ -526,9 +526,10 @@ fn visit_place(&mut self,
                                 this.add(Qualif::STATIC);
                             }
 
+                            this.add(Qualif::NOT_CONST);
+
                             let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
                             if let ty::TyRawPtr(_) = base_ty.sty {
-                                this.add(Qualif::NOT_CONST);
                                 if this.mode != Mode::Fn {
                                     let mut err = struct_span_err!(
                                         this.tcx.sess,
@@ -617,7 +618,38 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
 
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
         // Recurse through operands and places.
-        self.super_rvalue(rvalue, location);
+        if let Rvalue::Ref(region, kind, ref place) = *rvalue {
+            let mut is_reborrow = false;
+            if let Place::Projection(ref proj) = *place {
+                if let ProjectionElem::Deref = proj.elem {
+                    let base_ty = proj.base.ty(self.mir, self.tcx).to_ty(self.tcx);
+                    if let ty::TyRef(..) = base_ty.sty {
+                        is_reborrow = true;
+                    }
+                }
+            }
+
+            if is_reborrow {
+                self.nest(|this| {
+                    this.super_place(place, PlaceContext::Borrow {
+                        region,
+                        kind
+                    }, location);
+                    if !this.try_consume() {
+                        return;
+                    }
+
+                    if this.qualif.intersects(Qualif::STATIC_REF) {
+                        this.qualif = this.qualif - Qualif::STATIC_REF;
+                        this.add(Qualif::STATIC);
+                    }
+                });
+            } else {
+                self.super_rvalue(rvalue, location);
+            }
+        } else {
+            self.super_rvalue(rvalue, location);
+        }
 
         match *rvalue {
             Rvalue::Use(_) |
@@ -904,7 +936,7 @@ fn visit_terminator_kind(&mut self,
                     if self.mode != Mode::Fn &&
 
                         // feature-gate is not enabled,
-                        !self.tcx.sess.features.borrow()
+                        !self.tcx.features()
                             .declared_lib_features
                             .iter()
                             .any(|&(ref sym, _)| sym == feature_name) &&
@@ -1089,7 +1121,7 @@ pub fn provide(providers: &mut Providers) {
 
 fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               def_id: DefId)
-                              -> (u8, Rc<IdxSetBuf<Local>>) {
+                              -> (u8, Lrc<IdxSetBuf<Local>>) {
     // NB: This `borrow()` is guaranteed to be valid (i.e., the value
     // cannot yet be stolen), because `mir_validated()`, which steals
     // from `mir_const(), forces this query to execute before
@@ -1098,7 +1130,7 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     if mir.return_ty().references_error() {
         tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: Mir had errors");
-        return (Qualif::NOT_CONST.bits(), Rc::new(IdxSetBuf::new_empty(0)));
+        return (Qualif::NOT_CONST.bits(), Lrc::new(IdxSetBuf::new_empty(0)));
     }
 
     let mut qualifier = Qualifier::new(tcx, def_id, mir, Mode::Const);