]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/regionck.rs
rustc: do not depend on infcx.tables in MemCategorizationContext.
[rust.git] / src / librustc_typeck / check / regionck.rs
index 6cb9375c5de796d38b1b99b51f549ea28a4670d6..616de1fc41229106b1d3964b8fbee3c63dd4ef05 100644 (file)
@@ -386,7 +386,8 @@ fn relate_free_regions(&mut self,
         for &ty in fn_sig_tys {
             let ty = self.resolve_type(ty);
             debug!("relate_free_regions(t={:?})", ty);
-            let implied_bounds = ty::wf::implied_bounds(self, body_id, ty, span);
+            let implied_bounds =
+                ty::wf::implied_bounds(self, self.fcx.param_env, body_id, ty, span);
 
             // Record any relations between free regions that we observe into the free-region-map.
             self.free_region_map.relate_free_regions_from_implied_bounds(&implied_bounds);
@@ -520,14 +521,13 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
         self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span),
                                expr_ty, expr_region);
 
-        let opt_method_callee = self.tables.borrow().method_map.get(&expr.id).cloned();
-        let has_method_map = opt_method_callee.is_some();
+        let is_method_call = self.tables.borrow().is_method_call(expr);
 
         // If we are calling a method (either explicitly or via an
         // overloaded operator), check that all of the types provided as
         // arguments for its type parameters are well-formed, and all the regions
         // provided as arguments outlive the call.
-        if let Some(callee) = opt_method_callee {
+        if is_method_call {
             let origin = match expr.node {
                 hir::ExprMethodCall(..) =>
                     infer::ParameterOrigin::MethodCall,
@@ -537,65 +537,16 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
                     infer::ParameterOrigin::OverloadedOperator
             };
 
-            self.substs_wf_in_scope(origin, &callee.substs, expr.span, expr_region);
-            self.type_must_outlive(infer::ExprTypeIsNotInScope(callee.ty, expr.span),
-                                   callee.ty, expr_region);
+            let substs = self.tables.borrow().node_substs(expr.id);
+            self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
+            // Arguments (sub-expressions) are checked via `constrain_call`, below.
         }
 
         // Check any autoderefs or autorefs that appear.
-        let adjustment = self.tables.borrow().adjustments.get(&expr.id).map(|a| a.clone());
-        if let Some(adjustment) = adjustment {
-            debug!("adjustment={:?}", adjustment);
-            match adjustment.kind {
-                adjustment::Adjust::DerefRef { ref autoderefs, ref autoref, .. } => {
-                    let cmt = ignore_err!(self.constrain_autoderefs(expr, autoderefs));
-                    if let Some(ref autoref) = *autoref {
-                        self.link_autoref(expr, cmt, autoref);
-
-                        // Require that the resulting region encompasses
-                        // the current node.
-                        //
-                        // FIXME(#6268) remove to support nested method calls
-                        self.type_of_node_must_outlive(infer::AutoBorrow(expr.span),
-                                                       expr.id, expr_region);
-                    }
-                }
-                /*
-                adjustment::AutoObject(_, ref bounds, ..) => {
-                    // Determine if we are casting `expr` to a trait
-                    // instance. If so, we have to be sure that the type
-                    // of the source obeys the new region bound.
-                    let source_ty = self.resolve_node_type(expr.id);
-                    self.type_must_outlive(infer::RelateObjectBound(expr.span),
-                                           source_ty, bounds.region_bound);
-                }
-                */
-                _ => {}
-            }
-
-            // If necessary, constrain destructors in the unadjusted form of this
-            // expression.
-            let cmt_result = {
-                let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
-                mc.cat_expr_unadjusted(expr)
-            };
-            match cmt_result {
-                Ok(head_cmt) => {
-                    self.check_safety_of_rvalue_destructor_if_necessary(head_cmt,
-                                                                        expr.span);
-                }
-                Err(..) => {
-                    self.tcx.sess.delay_span_bug(expr.span, "cat_expr_unadjusted Errd");
-                }
-            }
-        }
+        let cmt_result = self.constrain_adjustments(expr);
 
         // If necessary, constrain destructors in this expression. This will be
         // the adjusted form if there is an adjustment.
-        let cmt_result = {
-            let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
-            mc.cat_expr(expr)
-        };
         match cmt_result {
             Ok(head_cmt) => {
                 self.check_safety_of_rvalue_destructor_if_necessary(head_cmt, expr.span);
@@ -609,57 +560,45 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
                expr, self.repeating_scope);
         match expr.node {
             hir::ExprPath(_) => {
-                self.fcx.opt_node_ty_substs(expr.id, |item_substs| {
-                    let origin = infer::ParameterOrigin::Path;
-                    self.substs_wf_in_scope(origin, &item_substs.substs, expr.span, expr_region);
-                });
+                let substs = self.tables.borrow().node_substs(expr.id);
+                let origin = infer::ParameterOrigin::Path;
+                self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
             }
 
             hir::ExprCall(ref callee, ref args) => {
-                if has_method_map {
-                    self.constrain_call(expr, Some(&callee),
-                                        args.iter().map(|e| &*e), false);
+                if is_method_call {
+                    self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e));
                 } else {
                     self.constrain_callee(callee.id, expr, &callee);
-                    self.constrain_call(expr, None,
-                                        args.iter().map(|e| &*e), false);
+                    self.constrain_call(expr, None, args.iter().map(|e| &*e));
                 }
 
                 intravisit::walk_expr(self, expr);
             }
 
             hir::ExprMethodCall(.., ref args) => {
-                self.constrain_call(expr, Some(&args[0]),
-                                    args[1..].iter().map(|e| &*e), false);
+                self.constrain_call(expr, Some(&args[0]), args[1..].iter().map(|e| &*e));
 
                 intravisit::walk_expr(self, expr);
             }
 
             hir::ExprAssignOp(_, ref lhs, ref rhs) => {
-                if has_method_map {
-                    self.constrain_call(expr, Some(&lhs),
-                                        Some(&**rhs).into_iter(), false);
+                if is_method_call {
+                    self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
                 }
 
                 intravisit::walk_expr(self, expr);
             }
 
-            hir::ExprIndex(ref lhs, ref rhs) if has_method_map => {
-                self.constrain_call(expr, Some(&lhs),
-                                    Some(&**rhs).into_iter(), true);
+            hir::ExprIndex(ref lhs, ref rhs) if is_method_call => {
+                self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
 
                 intravisit::walk_expr(self, expr);
             },
 
-            hir::ExprBinary(op, ref lhs, ref rhs) if has_method_map => {
-                let implicitly_ref_args = !op.node.is_by_value();
-
-                // As `expr_method_call`, but the call is via an
-                // overloaded op.  Note that we (sadly) currently use an
-                // implicit "by ref" sort of passing style here.  This
-                // should be converted to an adjustment!
-                self.constrain_call(expr, Some(&lhs),
-                                    Some(&**rhs).into_iter(), implicitly_ref_args);
+            hir::ExprBinary(_, ref lhs, ref rhs) if is_method_call => {
+                // As `ExprMethodCall`, but the call is via an overloaded op.
+                self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
 
                 intravisit::walk_expr(self, expr);
             }
@@ -676,28 +615,14 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
                 intravisit::walk_expr(self, expr);
             }
 
-            hir::ExprUnary(op, ref lhs) if has_method_map => {
-                let implicitly_ref_args = !op.is_by_value();
-
-                // As above.
-                self.constrain_call(expr, Some(&lhs),
-                                    None::<hir::Expr>.iter(), implicitly_ref_args);
-
-                intravisit::walk_expr(self, expr);
-            }
-
             hir::ExprUnary(hir::UnDeref, ref base) => {
                 // For *a, the lifetime of a must enclose the deref
-                let base_ty = match self.tables.borrow().method_map.get(&expr.id) {
-                    Some(method) => {
-                        self.constrain_call(expr, Some(&base),
-                                            None::<hir::Expr>.iter(), true);
-                        // late-bound regions in overloaded method calls are instantiated
-                        let fn_ret = self.tcx.no_late_bound_regions(&method.ty.fn_ret());
-                        fn_ret.unwrap()
-                    }
-                    None => self.resolve_node_type(base.id)
-                };
+                if is_method_call {
+                    self.constrain_call(expr, Some(base), None::<hir::Expr>.iter());
+                }
+                // For overloaded derefs, base_ty is the input to `Deref::deref`,
+                // but it's a reference type uing the same region as the output.
+                let base_ty = self.resolve_expr_type_adjusted(base);
                 if let ty::TyRef(r_ptr, _) = base_ty.sty {
                     self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr);
                 }
@@ -705,6 +630,13 @@ fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
                 intravisit::walk_expr(self, expr);
             }
 
+            hir::ExprUnary(_, ref lhs) if is_method_call => {
+                // As above.
+                self.constrain_call(expr, Some(&lhs), None::<hir::Expr>.iter());
+
+                intravisit::walk_expr(self, expr);
+            }
+
             hir::ExprIndex(ref vec_expr, _) => {
                 // For a[b], the lifetime of a must enclose the deref
                 let vec_type = self.resolve_expr_type_adjusted(&vec_expr);
@@ -856,19 +788,15 @@ fn constrain_callee(&mut self,
     fn constrain_call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
                                                            call_expr: &hir::Expr,
                                                            receiver: Option<&hir::Expr>,
-                                                           arg_exprs: I,
-                                                           implicitly_ref_args: bool) {
+                                                           arg_exprs: I) {
         //! Invoked on every call site (i.e., normal calls, method calls,
         //! and overloaded operators). Constrains the regions which appear
         //! in the type of the function. Also constrains the regions that
         //! appear in the arguments appropriately.
 
-        debug!("constrain_call(call_expr={:?}, \
-                receiver={:?}, \
-                implicitly_ref_args={})",
+        debug!("constrain_call(call_expr={:?}, receiver={:?})",
                 call_expr,
-                receiver,
-                implicitly_ref_args);
+                receiver);
 
         // `callee_region` is the scope representing the time in which the
         // call occurs.
@@ -886,14 +814,6 @@ fn constrain_call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
             // valid for at least the lifetime of the function:
             self.type_of_node_must_outlive(infer::CallArg(arg_expr.span),
                                            arg_expr.id, callee_region);
-
-            // unfortunately, there are two means of taking implicit
-            // references, and we need to propagate constraints as a
-            // result. modes are going away and the "DerefArgs" code
-            // should be ported to use adjustments
-            if implicitly_ref_args {
-                self.link_by_ref(arg_expr, callee_scope);
-            }
         }
 
         // as loop above, but for receiver
@@ -901,74 +821,82 @@ fn constrain_call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
             debug!("receiver: {:?}", r);
             self.type_of_node_must_outlive(infer::CallRcvr(r.span),
                                            r.id, callee_region);
-            if implicitly_ref_args {
-                self.link_by_ref(&r, callee_scope);
-            }
         }
     }
 
-    /// Invoked on any auto-dereference that occurs. Checks that if this is a region pointer being
-    /// dereferenced, the lifetime of the pointer includes the deref expr.
-    fn constrain_autoderefs(&mut self,
-                            deref_expr: &hir::Expr,
-                            autoderefs: &[Option<ty::MethodCallee<'tcx>>])
-                            -> mc::McResult<mc::cmt<'tcx>>
+    /// Create a temporary `MemCategorizationContext` and pass it to the closure.
+    fn with_mc<F, R>(&self, f: F) -> R
+        where F: for<'b> FnOnce(mc::MemCategorizationContext<'b, 'gcx, 'tcx>) -> R
     {
-        debug!("constrain_autoderefs(deref_expr={:?}, autoderefs={:?})",
-               deref_expr,
-               autoderefs);
+        f(mc::MemCategorizationContext::new(&self.infcx,
+                                            &self.region_maps,
+                                            &self.tables.borrow()))
+    }
 
-        let mut cmt = {
-            let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
-            mc.cat_expr_unadjusted(deref_expr)?
-        };
+    /// Invoked on any adjustments that occur. Checks that if this is a region pointer being
+    /// dereferenced, the lifetime of the pointer includes the deref expr.
+    fn constrain_adjustments(&mut self, expr: &hir::Expr) -> mc::McResult<mc::cmt<'tcx>> {
+        debug!("constrain_adjustments(expr={:?})", expr);
 
-        let r_deref_expr = self.tcx.node_scope_region(deref_expr.id);
-        for &overloaded in autoderefs {
-            if let Some(method) = overloaded {
-                debug!("constrain_autoderefs: overloaded, method={:?}", method);
+        let mut cmt = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
+
+        let tables = self.tables.borrow();
+        let adjustments = tables.expr_adjustments(&expr);
+        if adjustments.is_empty() {
+            return Ok(cmt);
+        }
 
-                let origin = infer::ParameterOrigin::OverloadedDeref;
-                self.substs_wf_in_scope(origin, method.substs, deref_expr.span, r_deref_expr);
+        debug!("constrain_adjustments: adjustments={:?}", adjustments);
+
+        // If necessary, constrain destructors in the unadjusted form of this
+        // expression.
+        self.check_safety_of_rvalue_destructor_if_necessary(cmt.clone(), expr.span);
+
+        let expr_region = self.tcx.node_scope_region(expr.id);
+        for adjustment in adjustments {
+            debug!("constrain_adjustments: adjustment={:?}, cmt={:?}",
+                   adjustment, cmt);
+
+            if let adjustment::Adjust::Deref(Some(deref)) = adjustment.kind {
+                debug!("constrain_adjustments: overloaded deref: {:?}", deref);
 
                 // Treat overloaded autoderefs as if an AutoBorrow adjustment
                 // was applied on the base type, as that is always the case.
-                let fn_sig = method.ty.fn_sig();
-                let fn_sig = // late-bound regions should have been instantiated
-                    self.tcx.no_late_bound_regions(&fn_sig).unwrap();
-                let self_ty = fn_sig.inputs()[0];
-                let (m, r) = match self_ty.sty {
-                    ty::TyRef(r, ref m) => (m.mutbl, r),
-                    _ => {
-                        span_bug!(
-                            deref_expr.span,
-                            "bad overloaded deref type {:?}",
-                            method.ty)
-                    }
-                };
-
-                debug!("constrain_autoderefs: receiver r={:?} m={:?}",
-                       r, m);
+                let input = self.tcx.mk_ref(deref.region, ty::TypeAndMut {
+                    ty: cmt.ty,
+                    mutbl: deref.mutbl,
+                });
+                let output = self.tcx.mk_ref(deref.region, ty::TypeAndMut {
+                    ty: adjustment.target,
+                    mutbl: deref.mutbl,
+                });
 
-                debug!("constrain_autoderefs: self_cmt={:?}", cmt);
-                self.link_region(deref_expr.span, r,
-                                 ty::BorrowKind::from_mutbl(m), cmt.clone());
+                self.link_region(expr.span, deref.region,
+                                 ty::BorrowKind::from_mutbl(deref.mutbl), cmt.clone());
 
                 // Specialized version of constrain_call.
-                self.type_must_outlive(infer::CallRcvr(deref_expr.span),
-                                       self_ty, r_deref_expr);
-                self.type_must_outlive(infer::CallReturn(deref_expr.span),
-                                       fn_sig.output(), r_deref_expr);
+                self.type_must_outlive(infer::CallRcvr(expr.span),
+                                       input, expr_region);
+                self.type_must_outlive(infer::CallReturn(expr.span),
+                                       output, expr_region);
             }
 
-            {
-                let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
-                cmt = mc.cat_deref(deref_expr, cmt, overloaded)?;
+            if let adjustment::Adjust::Borrow(ref autoref) = adjustment.kind {
+                self.link_autoref(expr, cmt.clone(), autoref);
+
+                // Require that the resulting region encompasses
+                // the current node.
+                //
+                // FIXME(#6268) remove to support nested method calls
+                self.type_of_node_must_outlive(infer::AutoBorrow(expr.span),
+                                               expr.id, expr_region);
             }
 
+            cmt = self.with_mc(|mc| mc.cat_expr_adjusted(expr, cmt, &adjustment))?;
+
             if let Categorization::Deref(_, mc::BorrowedPtr(_, r_ptr)) = cmt.cat {
-                self.mk_subregion_due_to_dereference(deref_expr.span,
-                                                     r_deref_expr, r_ptr);
+                self.mk_subregion_due_to_dereference(expr.span,
+                                                     expr_region, r_ptr);
             }
         }
 
@@ -987,7 +915,7 @@ fn check_safety_of_rvalue_destructor_if_necessary(&mut self,
                                                      cmt: mc::cmt<'tcx>,
                                                      span: Span) {
         match cmt.cat {
-            Categorization::Rvalue(region, _) => {
+            Categorization::Rvalue(region) => {
                 match *region {
                     ty::ReScope(rvalue_scope) => {
                         let typ = self.resolve_type(cmt.ty);
@@ -1039,7 +967,9 @@ fn type_of_node_must_outlive(&mut self,
         // is going to fail anyway, so just stop here and let typeck
         // report errors later on in the writeback phase.
         let ty0 = self.resolve_node_type(id);
-        let ty = self.tables.borrow().adjustments.get(&id).map_or(ty0, |adj| adj.target);
+        let ty = self.tables.borrow().adjustments.get(&id)
+            .and_then(|adj| adj.last())
+            .map_or(ty0, |adj| adj.target);
         let ty = self.resolve_type(ty);
         debug!("constrain_regions_in_type_of_node(\
                 ty={}, ty0={}, id={}, minimum_lifetime={:?})",
@@ -1054,10 +984,7 @@ fn link_addr_of(&mut self, expr: &hir::Expr,
                     mutability: hir::Mutability, base: &hir::Expr) {
         debug!("link_addr_of(expr={:?}, base={:?})", expr, base);
 
-        let cmt = {
-            let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
-            ignore_err!(mc.cat_expr(base))
-        };
+        let cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(base)));
 
         debug!("link_addr_of: cmt={:?}", cmt);
 
@@ -1073,9 +1000,8 @@ fn link_local(&self, local: &hir::Local) {
             None => { return; }
             Some(ref expr) => &**expr,
         };
-        let mc = &mc::MemCategorizationContext::new(self, &self.region_maps);
-        let discr_cmt = ignore_err!(mc.cat_expr(init_expr));
-        self.link_pattern(mc, discr_cmt, &local.pat);
+        let discr_cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(init_expr)));
+        self.link_pattern(discr_cmt, &local.pat);
     }
 
     /// Computes the guarantors for any ref bindings in a match and
@@ -1083,12 +1009,11 @@ fn link_local(&self, local: &hir::Local) {
     /// linked to the lifetime of its guarantor (if any).
     fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) {
         debug!("regionck::for_match()");
-        let mc = &mc::MemCategorizationContext::new(self, &self.region_maps);
-        let discr_cmt = ignore_err!(mc.cat_expr(discr));
+        let discr_cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(discr)));
         debug!("discr_cmt={:?}", discr_cmt);
         for arm in arms {
             for root_pat in &arm.pats {
-                self.link_pattern(mc, discr_cmt.clone(), &root_pat);
+                self.link_pattern(discr_cmt.clone(), &root_pat);
             }
         }
     }
@@ -1098,30 +1023,28 @@ fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) {
     /// linked to the lifetime of its guarantor (if any).
     fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) {
         debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
-        let mc = &mc::MemCategorizationContext::new(self, &self.region_maps);
         for arg in args {
             let arg_ty = self.node_ty(arg.id);
             let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
-            let arg_cmt = mc.cat_rvalue(
-                arg.id, arg.pat.span, re_scope, re_scope, arg_ty);
+            let arg_cmt = self.with_mc(|mc| {
+                mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty)
+            });
             debug!("arg_ty={:?} arg_cmt={:?} arg={:?}",
                    arg_ty,
                    arg_cmt,
                    arg);
-            self.link_pattern(mc, arg_cmt, &arg.pat);
+            self.link_pattern(arg_cmt, &arg.pat);
         }
     }
 
     /// Link lifetimes of any ref bindings in `root_pat` to the pointers found
     /// in the discriminant, if needed.
-    fn link_pattern<'t>(&self,
-                        mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
-                        discr_cmt: mc::cmt<'tcx>,
-                        root_pat: &hir::Pat) {
+    fn link_pattern(&self, discr_cmt: mc::cmt<'tcx>, root_pat: &hir::Pat) {
         debug!("link_pattern(discr_cmt={:?}, root_pat={:?})",
                discr_cmt,
                root_pat);
-        let _ = mc.cat_pattern(discr_cmt, root_pat, |_, sub_cmt, sub_pat| {
+        let _ = self.with_mc(|mc| {
+            mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, sub_pat| {
                 match sub_pat.node {
                     // `ref x` pattern
                     PatKind::Binding(hir::BindByRef(mutbl), ..) => {
@@ -1130,7 +1053,8 @@ fn link_pattern<'t>(&self,
                     }
                     _ => {}
                 }
-            });
+            })
+        });
     }
 
     /// Link lifetime of borrowed pointer resulting from autoref to lifetimes in the value being
@@ -1155,19 +1079,6 @@ fn link_autoref(&self,
         }
     }
 
-    /// Computes the guarantor for cases where the `expr` is being passed by implicit reference and
-    /// must outlive `callee_scope`.
-    fn link_by_ref(&self,
-                   expr: &hir::Expr,
-                   callee_scope: CodeExtent) {
-        debug!("link_by_ref(expr={:?}, callee_scope={:?})",
-               expr, callee_scope);
-        let mc = mc::MemCategorizationContext::new(self, &self.region_maps);
-        let expr_cmt = ignore_err!(mc.cat_expr(expr));
-        let borrow_region = self.tcx.mk_region(ty::ReScope(callee_scope));
-        self.link_region(expr.span, borrow_region, ty::ImmBorrow, expr_cmt);
-    }
-
     /// Like `link_region()`, except that the region is extracted from the type of `id`,
     /// which must be some reference (`&T`, `&str`, etc).
     fn link_region_from_node_type(&self,
@@ -1301,8 +1212,7 @@ fn link_reborrowed_region(&self,
         // Detect by-ref upvar `x`:
         let cause = match note {
             mc::NoteUpvarRef(ref upvar_id) => {
-                let upvar_capture_map = &self.tables.borrow_mut().upvar_capture_map;
-                match upvar_capture_map.get(upvar_id) {
+                match self.tables.borrow().upvar_capture_map.get(upvar_id) {
                     Some(&ty::UpvarCapture::ByRef(ref upvar_borrow)) => {
                         // The mutability of the upvar may have been modified
                         // by the above adjustment, so update our local variable.
@@ -1632,8 +1542,8 @@ fn projection_bound(&self,
                declared_bounds, projection_ty);
 
         // see the extensive comment in projection_must_outlive
-
-        let ty = self.tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name);
+        let item_name = projection_ty.item_name(self.tcx);
+        let ty = self.tcx.mk_projection(projection_ty.trait_ref, item_name);
         let recursive_bound = self.recursive_type_bound(span, ty);
 
         VerifyBound::AnyRegion(declared_bounds).or(recursive_bound)
@@ -1699,9 +1609,9 @@ fn declared_projection_bounds_from_trait(&self,
     {
         debug!("projection_bounds(projection_ty={:?})",
                projection_ty);
-
+        let item_name = projection_ty.item_name(self.tcx);
         let ty = self.tcx.mk_projection(projection_ty.trait_ref.clone(),
-                                        projection_ty.item_name);
+                                        item_name);
 
         // Say we have a projection `<T as SomeTrait<'a>>::SomeType`. We are interested
         // in looking for a trait definition like:
@@ -1739,7 +1649,7 @@ fn declared_projection_bounds_from_trait(&self,
                     let (outlives, _) =
                         self.replace_late_bound_regions_with_fresh_var(
                             span,
-                            infer::AssocTypeProjection(projection_ty.item_name),
+                            infer::AssocTypeProjection(projection_ty.item_name(self.tcx)),
                             &outlives);
 
                     debug!("projection_bounds: outlives={:?} (3)",
@@ -1747,7 +1657,7 @@ fn declared_projection_bounds_from_trait(&self,
 
                     // check whether this predicate applies to our current projection
                     let cause = self.fcx.misc(span);
-                    match self.eq_types(false, &cause, ty, outlives.0) {
+                    match self.at(&cause, self.fcx.param_env).eq(outlives.0, ty) {
                         Ok(ok) => {
                             self.register_infer_ok_obligations(ok);
                             Ok(outlives.1)