]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/infer/error_reporting/need_type_info.rs
Rollup merge of #61273 - RalfJung:maybe-uninit, r=Centril
[rust.git] / src / librustc / infer / error_reporting / need_type_info.rs
index 9e0e48e474118fd14730ee363d1f804427b4b026..972ffbe1820a5569ee59ae336b4f89652e4dcce2 100644 (file)
@@ -1,15 +1,17 @@
+use crate::hir::def::Namespace;
 use crate::hir::{self, Local, Pat, Body, HirId};
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use crate::infer::InferCtxt;
 use crate::infer::type_variable::TypeVariableOrigin;
 use crate::ty::{self, Ty, Infer, TyVar};
+use crate::ty::print::Print;
 use syntax::source_map::CompilerDesugaringKind;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
 
 struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
-    target_ty: &'a Ty<'tcx>,
+    target_ty: Ty<'tcx>,
     hir_map: &'a hir::map::Map<'gcx>,
     found_local_pattern: Option<&'gcx Pat>,
     found_arg_pattern: Option<&'gcx Pat>,
@@ -22,9 +24,9 @@ fn node_matches_type(&mut self, hir_id: HirId) -> bool {
         });
         match ty_opt {
             Some(ty) => {
-                let ty = self.infcx.resolve_type_vars_if_possible(&ty);
+                let ty = self.infcx.resolve_vars_if_possible(&ty);
                 ty.walk().any(|inner_ty| {
-                    inner_ty == *self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
+                    inner_ty == self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
                         (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
                             self.infcx
                                 .type_variables
@@ -64,41 +66,43 @@ fn visit_body(&mut self, body: &'gcx Body) {
 
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
-        if let ty::Infer(ty::TyVar(ty_vid)) = (*ty).sty {
+    pub fn extract_type_name(
+        &self,
+        ty: Ty<'tcx>,
+        highlight: Option<ty::print::RegionHighlightMode>,
+    ) -> String {
+        if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
             let ty_vars = self.type_variables.borrow();
             if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
                 *ty_vars.var_origin(ty_vid) {
-                name.to_string()
-            } else {
-                ty.to_string()
+                return name.to_string();
             }
-        } else {
-            ty.to_string()
         }
+
+        let mut s = String::new();
+        let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
+        if let Some(highlight) = highlight {
+            printer.region_highlight_mode = highlight;
+        }
+        let _ = ty.print(printer);
+        s
     }
 
-    pub fn need_type_info_err(&self,
-                            body_id: Option<hir::BodyId>,
-                            span: Span,
-                            ty: Ty<'tcx>)
-                            -> DiagnosticBuilder<'gcx> {
-        let ty = self.resolve_type_vars_if_possible(&ty);
-        let name = self.extract_type_name(&ty);
+    pub fn need_type_info_err(
+        &self,
+        body_id: Option<hir::BodyId>,
+        span: Span,
+        ty: Ty<'tcx>
+    ) -> DiagnosticBuilder<'gcx> {
+        let ty = self.resolve_vars_if_possible(&ty);
+        let name = self.extract_type_name(&ty, None);
 
         let mut err_span = span;
-        let mut labels = vec![(
-            span,
-            if &name == "_" {
-                "cannot infer type".to_owned()
-            } else {
-                format!("cannot infer type for `{}`", name)
-            },
-        )];
+        let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))];
 
         let mut local_visitor = FindLocalByTypeVisitor {
             infcx: &self,
-            target_ty: &ty,
+            target_ty: ty,
             hir_map: &self.tcx.hir(),
             found_local_pattern: None,
             found_arg_pattern: None,
@@ -156,4 +160,28 @@ pub fn need_type_info_err(&self,
 
         err
     }
+
+    pub fn need_type_info_err_in_generator(
+        &self,
+        span: Span,
+        ty: Ty<'tcx>
+    ) -> DiagnosticBuilder<'gcx> {
+        let ty = self.resolve_vars_if_possible(&ty);
+        let name = self.extract_type_name(&ty, None);
+
+        let mut err = struct_span_err!(self.tcx.sess,
+                       span,
+                       E0698,
+                       "type inside generator must be known in this context");
+        err.span_label(span, InferCtxt::missing_type_msg(&name));
+        err
+    }
+
+    fn missing_type_msg(type_name: &str) -> String {
+        if type_name == "_" {
+            "cannot infer type".to_owned()
+        } else {
+            format!("cannot infer type for `{}`", type_name)
+        }
+    }
 }