+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>,
});
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
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,
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)
+ }
+ }
}