diff options
| -rw-r--r-- | src/librustc/ty/context.rs | 16 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 35 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs | 7 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/diagnostics/region_errors.rs | 16 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/universal_regions.rs | 23 |
5 files changed, 83 insertions, 14 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index e59738d8886..fd2f58d24f8 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -209,7 +209,7 @@ fn validate_hir_id_for_typeck_tables( ty::tls::with(|tcx| { bug!( "node {} with HirId::owner {:?} cannot be placed in \ - TypeckTables with local_id_root {:?}", + TypeckTables with local_id_root {:?}", tcx.hir().node_to_string(hir_id), DefId::local(hir_id.owner), local_id_root @@ -1512,6 +1512,20 @@ impl<'tcx> TyCtxt<'tcx> { .subst(*self, self.mk_substs([self.lifetimes.re_static.into()].iter())), ) } + + /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "closure")`). + pub fn article_and_description( + &self, + def_id: crate::hir::def_id::DefId, + ) -> (&'static str, &'static str) { + self.def_kind(def_id).map_or_else( + || { + // TODO: is it a problem to try to use the ty here? + self.type_of(def_id).kind.article_and_description() + }, + |def_kind| (def_kind.article(), def_kind.descr(def_id)), + ) + } } impl<'tcx> GlobalCtxt<'tcx> { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index c3698f402a9..a54bf4d7eff 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -254,6 +254,41 @@ pub enum TyKind<'tcx> { Error, } +impl<'tcx> TyKind<'tcx> { + pub fn article_and_description(&self) -> (&'static str, &'static str) { + match *self { + Bool => ("a", "boolean value"), + Char => ("a", "character"), + Int(..) => ("a", "signed interger"), + Uint(..) => ("an", "unsigned integer"), + Float(..) => ("a", "floating point number"), + Adt(..) => ("an", "abstract data type"), + Foreign(..) => ("a", "foreign type"), + Str => ("a", "string slice"), + Array(..) => ("an", "array"), + Slice(..) => ("a", "slice"), + RawPtr(..) => ("a", "raw pointer"), + Ref(..) => ("a", "reference"), + FnDef(..) => ("a", "function"), + FnPtr(..) => ("a", "function pointer"), + Dynamic(..) => ("a", "trait object"), + Closure(..) => ("a", "closure"), + Generator(..) => ("a", "generator"), + GeneratorWitness(..) => ("a", "generator witness"), + Never => ("a", "never"), + Tuple(..) => ("a", "tuple"), + Projection(..) => ("a", "projection"), + UnnormalizedProjection(..) => ("an", "unnormalized projection"), + Opaque(..) => ("an", "opaque type"), + Param(..) => ("a", "type parameter"), + Bound(..) => ("a", "bound type variable"), + Placeholder(..) => ("a", "universally quantified higher-ranked type"), + Infer(..) => ("an", "inference variable"), + Error => ("a", "type error"), + } + } +} + // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(target_arch = "x86_64")] static_assert_size!(TyKind<'_>, 24); diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 0ed7dd03f3a..41a99d1125b 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1257,7 +1257,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } _ => bug!( "report_escaping_closure_capture called with unexpected constraint \ - category: `{:?}`", + category: `{:?}`", category ), }; @@ -1279,8 +1279,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tables = tcx.typeck_tables_of(self.mir_def_id); let mir_hir_id = tcx.hir().def_index_to_hir_id(self.mir_def_id.index); match tables.node_type(mir_hir_id).kind { - ty::Closure(..) => "closure", - ty::Generator(..) => "generator", + ref kind @ ty::Closure(..) | ref kind @ ty::Generator(..) => { + kind.article_and_description().1 + } _ => bug!("Closure body doesn't have a closure or generator type"), } } else { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index a3e0e51c5b6..0f0fd64844a 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -427,18 +427,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let escapes_from = match self.regioncx.universal_regions().defining_ty { - DefiningTy::Closure(..) => "closure", - DefiningTy::Generator(..) => "generator", - DefiningTy::FnDef(..) => "function", - DefiningTy::Const(..) => "const", - }; + let (_, escapes_from) = + self.infcx.tcx.article_and_description(self.universal_regions.defining_ty.def_id()); // Revert to the normal error in these cases. // Assignments aren't "escapes" in function items. if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none()) - || (*category == ConstraintCategory::Assignment && escapes_from == "function") - || escapes_from == "const" + || (*category == ConstraintCategory::Assignment + && self.universal_regions.defining_ty.is_fn_def()) + || self.universal_regions.defining_ty.is_closure() { return self.report_general_error(&ErrorConstraintInfo { fr_is_local: true, @@ -504,8 +501,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mut diag = self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); - let mir_def_name = - if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" }; + let (_, mir_def_name) = self.infcx.tcx.article_and_description(self.mir_def_id); let fr_name = self.give_region_a_name(*fr).unwrap(); fr_name.highlight_region_name(&mut diag); diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs index 0913de63e8e..777eea22eb6 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/src/librustc_mir/borrow_check/universal_regions.rs @@ -131,6 +131,29 @@ impl<'tcx> DefiningTy<'tcx> { DefiningTy::FnDef(..) | DefiningTy::Const(..) => 0, } } + + pub fn is_closure(&self) -> bool { + match *self { + DefiningTy::Closure(..) => true, + _ => false, + } + } + + pub fn is_fn_def(&self) -> bool { + match *self { + DefiningTy::FnDef(..) => true, + _ => false, + } + } + + pub fn def_id(&self) -> DefId { + match *self { + DefiningTy::Closure(def_id, ..) => def_id, + DefiningTy::Generator(def_id, ..) => def_id, + DefiningTy::FnDef(def_id, ..) => def_id, + DefiningTy::Const(def_id, ..) => def_id, + } + } } #[derive(Debug)] |
