trait_ref.self_ty()));
}
+ self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
+
// Try to report a help message
if !trait_ref.has_infer_types() &&
self.predicate_can_apply(obligation.param_env, trait_ref) {
violations)
}
- ty::Predicate::ClosureKind(closure_def_id, kind) => {
- let found_kind = self.closure_kind(closure_def_id).unwrap();
+ ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
+ let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap();
let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap();
let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
let mut err = struct_span_err!(
if let Some(tables) = self.in_progress_tables {
let tables = tables.borrow();
let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id);
- match tables.closure_kinds().get(closure_hir_id) {
- Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => {
- err.span_note(span, &format!(
+ match (found_kind, tables.closure_kind_origins().get(closure_hir_id)) {
+ (ty::ClosureKind::FnOnce, Some((span, name))) => {
+ err.span_note(*span, &format!(
"closure is `FnOnce` because it moves the \
variable `{}` out of its environment", name));
},
- Some(&(ty::ClosureKind::FnMut, Some((span, name)))) => {
- err.span_note(span, &format!(
+ (ty::ClosureKind::FnMut, Some((span, name))) => {
+ err.span_note(*span, &format!(
"closure is `FnMut` because it mutates the \
variable `{}` here", name));
},
err.emit();
}
+ /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
+ /// suggestion to borrow the initializer in order to use have a slice instead.
+ fn suggest_borrow_on_unsized_slice(&self,
+ code: &ObligationCauseCode<'tcx>,
+ err: &mut DiagnosticBuilder<'tcx>) {
+ if let &ObligationCauseCode::VariableType(node_id) = code {
+ let parent_node = self.tcx.hir.get_parent_node(node_id);
+ if let Some(hir::map::NodeLocal(ref local)) = self.tcx.hir.find(parent_node) {
+ if let Some(ref expr) = local.init {
+ if let hir::ExprIndex(_, _) = expr.node {
+ if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
+ err.span_suggestion(expr.span,
+ "consider a slice instead",
+ format!("&{}", snippet));
+ }
+ }
+ }
+ }
+ }
+ }
+
fn report_arg_count_mismatch(
&self,
span: Span,