diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/closure.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs | 142 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 12 |
3 files changed, 86 insertions, 70 deletions
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index b19fb6da6de..e426b937542 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let inferred_sig = self.normalize( span, self.deduce_sig_from_projection( - Some(span), + Some(span), bound_predicate.rebind(proj_predicate), ), ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f50aeaf4511..5be67a4b14e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -20,10 +20,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { else { return false; }; - let hir = self.tcx.hir(); - let hir::Node::Expr(expr) = hir.get(hir_id) else { - return false; - }; let Some(unsubstituted_pred) = self .tcx @@ -69,15 +65,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Account for enum variant constructors, where the type param corresponds to the enum // itself. - let enum_def_id = if let hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _) = - self.tcx.def_kind(def_id) - { - // `def_id` corresponds to a constructor, and its parent is the variant, and we want - // the enum. - Some(self.tcx.parent(self.tcx.parent(def_id))) - } else { - None - }; + let enum_def_id = + if let DefKind::Ctor(hir::def::CtorOf::Variant, _) = self.tcx.def_kind(def_id) { + // `def_id` corresponds to a constructor, and its parent is the variant, and we want + // the enum. + Some(self.tcx.parent(self.tcx.parent(def_id))) + } else { + None + }; let variant_param_to_point_at = find_param_matching(&|param_term| { // FIXME: It would be nice to make this not use string manipulation, // but it's pretty hard to do this, since `ty::ParamTy` is missing @@ -90,11 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Account for enum variant constructors, where the type param corresponds to the enum // itself. - let def_id = if let Some(def_id) = enum_def_id { - def_id - } else { - def_id - }; + let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id }; self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id && include }); @@ -127,68 +118,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate); } - if self.closure_span_overlaps_error(error, expr.span) { - return false; - } - - match &expr.kind { - hir::ExprKind::Path(qpath) => { - let def_id = if let Some(def_id) = enum_def_id { - def_id - } else { - def_id - }; - if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind { - for segment in path.segments { - if let Some(param) = variant_param_to_point_at - && self.point_at_generic_if_possible(error, def_id, param, segment) - { - return true; - } - } + let hir = self.tcx.hir(); + let (expr, qpath) = match hir.get(hir_id) { + hir::Node::Expr(expr) => { + if self.closure_span_overlaps_error(error, expr.span) { + return false; } - if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Call(callee, args), - hir_id: call_hir_id, - span: call_span, - .. - }) = hir.get_parent(expr.hir_id) - && callee.hir_id == expr.hir_id - { - if self.closure_span_overlaps_error(error, *call_span) { - return false; - } + let qpath = + if let hir::ExprKind::Path(qpath) = expr.kind { Some(qpath) } else { None }; - for param in - [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] - .into_iter() - .flatten() + (Some(*expr), qpath) + } + hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => (None, Some(*qpath)), + _ => return false, + }; + + if let Some(qpath) = qpath { + let def_id = if let Some(def_id) = enum_def_id { def_id } else { def_id }; + if let hir::QPath::Resolved(None, path) = qpath { + for segment in path.segments { + if let Some(param) = variant_param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param, segment) { - if self.blame_specific_arg_if_possible( - error, - def_id, - param, - *call_hir_id, - callee.span, - None, - args, - ) - { - return true; - } + return true; } } + } + if let hir::QPath::TypeRelative(_ty, segment) = qpath { + if let Some(param) = variant_param_to_point_at + && self.point_at_generic_if_possible(error, def_id, param, segment) + { + return true; + } + } + if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Call(callee, args), + hir_id: call_hir_id, + span: call_span, + .. + }) = hir.get_parent(hir_id) + && callee.hir_id == hir_id + { + if self.closure_span_overlaps_error(error, *call_span) { + return false; + } - for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + for param in + [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() .flatten() { - if self.point_at_path_if_possible(error, def_id, param, qpath) { + if self.blame_specific_arg_if_possible( + error, + def_id, + param, + *call_hir_id, + callee.span, + None, + args, + ) + { return true; } } } - hir::ExprKind::MethodCall(segment, receiver, args, ..) => { + + for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] + .into_iter() + .flatten() + { + if self.point_at_path_if_possible(error, def_id, param, &qpath) { + return true; + } + } + } + + match expr.map(|e| e.kind) { + Some(hir::ExprKind::MethodCall(segment, receiver, args, ..)) => { for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at] .into_iter() .flatten() @@ -220,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return true; } } - hir::ExprKind::Struct(qpath, fields, ..) => { + Some(hir::ExprKind::Struct(qpath, fields, ..)) => { if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) = self.typeck_results.borrow().qpath_res(qpath, hir_id) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 6a82b00211e..45bf43efa83 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -317,7 +317,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) { // FIXME: normalization and escaping regions - let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty }; + let ty = if !ty.has_escaping_bound_vars() { + if let ty::Alias(ty::AliasKind::Projection, ty::AliasTy { args, def_id, .. }) = + ty.kind() + { + self.add_required_obligations_for_hir(span, *def_id, args, hir_id); + self.select_obligations_where_possible(|_| {}); + } + self.normalize(span, ty) + } else { + ty + }; self.write_ty(hir_id, ty) } |
