about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-07-29 17:19:57 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-07-29 17:50:42 +0300
commit80cf3f99f4a3377fd9b544d18017ef29b8713dfd (patch)
tree78abf14ee563149968a7e6b84f1b28b335a25aa5 /src
parentad36f8febad77942b4f1f0e2ba0f422b69276d7b (diff)
downloadrust-80cf3f99f4a3377fd9b544d18017ef29b8713dfd.tar.gz
rust-80cf3f99f4a3377fd9b544d18017ef29b8713dfd.zip
Cleanup some remains of `hr_lifetime_in_assoc_type` compatibility lint
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ich/impls_ty.rs1
-rw-r--r--src/librustc/infer/error_reporting/mod.rs35
-rw-r--r--src/librustc/infer/higher_ranked/mod.rs56
-rw-r--r--src/librustc/infer/mod.rs7
-rw-r--r--src/librustc/middle/resolve_lifetime.rs38
-rw-r--r--src/librustc/traits/project.rs41
-rw-r--r--src/librustc/ty/error.rs14
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc/ty/structural_impls.rs24
-rw-r--r--src/librustc/ty/sty.rs14
-rw-r--r--src/librustc_typeck/astconv.rs80
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/test/compile-fail/associated-types/cache/project-fn-ret-contravariant.rs24
-rw-r--r--src/test/compile-fail/associated-types/cache/project-fn-ret-invariant.rs46
-rw-r--r--src/test/compile-fail/hr-subtype.rs3
-rw-r--r--src/test/ui/regions-fn-subtyping-return-static.stderr2
17 files changed, 113 insertions, 278 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 3e227872848..42e4338ca30 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -368,7 +368,6 @@ for ty::RegionParameterDef {
             name,
             def_id,
             index,
-            issue_32330: _,
             pure_wrt_drop
         } = *self;
 
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 77ec866dc80..8e8576b83e4 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -66,8 +66,7 @@ use hir::map as hir_map;
 use hir::def_id::DefId;
 use middle::region;
 use traits::{ObligationCause, ObligationCauseCode};
-use ty::{self, TyCtxt, TypeFoldable};
-use ty::{Region, Issue32330};
+use ty::{self, Region, TyCtxt, TypeFoldable};
 use ty::error::TypeError;
 use syntax::ast::DUMMY_NODE_ID;
 use syntax_pos::{Pos, Span};
@@ -713,35 +712,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.tcx.note_and_explain_type_err(diag, terr, span);
     }
 
-    pub fn note_issue_32330(&self,
-                            diag: &mut DiagnosticBuilder<'tcx>,
-                            terr: &TypeError<'tcx>)
-    {
-        debug!("note_issue_32330: terr={:?}", terr);
-        match *terr {
-            TypeError::RegionsInsufficientlyPolymorphic(_, _, Some(box Issue32330 {
-                fn_def_id, region_name
-            })) |
-            TypeError::RegionsOverlyPolymorphic(_, _, Some(box Issue32330 {
-                fn_def_id, region_name
-            })) => {
-                diag.note(
-                    &format!("lifetime parameter `{0}` declared on fn `{1}` \
-                              appears only in the return type, \
-                              but here is required to be higher-ranked, \
-                              which means that `{0}` must appear in both \
-                              argument and return types",
-                             region_name,
-                             self.tcx.item_path_str(fn_def_id)));
-                diag.note(
-                    &format!("this error is the result of a recent bug fix; \
-                              for more information, see issue #33685 \
-                              <https://github.com/rust-lang/rust/issues/33685>"));
-            }
-            _ => {}
-        }
-    }
-
     pub fn report_and_explain_type_error(&self,
                                          trace: TypeTrace<'tcx>,
                                          terr: &TypeError<'tcx>)
@@ -761,7 +731,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
         };
         self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr);
-        self.note_issue_32330(&mut diag, terr);
         diag
     }
 
@@ -934,7 +903,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 format!(" for lifetime parameter {}in trait containing associated type `{}`",
                         br_string(br), type_name)
             }
-            infer::EarlyBoundRegion(_, name, _) => {
+            infer::EarlyBoundRegion(_, name) => {
                 format!(" for lifetime parameter `{}`",
                         name)
             }
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index 541a9978341..9ecc8b0e66b 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -13,9 +13,7 @@
 
 use super::{CombinedSnapshot,
             InferCtxt,
-            LateBoundRegion,
             HigherRankedType,
-            RegionVariableOrigin,
             SubregionOrigin,
             SkolemizationMap};
 use super::combine::CombineFields;
@@ -29,15 +27,6 @@ use util::nodemap::{FxHashMap, FxHashSet};
 
 pub struct HrMatchResult<U> {
     pub value: U,
-
-    /// Normally, when we do a higher-ranked match operation, we
-    /// expect all higher-ranked regions to be constrained as part of
-    /// the match operation. However, in the transition period for
-    /// #32330, it can happen that we sometimes have unconstrained
-    /// regions that get instantiated with fresh variables. In that
-    /// case, we collect the set of unconstrained bound regions here
-    /// and replace them with fresh variables.
-    pub unconstrained_regions: Vec<ty::BoundRegion>,
 }
 
 impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
@@ -108,7 +97,6 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
     /// that do not appear in `T`. If that happens, those regions are
     /// unconstrained, and this routine replaces them with `'static`.
     pub fn higher_ranked_match<T, U>(&mut self,
-                                     span: Span,
                                      a_pair: &Binder<(T, U)>,
                                      b_match: &T,
                                      a_is_expected: bool)
@@ -158,28 +146,16 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
             // be any region from the sets above, except for other members of
             // `skol_map`. There should always be a representative if things
             // are properly well-formed.
-            let mut unconstrained_regions = vec![];
             let skol_representatives: FxHashMap<_, _> =
                 skol_resolution_map
                 .iter()
-                .map(|(&skol, &(br, ref regions))| {
+                .map(|(&skol, &(_, ref regions))| {
                     let representative =
                         regions.iter()
                                .filter(|&&r| !skol_resolution_map.contains_key(r))
                                .cloned()
                                .next()
-                               .unwrap_or_else(|| { // [1]
-                                   unconstrained_regions.push(br);
-                                   self.infcx.next_region_var(
-                                       LateBoundRegion(span, br, HigherRankedType))
-                               });
-
-                    // [1] There should always be a representative,
-                    // unless the higher-ranked region did not appear
-                    // in the values being matched. We should reject
-                    // as ill-formed cases that can lead to this, but
-                    // right now we sometimes issue warnings (see
-                    // #32330).
+                               .expect("no representative region");
 
                     (skol, representative)
                 })
@@ -216,10 +192,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
             // We are now done with these skolemized variables.
             self.infcx.pop_skolemized(skol_map, snapshot);
 
-            Ok(HrMatchResult {
-                value: a_value,
-                unconstrained_regions,
-            })
+            Ok(HrMatchResult { value: a_value })
         });
     }
 
@@ -657,28 +630,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                        skol_br,
                        tainted_region);
 
-                let issue_32330 = if let &ty::ReVar(vid) = tainted_region {
-                    match self.region_vars.var_origin(vid) {
-                        RegionVariableOrigin::EarlyBoundRegion(_, _, issue_32330) => {
-                            issue_32330.map(Box::new)
-                        }
-                        _ => None
-                    }
-                } else {
-                    None
-                };
-
-                if overly_polymorphic {
+                return Err(if overly_polymorphic {
                     debug!("Overly polymorphic!");
-                    return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
-                                                                   tainted_region,
-                                                                   issue_32330));
+                    TypeError::RegionsOverlyPolymorphic(skol_br, tainted_region)
                 } else {
                     debug!("Not as polymorphic!");
-                    return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
-                                                                           tainted_region,
-                                                                           issue_32330));
-                }
+                    TypeError::RegionsInsufficientlyPolymorphic(skol_br, tainted_region)
+                })
             }
         }
 
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 7154ce9e38f..bf79becfe4a 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -299,7 +299,7 @@ pub enum RegionVariableOrigin {
     Coercion(Span),
 
     // Region variables created as the values for early-bound regions
-    EarlyBoundRegion(Span, ast::Name, Option<ty::Issue32330>),
+    EarlyBoundRegion(Span, ast::Name),
 
     // Region variables created for bound regions
     // in a function or method that is called
@@ -989,7 +989,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                               span: Span,
                               def: &ty::RegionParameterDef)
                               -> ty::Region<'tcx> {
-        self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
+        self.next_region_var(EarlyBoundRegion(span, def.name))
     }
 
     /// Create a type inference variable for the given
@@ -1278,14 +1278,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                            -> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
     {
         let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
-        let span = cause.span;
         let trace = TypeTrace {
             cause,
             values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
         };
 
         let mut combine = self.combine_fields(trace, param_env);
-        let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
+        let result = combine.higher_ranked_match(&match_pair, &match_b, true)?;
         Ok(InferOk { value: result, obligations: combine.obligations })
     }
 
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index c4f785757ce..13efa94a5c9 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -153,10 +153,6 @@ pub struct NamedRegionMap {
     // (b) it DOES appear in the arguments.
     pub late_bound: NodeSet,
 
-    // Contains the node-ids for lifetimes that were (incorrectly) categorized
-    // as late-bound, until #32330 was fixed.
-    pub issue_32330: NodeMap<ty::Issue32330>,
-
     // For each type and trait definition, maps type parameters
     // to the trait object lifetime defaults computed from them.
     pub object_lifetime_defaults: NodeMap<Vec<ObjectLifetimeDefault>>,
@@ -261,7 +257,6 @@ pub fn krate(sess: &Session,
     let mut map = NamedRegionMap {
         defs: NodeMap(),
         late_bound: NodeSet(),
-        issue_32330: NodeMap(),
         object_lifetime_defaults: compute_object_lifetime_defaults(sess, hir_map),
     };
     sess.track_errors(|| {
@@ -303,7 +298,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         match item.node {
             hir::ItemFn(ref decl, _, _, _, ref generics, _) => {
-                self.visit_early_late(item.id, None, decl, generics, |this| {
+                self.visit_early_late(None, decl, generics, |this| {
                     intravisit::walk_item(this, item);
                 });
             }
@@ -355,7 +350,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
         match item.node {
             hir::ForeignItemFn(ref decl, _, ref generics) => {
-                self.visit_early_late(item.id, None, decl, generics, |this| {
+                self.visit_early_late(None, decl, generics, |this| {
                     intravisit::walk_foreign_item(this, item);
                 })
             }
@@ -406,7 +401,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
         if let hir::TraitItemKind::Method(ref sig, _) = trait_item.node {
             self.visit_early_late(
-                trait_item.id,
                 Some(self.hir_map.get_parent(trait_item.id)),
                 &sig.decl, &sig.generics,
                 |this| intravisit::walk_trait_item(this, trait_item))
@@ -418,7 +412,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
         if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
             self.visit_early_late(
-                impl_item.id,
                 Some(self.hir_map.get_parent(impl_item.id)),
                 &sig.decl, &sig.generics,
                 |this| intravisit::walk_impl_item(this, impl_item))
@@ -811,18 +804,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
     /// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
     /// ordering is not important there.
     fn visit_early_late<F>(&mut self,
-                           fn_id: ast::NodeId,
                            parent_id: Option<ast::NodeId>,
                            decl: &'tcx hir::FnDecl,
                            generics: &'tcx hir::Generics,
                            walk: F) where
         F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>),
     {
-        let fn_def_id = self.hir_map.local_def_id(fn_id);
-        insert_late_bound_lifetimes(self.map,
-                                    fn_def_id,
-                                    decl,
-                                    generics);
+        insert_late_bound_lifetimes(self.map, decl, generics);
 
         // Find the start of nested early scopes, e.g. in methods.
         let mut index = 0;
@@ -1549,7 +1537,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
 /// not amongst the inputs to a projection.  In other words, `<&'a
 /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`.
 fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
-                               fn_def_id: DefId,
                                decl: &hir::FnDecl,
                                generics: &hir::Generics) {
     debug!("insert_late_bound_lifetimes(decl={:?}, generics={:?})", decl, generics);
@@ -1607,22 +1594,9 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
         // any `impl Trait` in the return type? early-bound.
         if appears_in_output.impl_trait { continue; }
 
-        // does not appear in the inputs, but appears in the return
-        // type? eventually this will be early-bound, but for now we
-        // just mark it so we can issue warnings.
-        let constrained_by_input = constrained_by_input.regions.contains(&name);
-        let appears_in_output = appears_in_output.regions.contains(&name);
-        if !constrained_by_input && appears_in_output {
-            debug!("inserting issue_32330 entry for {:?}, {:?} on {:?}",
-                   lifetime.lifetime.id,
-                   name,
-                   fn_def_id);
-            map.issue_32330.insert(
-                lifetime.lifetime.id,
-                ty::Issue32330 {
-                    fn_def_id,
-                    region_name: name,
-                });
+        // does not appear in the inputs, but appears in the return type? early-bound.
+        if !constrained_by_input.regions.contains(&name) &&
+            appears_in_output.regions.contains(&name) {
             continue;
         }
 
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index b5284852747..cae1eba5797 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -479,9 +479,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
 
     let obligation = Obligation::with_depth(cause.clone(), depth, param_env, projection_ty);
     match project_type(selcx, &obligation) {
-        Ok(ProjectedTy::Progress(Progress { ty: projected_ty,
-                                            mut obligations,
-                                            cacheable })) => {
+        Ok(ProjectedTy::Progress(Progress { ty: projected_ty, mut obligations })) => {
             // if projection succeeded, then what we get out of this
             // is also non-normalized (consider: it was derived from
             // an impl, where-clause etc) and hence we must
@@ -490,12 +488,10 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
             debug!("opt_normalize_projection_type: \
                     projected_ty={:?} \
                     depth={} \
-                    obligations={:?} \
-                    cacheable={:?}",
+                    obligations={:?}",
                    projected_ty,
                    depth,
-                   obligations,
-                   cacheable);
+                   obligations);
 
             let result = if projected_ty.has_projection_types() {
                 let mut normalizer = AssociatedTypeNormalizer::new(selcx,
@@ -520,8 +516,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
                     obligations,
                 }
             };
-            infcx.projection_cache.borrow_mut()
-                                  .complete(projection_ty, &result, cacheable);
+            infcx.projection_cache.borrow_mut().complete(projection_ty, &result);
             Some(result)
         }
         Ok(ProjectedTy::NoProgress(projected_ty)) => {
@@ -532,8 +527,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
                 value: projected_ty,
                 obligations: vec![]
             };
-            infcx.projection_cache.borrow_mut()
-                                  .complete(projection_ty, &result, true);
+            infcx.projection_cache.borrow_mut().complete(projection_ty, &result);
             Some(result)
         }
         Err(ProjectionTyError::TooManyCandidates) => {
@@ -606,7 +600,6 @@ enum ProjectedTy<'tcx> {
 struct Progress<'tcx> {
     ty: Ty<'tcx>,
     obligations: Vec<PredicateObligation<'tcx>>,
-    cacheable: bool,
 }
 
 impl<'tcx> Progress<'tcx> {
@@ -614,7 +607,6 @@ impl<'tcx> Progress<'tcx> {
         Progress {
             ty: tcx.types.err,
             obligations: vec![],
-            cacheable: true
         }
     }
 
@@ -1228,7 +1220,6 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
             Progress {
                 ty: ty_match.value,
                 obligations,
-                cacheable: ty_match.unconstrained_regions.is_empty(),
             }
         }
         Err(e) => {
@@ -1272,7 +1263,6 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
     Progress {
         ty: ty.subst(tcx, substs),
         obligations: nested,
-        cacheable: true
     }
 }
 
@@ -1380,22 +1370,11 @@ impl<'tcx> ProjectionCache<'tcx> {
         Ok(())
     }
 
-    /// Indicates that `key` was normalized to `value`. If `cacheable` is false,
-    /// then this result is sadly not cacheable.
-    fn complete(&mut self,
-                key: ty::ProjectionTy<'tcx>,
-                value: &NormalizedTy<'tcx>,
-                cacheable: bool) {
-        let fresh_key = if cacheable {
-            debug!("ProjectionCacheEntry::complete: adding cache entry: key={:?}, value={:?}",
-                   key, value);
-            self.map.insert(key, ProjectionCacheEntry::NormalizedTy(value.value))
-        } else {
-            debug!("ProjectionCacheEntry::complete: cannot cache: key={:?}, value={:?}",
-                   key, value);
-            !self.map.remove(key)
-        };
-
+    /// Indicates that `key` was normalized to `value`.
+    fn complete(&mut self, key: ty::ProjectionTy<'tcx>, value: &NormalizedTy<'tcx>) {
+        debug!("ProjectionCacheEntry::complete: adding cache entry: key={:?}, value={:?}",
+               key, value);
+        let fresh_key = self.map.insert(key, ProjectionCacheEntry::NormalizedTy(value.value));
         assert!(!fresh_key, "never started projecting `{:?}`", key);
     }
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 3442cf0ef69..86a4f669189 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -39,8 +39,8 @@ pub enum TypeError<'tcx> {
     RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
     RegionsNotSame(Region<'tcx>, Region<'tcx>),
     RegionsNoOverlap(Region<'tcx>, Region<'tcx>),
-    RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>, Option<Box<ty::Issue32330>>),
-    RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>, Option<Box<ty::Issue32330>>),
+    RegionsInsufficientlyPolymorphic(BoundRegion, Region<'tcx>),
+    RegionsOverlyPolymorphic(BoundRegion, Region<'tcx>),
     Sorts(ExpectedFound<Ty<'tcx>>),
     IntMismatch(ExpectedFound<ty::IntVarValue>),
     FloatMismatch(ExpectedFound<ast::FloatTy>),
@@ -116,13 +116,13 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             RegionsNoOverlap(..) => {
                 write!(f, "lifetimes do not intersect")
             }
-            RegionsInsufficientlyPolymorphic(br, _, _) => {
+            RegionsInsufficientlyPolymorphic(br, _) => {
                 write!(f,
                        "expected bound lifetime parameter{}{}, found concrete lifetime",
                        if br.is_named() { " " } else { "" },
                        br)
             }
-            RegionsOverlyPolymorphic(br, _, _) => {
+            RegionsOverlyPolymorphic(br, _) => {
                 write!(f,
                        "expected concrete lifetime, found bound lifetime parameter{}{}",
                        if br.is_named() { " " } else { "" },
@@ -257,15 +257,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 self.note_and_explain_region(db, "...does not overlap ",
                                            region2, "");
             }
-            RegionsInsufficientlyPolymorphic(_, conc_region, _) => {
+            RegionsInsufficientlyPolymorphic(_, conc_region) => {
                 self.note_and_explain_region(db, "concrete lifetime that was found is ",
                                            conc_region, "");
             }
-            RegionsOverlyPolymorphic(_, &ty::ReVar(_), _) => {
+            RegionsOverlyPolymorphic(_, &ty::ReVar(_)) => {
                 // don't bother to print out the message below for
                 // inference variables, it's not very illuminating.
             }
-            RegionsOverlyPolymorphic(_, conc_region, _) => {
+            RegionsOverlyPolymorphic(_, conc_region) => {
                 self.note_and_explain_region(db, "expected concrete lifetime is ",
                                            conc_region, "");
             }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 804f47b5283..2ee7149fc13 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -67,7 +67,6 @@ pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
 pub use self::sty::{ExistentialProjection, PolyExistentialProjection};
 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
 pub use self::sty::RegionKind;
-pub use self::sty::Issue32330;
 pub use self::sty::{TyVid, IntVid, FloatVid, RegionVid, SkolemizedRegionVid};
 pub use self::sty::BoundRegion::*;
 pub use self::sty::InferTy::*;
@@ -676,7 +675,6 @@ pub struct RegionParameterDef {
     pub name: Name,
     pub def_id: DefId,
     pub index: u32,
-    pub issue_32330: Option<ty::Issue32330>,
 
     /// `pure_wrt_drop`, set by the (unsafe) `#[may_dangle]` attribute
     /// on generic parameter `'a`, asserts data of lifetime `'a`
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index f261a56cdcc..48ace804995 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -346,13 +346,11 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             RegionsNoOverlap(a, b) => {
                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
             }
-            RegionsInsufficientlyPolymorphic(a, b, ref c) => {
-                let c = c.clone();
-                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b, c))
+            RegionsInsufficientlyPolymorphic(a, b) => {
+                return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
             }
-            RegionsOverlyPolymorphic(a, b, ref c) => {
-                let c = c.clone();
-                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b, c))
+            RegionsOverlyPolymorphic(a, b) => {
+                return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
             }
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
@@ -1004,13 +1002,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
             RegionsNoOverlap(a, b) => {
                 RegionsNoOverlap(a.fold_with(folder), b.fold_with(folder))
             },
-            RegionsInsufficientlyPolymorphic(a, b, ref c) => {
-                let c = c.clone();
-                RegionsInsufficientlyPolymorphic(a, b.fold_with(folder), c)
+            RegionsInsufficientlyPolymorphic(a, b) => {
+                RegionsInsufficientlyPolymorphic(a, b.fold_with(folder))
             },
-            RegionsOverlyPolymorphic(a, b, ref c) => {
-                let c = c.clone();
-                RegionsOverlyPolymorphic(a, b.fold_with(folder), c)
+            RegionsOverlyPolymorphic(a, b) => {
+                RegionsOverlyPolymorphic(a, b.fold_with(folder))
             },
             IntMismatch(x) => IntMismatch(x),
             FloatMismatch(x) => FloatMismatch(x),
@@ -1036,8 +1032,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
             RegionsNoOverlap(a, b) => {
                 a.visit_with(visitor) || b.visit_with(visitor)
             },
-            RegionsInsufficientlyPolymorphic(_, b, _) |
-            RegionsOverlyPolymorphic(_, b, _) => {
+            RegionsInsufficientlyPolymorphic(_, b) |
+            RegionsOverlyPolymorphic(_, b) => {
                 b.visit_with(visitor)
             },
             Sorts(x) => x.visit_with(visitor),
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 5f89714b33f..b42180b288b 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -77,20 +77,6 @@ impl BoundRegion {
     }
 }
 
-/// When a region changed from late-bound to early-bound when #32330
-/// was fixed, its `RegionParameterDef` will have one of these
-/// structures that we can use to give nicer errors.
-#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash,
-         RustcEncodable, RustcDecodable)]
-pub struct Issue32330 {
-    /// fn where is region declared
-    pub fn_def_id: DefId,
-
-    /// name of region; duplicates the info in BrNamed but convenient
-    /// to have it here, and this code is only temporary
-    pub region_name: ast::Name,
-}
-
 /// NB: If you change this, you'll probably want to change the corresponding
 /// AST structure in libsyntax/ast.rs as well.
 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index bb6e478738a..1ec850ad7f3 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1110,46 +1110,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
             }
             hir::TyBareFn(ref bf) => {
                 require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
-                let bare_fn_ty = self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl);
-
-                // Find any late-bound regions declared in return type that do
-                // not appear in the arguments. These are not wellformed.
-                //
-                // Example:
-                //
-                //     for<'a> fn() -> &'a str <-- 'a is bad
-                //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
-                //
-                // Note that we do this check **here** and not in
-                // `ty_of_bare_fn` because the latter is also used to make
-                // the types for fn items, and we do not want to issue a
-                // warning then. (Once we fix #32330, the regions we are
-                // checking for here would be considered early bound
-                // anyway.)
-                let inputs = bare_fn_ty.inputs();
-                let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
-                    &inputs.map_bound(|i| i.to_owned()));
-                let output = bare_fn_ty.output();
-                let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
-                for br in late_bound_in_ret.difference(&late_bound_in_args) {
-                    let br_name = match *br {
-                        ty::BrNamed(_, name) => name,
-                        _ => {
-                            span_bug!(
-                                bf.decl.output.span(),
-                                "anonymous bound region {:?} in return but not args",
-                                br);
-                        }
-                    };
-                    struct_span_err!(tcx.sess,
-                                     ast_ty.span,
-                                     E0581,
-                                     "return type references lifetime `{}`, \
-                                      which does not appear in the fn input types",
-                                     br_name)
-                        .emit();
-                }
-                tcx.mk_fn_ptr(bare_fn_ty)
+                tcx.mk_fn_ptr(self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl))
             }
             hir::TyTraitObject(ref bounds, ref lifetime) => {
                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
@@ -1269,23 +1230,56 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                     -> ty::PolyFnSig<'tcx> {
         debug!("ty_of_fn");
 
+        let tcx = self.tcx();
         let input_tys: Vec<Ty> =
             decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect();
 
         let output_ty = match decl.output {
             hir::Return(ref output) => self.ast_ty_to_ty(output),
-            hir::DefaultReturn(..) => self.tcx().mk_nil(),
+            hir::DefaultReturn(..) => tcx.mk_nil(),
         };
 
         debug!("ty_of_fn: output_ty={:?}", output_ty);
 
-        ty::Binder(self.tcx().mk_fn_sig(
+        let bare_fn_ty = ty::Binder(tcx.mk_fn_sig(
             input_tys.into_iter(),
             output_ty,
             decl.variadic,
             unsafety,
             abi
-        ))
+        ));
+
+        // Find any late-bound regions declared in return type that do
+        // not appear in the arguments. These are not wellformed.
+        //
+        // Example:
+        //     for<'a> fn() -> &'a str <-- 'a is bad
+        //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
+        let inputs = bare_fn_ty.inputs();
+        let late_bound_in_args = tcx.collect_constrained_late_bound_regions(
+            &inputs.map_bound(|i| i.to_owned()));
+        let output = bare_fn_ty.output();
+        let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
+        for br in late_bound_in_ret.difference(&late_bound_in_args) {
+            let br_name = match *br {
+                ty::BrNamed(_, name) => name,
+                _ => {
+                    span_bug!(
+                        decl.output.span(),
+                        "anonymous bound region {:?} in return but not args",
+                        br);
+                }
+            };
+            struct_span_err!(tcx.sess,
+                             decl.output.span(),
+                             E0581,
+                             "return type references lifetime `{}`, \
+                             which does not appear in the fn input types",
+                             br_name)
+                .emit();
+        }
+
+        bare_fn_ty
     }
 
     pub fn ty_of_closure(&self,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 7f69885047b..cb22dcc21de 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1607,7 +1607,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
     fn re_infer(&self, span: Span, def: Option<&ty::RegionParameterDef>)
                 -> Option<ty::Region<'tcx>> {
         let v = match def {
-            Some(def) => infer::EarlyBoundRegion(span, def.name, def.issue_32330),
+            Some(def) => infer::EarlyBoundRegion(span, def.name),
             None => infer::MiscVariable(span)
         };
         Some(self.next_region_var(v))
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 8780131bbcc..f25a6cf58a7 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -979,13 +979,11 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics);
     let regions = early_lifetimes.enumerate().map(|(i, l)| {
-        let issue_32330 = tcx.named_region_map.issue_32330.get(&l.lifetime.id).cloned();
         ty::RegionParameterDef {
             name: l.lifetime.name,
             index: own_start + i as u32,
             def_id: tcx.hir.local_def_id(l.lifetime.id),
             pure_wrt_drop: l.pure_wrt_drop,
-            issue_32330: issue_32330,
         }
     }).collect::<Vec<_>>();
 
diff --git a/src/test/compile-fail/associated-types/cache/project-fn-ret-contravariant.rs b/src/test/compile-fail/associated-types/cache/project-fn-ret-contravariant.rs
index c5557cee7cc..0e822aff01e 100644
--- a/src/test/compile-fail/associated-types/cache/project-fn-ret-contravariant.rs
+++ b/src/test/compile-fail/associated-types/cache/project-fn-ret-contravariant.rs
@@ -43,23 +43,19 @@ fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
     (a, b)
 }
 
-// FIXME(#32330)
-//#[cfg(transmute)] // one instantiations: BAD
-//fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
-//    bar(foo, x) //[transmute] ERROR E0495
-//}
+#[cfg(transmute)] // one instantiations: BAD
+fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+   bar(foo, x) //[transmute]~ ERROR E0495
+}
 
-// FIXME(#32330)
-//#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
-//fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
-//    let a = bar(foo, y); //[krisskross] ERROR E0495
-//    let b = bar(foo, x); //[krisskross] ERROR E0495
-//    (a, b)
-//}
+#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
+fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+   let a = bar(foo, y); //[krisskross]~ ERROR E0495
+   let b = bar(foo, x); //[krisskross]~ ERROR E0495
+   (a, b)
+}
 
 #[rustc_error]
 fn main() { }
 //[ok]~^ ERROR compilation successful
 //[oneuse]~^^ ERROR compilation successful
-//[transmute]~^^^ ERROR compilation successful
-//[krisskross]~^^^^ ERROR compilation successful
diff --git a/src/test/compile-fail/associated-types/cache/project-fn-ret-invariant.rs b/src/test/compile-fail/associated-types/cache/project-fn-ret-invariant.rs
index a15422e42d9..10fe612980d 100644
--- a/src/test/compile-fail/associated-types/cache/project-fn-ret-invariant.rs
+++ b/src/test/compile-fail/associated-types/cache/project-fn-ret-invariant.rs
@@ -42,35 +42,29 @@ fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
     (a, b)
 }
 
-// FIXME(#32330)
-//#[cfg(oneuse)] // one instantiation: BAD
-//fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-//    let f = foo; // <-- No consistent type can be inferred for `f` here.
-//    let a = bar(f, x); //[oneuse] ERROR E0495
-//    let b = bar(f, y);
-//    (a, b)
-//}
+#[cfg(oneuse)] // one instantiation: BAD
+fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+   let f = foo; // <-- No consistent type can be inferred for `f` here.
+   let a = bar(f, x); //[oneuse]~^ ERROR E0495
+   let b = bar(f, y);
+   (a, b)
+}
 
-// FIXME(#32330)
-//#[cfg(transmute)] // one instantiations: BAD
-//fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
-//    // Cannot instantiate `foo` with any lifetime other than `'a`,
-//    // since it is provided as input.
-//
-//    bar(foo, x) //[transmute] ERROR E0495
-//}
+#[cfg(transmute)] // one instantiations: BAD
+fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
+   // Cannot instantiate `foo` with any lifetime other than `'a`,
+   // since it is provided as input.
 
-// FIXME(#32330)
-//#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
-//fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
-//    let a = bar(foo, y); //[krisskross] ERROR E0495
-//    let b = bar(foo, x); //[krisskross] ERROR E0495
-//    (a, b)
-//}
+   bar(foo, x) //[transmute]~ ERROR E0495
+}
+
+#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
+fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+   let a = bar(foo, y); //[krisskross]~ ERROR E0495
+   let b = bar(foo, x); //[krisskross]~ ERROR E0495
+   (a, b)
+}
 
 #[rustc_error]
 fn main() { }
 //[ok]~^ ERROR compilation successful
-//[oneuse]~^^ ERROR compilation successful
-//[transmute]~^^^ ERROR compilation successful
-//[krisskross]~^^^^ ERROR compilation successful
diff --git a/src/test/compile-fail/hr-subtype.rs b/src/test/compile-fail/hr-subtype.rs
index 95e469ebcfd..c88d74d53ce 100644
--- a/src/test/compile-fail/hr-subtype.rs
+++ b/src/test/compile-fail/hr-subtype.rs
@@ -91,9 +91,6 @@ check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
 // - if we are covariant, then 'a and 'b can be set to the call-site
 //   intersection;
 // - if we are contravariant, then 'a can be inferred to 'static.
-//
-// FIXME(#32330) this is true, but we are not currently impl'ing this
-// full semantics
 check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32),
                                 for<'a>    fn(&'a u32, &'a u32)) }
 check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>),
diff --git a/src/test/ui/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions-fn-subtyping-return-static.stderr
index 0c7b44af949..1598a8a40d2 100644
--- a/src/test/ui/regions-fn-subtyping-return-static.stderr
+++ b/src/test/ui/regions-fn-subtyping-return-static.stderr
@@ -6,8 +6,6 @@ error[E0308]: mismatched types
    |
    = note: expected type `fn(&'cx S) -> &'cx S`
               found type `fn(&'a S) -> &S {bar::<'_>}`
-   = note: lifetime parameter `'b` declared on fn `bar` appears only in the return type, but here is required to be higher-ranked, which means that `'b` must appear in both argument and return types
-   = note: this error is the result of a recent bug fix; for more information, see issue #33685 <https://github.com/rust-lang/rust/issues/33685>
 
 error: aborting due to previous error