]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Rollup merge of #93497 - willcrichton:rustdoc-scrape-test, r=GuillaumeGomez
[rust.git] / compiler / rustc_typeck / src / check / fn_ctxt / checks.rs
1 use crate::astconv::AstConv;
2 use crate::check::coercion::CoerceMany;
3 use crate::check::gather_locals::Declaration;
4 use crate::check::method::MethodCallee;
5 use crate::check::Expectation::*;
6 use crate::check::TupleArgumentsFlag::*;
7 use crate::check::{
8     potentially_plural_count, struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt,
9     LocalTy, Needs, TupleArgumentsFlag,
10 };
11
12 use rustc_ast as ast;
13 use rustc_data_structures::sync::Lrc;
14 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
15 use rustc_hir as hir;
16 use rustc_hir::def::{CtorOf, DefKind, Res};
17 use rustc_hir::def_id::DefId;
18 use rustc_hir::{ExprKind, Node, QPath};
19 use rustc_middle::ty::adjustment::AllowTwoPhase;
20 use rustc_middle::ty::fold::TypeFoldable;
21 use rustc_middle::ty::{self, Ty};
22 use rustc_session::Session;
23 use rustc_span::symbol::Ident;
24 use rustc_span::{self, MultiSpan, Span};
25 use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
26
27 use crate::structured_errors::StructuredDiagnostic;
28 use std::iter;
29 use std::slice;
30
31 struct FnArgsAsTuple<'hir> {
32     first: &'hir hir::Expr<'hir>,
33     last: &'hir hir::Expr<'hir>,
34 }
35
36 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
37     pub(in super::super) fn check_casts(&self) {
38         let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
39         debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
40         for cast in deferred_cast_checks.drain(..) {
41             cast.check(self);
42         }
43     }
44
45     pub(in super::super) fn check_method_argument_types(
46         &self,
47         sp: Span,
48         expr: &'tcx hir::Expr<'tcx>,
49         method: Result<MethodCallee<'tcx>, ()>,
50         args_no_rcvr: &'tcx [hir::Expr<'tcx>],
51         tuple_arguments: TupleArgumentsFlag,
52         expected: Expectation<'tcx>,
53     ) -> Ty<'tcx> {
54         let has_error = match method {
55             Ok(method) => method.substs.references_error() || method.sig.references_error(),
56             Err(_) => true,
57         };
58         if has_error {
59             let err_inputs = self.err_args(args_no_rcvr.len());
60
61             let err_inputs = match tuple_arguments {
62                 DontTupleArguments => err_inputs,
63                 TupleArguments => vec![self.tcx.intern_tup(&err_inputs)],
64             };
65
66             self.check_argument_types(
67                 sp,
68                 expr,
69                 &err_inputs,
70                 vec![],
71                 args_no_rcvr,
72                 false,
73                 tuple_arguments,
74                 None,
75             );
76             return self.tcx.ty_error();
77         }
78
79         let method = method.unwrap();
80         // HACK(eddyb) ignore self in the definition (see above).
81         let expected_input_tys = self.expected_inputs_for_expected_output(
82             sp,
83             expected,
84             method.sig.output(),
85             &method.sig.inputs()[1..],
86         );
87         self.check_argument_types(
88             sp,
89             expr,
90             &method.sig.inputs()[1..],
91             expected_input_tys,
92             args_no_rcvr,
93             method.sig.c_variadic,
94             tuple_arguments,
95             Some(method.def_id),
96         );
97         method.sig.output()
98     }
99
100     /// Generic function that factors out common logic from function calls,
101     /// method calls and overloaded operators.
102     pub(in super::super) fn check_argument_types(
103         &self,
104         // Span enclosing the call site
105         call_span: Span,
106         // Expression of the call site
107         call_expr: &'tcx hir::Expr<'tcx>,
108         // Types (as defined in the *signature* of the target function)
109         formal_input_tys: &[Ty<'tcx>],
110         // More specific expected types, after unifying with caller output types
111         expected_input_tys: Vec<Ty<'tcx>>,
112         // The expressions for each provided argument
113         provided_args: &'tcx [hir::Expr<'tcx>],
114         // Whether the function is variadic, for example when imported from C
115         c_variadic: bool,
116         // Whether the arguments have been bundled in a tuple (ex: closures)
117         tuple_arguments: TupleArgumentsFlag,
118         // The DefId for the function being called, for better error messages
119         fn_def_id: Option<DefId>,
120     ) {
121         let tcx = self.tcx;
122         // Grab the argument types, supplying fresh type variables
123         // if the wrong number of arguments were supplied
124         let supplied_arg_count =
125             if tuple_arguments == DontTupleArguments { provided_args.len() } else { 1 };
126
127         // All the input types from the fn signature must outlive the call
128         // so as to validate implied bounds.
129         for (&fn_input_ty, arg_expr) in iter::zip(formal_input_tys, provided_args) {
130             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
131         }
132
133         let expected_arg_count = formal_input_tys.len();
134
135         // expected_count, arg_count, error_code, sugg_unit, sugg_tuple_wrap_args
136         let mut error: Option<(usize, usize, &str, bool, Option<FnArgsAsTuple<'_>>)> = None;
137
138         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
139         let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
140             let tuple_type = self.structurally_resolved_type(call_span, formal_input_tys[0]);
141             match tuple_type.kind() {
142                 // We expected a tuple and got a tuple
143                 ty::Tuple(arg_types) => {
144                     // Argument length differs
145                     if arg_types.len() != provided_args.len() {
146                         error = Some((arg_types.len(), provided_args.len(), "E0057", false, None));
147                     }
148                     let expected_input_tys = match expected_input_tys.get(0) {
149                         Some(&ty) => match ty.kind() {
150                             ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
151                             _ => vec![],
152                         },
153                         None => vec![],
154                     };
155                     (arg_types.iter().map(|k| k.expect_ty()).collect(), expected_input_tys)
156                 }
157                 _ => {
158                     // Otherwise, there's a mismatch, so clear out what we're expecting, and set
159                     // our input typs to err_args so we don't blow up the error messages
160                     struct_span_err!(
161                         tcx.sess,
162                         call_span,
163                         E0059,
164                         "cannot use call notation; the first type parameter \
165                          for the function trait is neither a tuple nor unit"
166                     )
167                     .emit();
168                     (self.err_args(provided_args.len()), vec![])
169                 }
170             }
171         } else if expected_arg_count == supplied_arg_count {
172             (formal_input_tys.to_vec(), expected_input_tys)
173         } else if c_variadic {
174             if supplied_arg_count >= expected_arg_count {
175                 (formal_input_tys.to_vec(), expected_input_tys)
176             } else {
177                 error = Some((expected_arg_count, supplied_arg_count, "E0060", false, None));
178                 (self.err_args(supplied_arg_count), vec![])
179             }
180         } else {
181             // is the missing argument of type `()`?
182             let sugg_unit = if expected_input_tys.len() == 1 && supplied_arg_count == 0 {
183                 self.resolve_vars_if_possible(expected_input_tys[0]).is_unit()
184             } else if formal_input_tys.len() == 1 && supplied_arg_count == 0 {
185                 self.resolve_vars_if_possible(formal_input_tys[0]).is_unit()
186             } else {
187                 false
188             };
189
190             // are we passing elements of a tuple without the tuple parentheses?
191             let expected_input_tys = if expected_input_tys.is_empty() {
192                 // In most cases we can use expected_input_tys, but some callers won't have the type
193                 // information, in which case we fall back to the types from the input expressions.
194                 formal_input_tys
195             } else {
196                 &*expected_input_tys
197             };
198
199             let sugg_tuple_wrap_args = self.suggested_tuple_wrap(expected_input_tys, provided_args);
200
201             error = Some((
202                 expected_arg_count,
203                 supplied_arg_count,
204                 "E0061",
205                 sugg_unit,
206                 sugg_tuple_wrap_args,
207             ));
208             (self.err_args(supplied_arg_count), vec![])
209         };
210
211         debug!(
212             "check_argument_types: formal_input_tys={:?}",
213             formal_input_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
214         );
215
216         // If there is no expectation, expect formal_input_tys.
217         let expected_input_tys = if !expected_input_tys.is_empty() {
218             expected_input_tys
219         } else {
220             formal_input_tys.clone()
221         };
222
223         assert_eq!(expected_input_tys.len(), formal_input_tys.len());
224
225         let provided_arg_count: usize = provided_args.len();
226
227         // Keep track of the fully coerced argument types
228         let mut final_arg_types: Vec<Option<(Ty<'_>, Ty<'_>)>> = vec![None; provided_arg_count];
229
230         // We introduce a helper function to demand that a given argument satisfy a given input
231         // This is more complicated than just checking type equality, as arguments could be coerced
232         // This version writes those types back so further type checking uses the narrowed types
233         let demand_compatible = |idx, final_arg_types: &mut Vec<Option<(Ty<'tcx>, Ty<'tcx>)>>| {
234             let formal_input_ty: Ty<'tcx> = formal_input_tys[idx];
235             let expected_input_ty: Ty<'tcx> = expected_input_tys[idx];
236             let provided_arg = &provided_args[idx];
237
238             debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
239
240             // The special-cased logic below has three functions:
241             // 1. Provide as good of an expected type as possible.
242             let expectation = Expectation::rvalue_hint(self, expected_input_ty);
243
244             let checked_ty = self.check_expr_with_expectation(provided_arg, expectation);
245
246             // 2. Coerce to the most detailed type that could be coerced
247             //    to, which is `expected_ty` if `rvalue_hint` returns an
248             //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
249             let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
250
251             // Keep track of these for below
252             final_arg_types[idx] = Some((checked_ty, coerced_ty));
253
254             // Cause selection errors caused by resolving a single argument to point at the
255             // argument and not the call. This is otherwise redundant with the `demand_coerce`
256             // call immediately after, but it lets us customize the span pointed to in the
257             // fulfillment error to be more accurate.
258             let coerced_ty =
259                 self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| {
260                     self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
261                     self.point_at_arg_instead_of_call_if_possible(
262                         errors,
263                         &final_arg_types,
264                         call_expr,
265                         call_span,
266                         provided_args,
267                     );
268                 });
269
270             final_arg_types[idx] = Some((checked_ty, coerced_ty));
271
272             // We're processing function arguments so we definitely want to use
273             // two-phase borrows.
274             self.demand_coerce(&provided_arg, checked_ty, coerced_ty, None, AllowTwoPhase::Yes);
275
276             // 3. Relate the expected type and the formal one,
277             //    if the expected type was used for the coercion.
278             self.demand_suptype(provided_arg.span, formal_input_ty, coerced_ty);
279         };
280
281         // Check the arguments.
282         // We do this in a pretty awful way: first we type-check any arguments
283         // that are not closures, then we type-check the closures. This is so
284         // that we have more information about the types of arguments when we
285         // type-check the functions. This isn't really the right way to do this.
286         for check_closures in [false, true] {
287             // More awful hacks: before we check argument types, try to do
288             // an "opportunistic" trait resolution of any trait bounds on
289             // the call. This helps coercions.
290             if check_closures {
291                 self.select_obligations_where_possible(false, |errors| {
292                     self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
293                     self.point_at_arg_instead_of_call_if_possible(
294                         errors,
295                         &final_arg_types,
296                         call_expr,
297                         call_span,
298                         &provided_args,
299                     );
300                 })
301             }
302
303             let minimum_input_count = formal_input_tys.len();
304             for (idx, arg) in provided_args.iter().enumerate() {
305                 // Warn only for the first loop (the "no closures" one).
306                 // Closure arguments themselves can't be diverging, but
307                 // a previous argument can, e.g., `foo(panic!(), || {})`.
308                 if !check_closures {
309                     self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
310                 }
311
312                 // For C-variadic functions, we don't have a declared type for all of
313                 // the arguments hence we only do our usual type checking with
314                 // the arguments who's types we do know. However, we *can* check
315                 // for unreachable expressions (see above).
316                 // FIXME: unreachable warning current isn't emitted
317                 if idx >= minimum_input_count {
318                     continue;
319                 }
320
321                 let is_closure = matches!(arg.kind, ExprKind::Closure(..));
322                 if is_closure != check_closures {
323                     continue;
324                 }
325
326                 demand_compatible(idx, &mut final_arg_types);
327             }
328         }
329
330         // If there was an error in parameter count, emit that here
331         if let Some((expected_count, arg_count, err_code, sugg_unit, sugg_tuple_wrap_args)) = error
332         {
333             let (span, start_span, args, ctor_of) = match &call_expr.kind {
334                 hir::ExprKind::Call(
335                     hir::Expr {
336                         span,
337                         kind:
338                             hir::ExprKind::Path(hir::QPath::Resolved(
339                                 _,
340                                 hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
341                             )),
342                         ..
343                     },
344                     args,
345                 ) => (*span, *span, &args[..], Some(of)),
346                 hir::ExprKind::Call(hir::Expr { span, .. }, args) => {
347                     (*span, *span, &args[..], None)
348                 }
349                 hir::ExprKind::MethodCall(path_segment, args, _) => (
350                     path_segment.ident.span,
351                     // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
352                     path_segment
353                         .args
354                         .and_then(|args| args.args.iter().last())
355                         // Account for `foo.bar::<T>()`.
356                         .map(|arg| {
357                             // Skip the closing `>`.
358                             tcx.sess
359                                 .source_map()
360                                 .next_point(tcx.sess.source_map().next_point(arg.span()))
361                         })
362                         .unwrap_or(path_segment.ident.span),
363                     &args[1..], // Skip the receiver.
364                     None,       // methods are never ctors
365                 ),
366                 k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
367             };
368             let arg_spans = if provided_args.is_empty() {
369                 // foo()
370                 // ^^^-- supplied 0 arguments
371                 // |
372                 // expected 2 arguments
373                 vec![tcx.sess.source_map().next_point(start_span).with_hi(call_span.hi())]
374             } else {
375                 // foo(1, 2, 3)
376                 // ^^^ -  -  - supplied 3 arguments
377                 // |
378                 // expected 2 arguments
379                 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
380             };
381             let call_name = match ctor_of {
382                 Some(CtorOf::Struct) => "struct",
383                 Some(CtorOf::Variant) => "enum variant",
384                 None => "function",
385             };
386             let mut err = tcx.sess.struct_span_err_with_code(
387                 span,
388                 &format!(
389                     "this {} takes {}{} but {} {} supplied",
390                     call_name,
391                     if c_variadic { "at least " } else { "" },
392                     potentially_plural_count(expected_count, "argument"),
393                     potentially_plural_count(arg_count, "argument"),
394                     if arg_count == 1 { "was" } else { "were" }
395                 ),
396                 DiagnosticId::Error(err_code.to_owned()),
397             );
398             let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
399             for (i, span) in arg_spans.into_iter().enumerate() {
400                 err.span_label(
401                     span,
402                     if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
403                 );
404             }
405             if let Some(def_id) = fn_def_id {
406                 if let Some(def_span) = tcx.def_ident_span(def_id) {
407                     let mut spans: MultiSpan = def_span.into();
408
409                     let params = tcx
410                         .hir()
411                         .get_if_local(def_id)
412                         .and_then(|node| node.body_id())
413                         .into_iter()
414                         .map(|id| tcx.hir().body(id).params)
415                         .flatten();
416
417                     for param in params {
418                         spans.push_span_label(param.span, String::new());
419                     }
420
421                     let def_kind = tcx.def_kind(def_id);
422                     err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
423                 }
424             }
425             if sugg_unit {
426                 let sugg_span = tcx.sess.source_map().end_point(call_expr.span);
427                 // remove closing `)` from the span
428                 let sugg_span = sugg_span.shrink_to_lo();
429                 err.span_suggestion(
430                     sugg_span,
431                     "expected the unit value `()`; create it with empty parentheses",
432                     String::from("()"),
433                     Applicability::MachineApplicable,
434                 );
435             } else if let Some(FnArgsAsTuple { first, last }) = sugg_tuple_wrap_args {
436                 err.multipart_suggestion(
437                     "use parentheses to construct a tuple",
438                     vec![
439                         (first.span.shrink_to_lo(), '('.to_string()),
440                         (last.span.shrink_to_hi(), ')'.to_string()),
441                     ],
442                     Applicability::MachineApplicable,
443                 );
444             } else {
445                 err.span_label(
446                     span,
447                     format!(
448                         "expected {}{}",
449                         if c_variadic { "at least " } else { "" },
450                         potentially_plural_count(expected_count, "argument")
451                     ),
452                 );
453             }
454             err.emit();
455         }
456
457         // We also need to make sure we at least write the ty of the other
458         // arguments which we skipped above.
459         if c_variadic {
460             fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
461                 use crate::structured_errors::MissingCastForVariadicArg;
462
463                 MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit()
464             }
465
466             for arg in provided_args.iter().skip(expected_arg_count) {
467                 let arg_ty = self.check_expr(&arg);
468
469                 // There are a few types which get autopromoted when passed via varargs
470                 // in C but we just error out instead and require explicit casts.
471                 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
472                 match arg_ty.kind() {
473                     ty::Float(ty::FloatTy::F32) => {
474                         variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
475                     }
476                     ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
477                         variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
478                     }
479                     ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
480                         variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
481                     }
482                     ty::FnDef(..) => {
483                         let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
484                         let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
485                         variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
486                     }
487                     _ => {}
488                 }
489             }
490         }
491     }
492
493     fn suggested_tuple_wrap(
494         &self,
495         expected_input_tys: &[Ty<'tcx>],
496         provided_args: &'tcx [hir::Expr<'tcx>],
497     ) -> Option<FnArgsAsTuple<'_>> {
498         let [expected_arg_type] = &expected_input_tys[..] else { return None };
499
500         let ty::Tuple(expected_elems) = self.resolve_vars_if_possible(*expected_arg_type).kind()
501             else { return None };
502
503         let expected_types: Vec<_> = expected_elems.iter().map(|k| k.expect_ty()).collect();
504         let supplied_types: Vec<_> = provided_args.iter().map(|arg| self.check_expr(arg)).collect();
505
506         let all_match = iter::zip(expected_types, supplied_types)
507             .all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok());
508
509         if all_match {
510             match provided_args {
511                 [] => None,
512                 [_] => unreachable!(
513                     "shouldn't reach here - need count mismatch between 1-tuple and 1-argument"
514                 ),
515                 [first, .., last] => Some(FnArgsAsTuple { first, last }),
516             }
517         } else {
518             None
519         }
520     }
521
522     // AST fragment checking
523     pub(in super::super) fn check_lit(
524         &self,
525         lit: &hir::Lit,
526         expected: Expectation<'tcx>,
527     ) -> Ty<'tcx> {
528         let tcx = self.tcx;
529
530         match lit.node {
531             ast::LitKind::Str(..) => tcx.mk_static_str(),
532             ast::LitKind::ByteStr(ref v) => {
533                 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
534             }
535             ast::LitKind::Byte(_) => tcx.types.u8,
536             ast::LitKind::Char(_) => tcx.types.char,
537             ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(ty::int_ty(t)),
538             ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(ty::uint_ty(t)),
539             ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
540                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
541                     ty::Int(_) | ty::Uint(_) => Some(ty),
542                     ty::Char => Some(tcx.types.u8),
543                     ty::RawPtr(..) => Some(tcx.types.usize),
544                     ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
545                     _ => None,
546                 });
547                 opt_ty.unwrap_or_else(|| self.next_int_var())
548             }
549             ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => {
550                 tcx.mk_mach_float(ty::float_ty(t))
551             }
552             ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
553                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
554                     ty::Float(_) => Some(ty),
555                     _ => None,
556                 });
557                 opt_ty.unwrap_or_else(|| self.next_float_var())
558             }
559             ast::LitKind::Bool(_) => tcx.types.bool,
560             ast::LitKind::Err(_) => tcx.ty_error(),
561         }
562     }
563
564     pub fn check_struct_path(
565         &self,
566         qpath: &QPath<'_>,
567         hir_id: hir::HirId,
568     ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
569         let path_span = qpath.span();
570         let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
571         let variant = match def {
572             Res::Err => {
573                 self.set_tainted_by_errors();
574                 return None;
575             }
576             Res::Def(DefKind::Variant, _) => match ty.kind() {
577                 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
578                 _ => bug!("unexpected type: {:?}", ty),
579             },
580             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
581             | Res::SelfTy { .. } => match ty.kind() {
582                 ty::Adt(adt, substs) if !adt.is_enum() => {
583                     Some((adt.non_enum_variant(), adt.did, substs))
584                 }
585                 _ => None,
586             },
587             _ => bug!("unexpected definition: {:?}", def),
588         };
589
590         if let Some((variant, did, substs)) = variant {
591             debug!("check_struct_path: did={:?} substs={:?}", did, substs);
592             self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
593
594             // Check bounds on type arguments used in the path.
595             self.add_required_obligations(path_span, did, substs);
596
597             Some((variant, ty))
598         } else {
599             match ty.kind() {
600                 ty::Error(_) => {
601                     // E0071 might be caused by a spelling error, which will have
602                     // already caused an error message and probably a suggestion
603                     // elsewhere. Refrain from emitting more unhelpful errors here
604                     // (issue #88844).
605                 }
606                 _ => {
607                     struct_span_err!(
608                         self.tcx.sess,
609                         path_span,
610                         E0071,
611                         "expected struct, variant or union type, found {}",
612                         ty.sort_string(self.tcx)
613                     )
614                     .span_label(path_span, "not a struct")
615                     .emit();
616                 }
617             }
618             None
619         }
620     }
621
622     pub fn check_decl_initializer(
623         &self,
624         hir_id: hir::HirId,
625         pat: &'tcx hir::Pat<'tcx>,
626         init: &'tcx hir::Expr<'tcx>,
627     ) -> Ty<'tcx> {
628         // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
629         // for #42640 (default match binding modes).
630         //
631         // See #44848.
632         let ref_bindings = pat.contains_explicit_ref_binding();
633
634         let local_ty = self.local_ty(init.span, hir_id).revealed_ty;
635         if let Some(m) = ref_bindings {
636             // Somewhat subtle: if we have a `ref` binding in the pattern,
637             // we want to avoid introducing coercions for the RHS. This is
638             // both because it helps preserve sanity and, in the case of
639             // ref mut, for soundness (issue #23116). In particular, in
640             // the latter case, we need to be clear that the type of the
641             // referent for the reference that results is *equal to* the
642             // type of the place it is referencing, and not some
643             // supertype thereof.
644             let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
645             self.demand_eqtype(init.span, local_ty, init_ty);
646             init_ty
647         } else {
648             self.check_expr_coercable_to_type(init, local_ty, None)
649         }
650     }
651
652     pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
653         // Determine and write the type which we'll check the pattern against.
654         let decl_ty = self.local_ty(decl.span, decl.hir_id).decl_ty;
655         self.write_ty(decl.hir_id, decl_ty);
656
657         // Type check the initializer.
658         if let Some(ref init) = decl.init {
659             let init_ty = self.check_decl_initializer(decl.hir_id, decl.pat, &init);
660             self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, init_ty);
661         }
662
663         // Does the expected pattern type originate from an expression and what is the span?
664         let (origin_expr, ty_span) = match (decl.ty, decl.init) {
665             (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
666             (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
667             _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
668         };
669
670         // Type check the pattern. Override if necessary to avoid knock-on errors.
671         self.check_pat_top(&decl.pat, decl_ty, ty_span, origin_expr);
672         let pat_ty = self.node_ty(decl.pat.hir_id);
673         self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, pat_ty);
674     }
675
676     /// Type check a `let` statement.
677     pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
678         self.check_decl(local.into());
679     }
680
681     pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>, is_last: bool) {
682         // Don't do all the complex logic below for `DeclItem`.
683         match stmt.kind {
684             hir::StmtKind::Item(..) => return,
685             hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
686         }
687
688         self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
689
690         // Hide the outer diverging and `has_errors` flags.
691         let old_diverges = self.diverges.replace(Diverges::Maybe);
692         let old_has_errors = self.has_errors.replace(false);
693
694         match stmt.kind {
695             hir::StmtKind::Local(ref l) => {
696                 self.check_decl_local(&l);
697             }
698             // Ignore for now.
699             hir::StmtKind::Item(_) => {}
700             hir::StmtKind::Expr(ref expr) => {
701                 // Check with expected type of `()`.
702                 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
703                     if expr.can_have_side_effects() {
704                         self.suggest_semicolon_at_end(expr.span, err);
705                     }
706                 });
707             }
708             hir::StmtKind::Semi(ref expr) => {
709                 // All of this is equivalent to calling `check_expr`, but it is inlined out here
710                 // in order to capture the fact that this `match` is the last statement in its
711                 // function. This is done for better suggestions to remove the `;`.
712                 let expectation = match expr.kind {
713                     hir::ExprKind::Match(..) if is_last => IsLast(stmt.span),
714                     _ => NoExpectation,
715                 };
716                 self.check_expr_with_expectation(expr, expectation);
717             }
718         }
719
720         // Combine the diverging and `has_error` flags.
721         self.diverges.set(self.diverges.get() | old_diverges);
722         self.has_errors.set(self.has_errors.get() | old_has_errors);
723     }
724
725     pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
726         let unit = self.tcx.mk_unit();
727         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
728
729         // if the block produces a `!` value, that can always be
730         // (effectively) coerced to unit.
731         if !ty.is_never() {
732             self.demand_suptype(blk.span, unit, ty);
733         }
734     }
735
736     pub(in super::super) fn check_block_with_expected(
737         &self,
738         blk: &'tcx hir::Block<'tcx>,
739         expected: Expectation<'tcx>,
740     ) -> Ty<'tcx> {
741         let prev = self.ps.replace(self.ps.get().recurse(blk));
742
743         // In some cases, blocks have just one exit, but other blocks
744         // can be targeted by multiple breaks. This can happen both
745         // with labeled blocks as well as when we desugar
746         // a `try { ... }` expression.
747         //
748         // Example 1:
749         //
750         //    'a: { if true { break 'a Err(()); } Ok(()) }
751         //
752         // Here we would wind up with two coercions, one from
753         // `Err(())` and the other from the tail expression
754         // `Ok(())`. If the tail expression is omitted, that's a
755         // "forced unit" -- unless the block diverges, in which
756         // case we can ignore the tail expression (e.g., `'a: {
757         // break 'a 22; }` would not force the type of the block
758         // to be `()`).
759         let tail_expr = blk.expr.as_ref();
760         let coerce_to_ty = expected.coercion_target_type(self, blk.span);
761         let coerce = if blk.targeted_by_break {
762             CoerceMany::new(coerce_to_ty)
763         } else {
764             let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
765                 Some(e) => slice::from_ref(e),
766                 None => &[],
767             };
768             CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
769         };
770
771         let prev_diverges = self.diverges.get();
772         let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
773
774         let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
775             for (pos, s) in blk.stmts.iter().enumerate() {
776                 self.check_stmt(s, blk.stmts.len() - 1 == pos);
777             }
778
779             // check the tail expression **without** holding the
780             // `enclosing_breakables` lock below.
781             let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
782
783             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
784             let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
785             let coerce = ctxt.coerce.as_mut().unwrap();
786             if let Some(tail_expr_ty) = tail_expr_ty {
787                 let tail_expr = tail_expr.unwrap();
788                 let span = self.get_expr_coercion_span(tail_expr);
789                 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
790                 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
791             } else {
792                 // Subtle: if there is no explicit tail expression,
793                 // that is typically equivalent to a tail expression
794                 // of `()` -- except if the block diverges. In that
795                 // case, there is no value supplied from the tail
796                 // expression (assuming there are no other breaks,
797                 // this implies that the type of the block will be
798                 // `!`).
799                 //
800                 // #41425 -- label the implicit `()` as being the
801                 // "found type" here, rather than the "expected type".
802                 if !self.diverges.get().is_always() {
803                     // #50009 -- Do not point at the entire fn block span, point at the return type
804                     // span, as it is the cause of the requirement, and
805                     // `consider_hint_about_removing_semicolon` will point at the last expression
806                     // if it were a relevant part of the error. This improves usability in editors
807                     // that highlight errors inline.
808                     let mut sp = blk.span;
809                     let mut fn_span = None;
810                     if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
811                         let ret_sp = decl.output.span();
812                         if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
813                             // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
814                             // output would otherwise be incorrect and even misleading. Make sure
815                             // the span we're aiming at correspond to a `fn` body.
816                             if block_sp == blk.span {
817                                 sp = ret_sp;
818                                 fn_span = Some(ident.span);
819                             }
820                         }
821                     }
822                     coerce.coerce_forced_unit(
823                         self,
824                         &self.misc(sp),
825                         &mut |err| {
826                             if let Some(expected_ty) = expected.only_has_type(self) {
827                                 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
828                                 if expected_ty == self.tcx.types.bool {
829                                     // If this is caused by a missing `let` in a `while let`,
830                                     // silence this redundant error, as we already emit E0070.
831                                     let parent = self.tcx.hir().get_parent_node(blk.hir_id);
832                                     let parent = self.tcx.hir().get_parent_node(parent);
833                                     let parent = self.tcx.hir().get_parent_node(parent);
834                                     let parent = self.tcx.hir().get_parent_node(parent);
835                                     let parent = self.tcx.hir().get_parent_node(parent);
836                                     match self.tcx.hir().find(parent) {
837                                         Some(hir::Node::Expr(hir::Expr {
838                                             kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
839                                             ..
840                                         })) => {
841                                             err.delay_as_bug();
842                                         }
843                                         _ => {}
844                                     }
845                                 }
846                             }
847                             if let Some(fn_span) = fn_span {
848                                 err.span_label(
849                                     fn_span,
850                                     "implicitly returns `()` as its body has no tail or `return` \
851                                      expression",
852                                 );
853                             }
854                         },
855                         false,
856                     );
857                 }
858             }
859         });
860
861         if ctxt.may_break {
862             // If we can break from the block, then the block's exit is always reachable
863             // (... as long as the entry is reachable) - regardless of the tail of the block.
864             self.diverges.set(prev_diverges);
865         }
866
867         let mut ty = ctxt.coerce.unwrap().complete(self);
868
869         if self.has_errors.get() || ty.references_error() {
870             ty = self.tcx.ty_error()
871         }
872
873         self.write_ty(blk.hir_id, ty);
874
875         self.ps.set(prev);
876         ty
877     }
878
879     /// A common error is to add an extra semicolon:
880     ///
881     /// ```
882     /// fn foo() -> usize {
883     ///     22;
884     /// }
885     /// ```
886     ///
887     /// This routine checks if the final statement in a block is an
888     /// expression with an explicit semicolon whose type is compatible
889     /// with `expected_ty`. If so, it suggests removing the semicolon.
890     fn consider_hint_about_removing_semicolon(
891         &self,
892         blk: &'tcx hir::Block<'tcx>,
893         expected_ty: Ty<'tcx>,
894         err: &mut DiagnosticBuilder<'_>,
895     ) {
896         if let Some((span_semi, boxed)) = self.could_remove_semicolon(blk, expected_ty) {
897             if let StatementAsExpression::NeedsBoxing = boxed {
898                 err.span_suggestion_verbose(
899                     span_semi,
900                     "consider removing this semicolon and boxing the expression",
901                     String::new(),
902                     Applicability::HasPlaceholders,
903                 );
904             } else {
905                 err.span_suggestion_short(
906                     span_semi,
907                     "consider removing this semicolon",
908                     String::new(),
909                     Applicability::MachineApplicable,
910                 );
911             }
912         }
913     }
914
915     fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
916         let node = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(id));
917         match node {
918             Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
919             | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
920                 let body = self.tcx.hir().body(body_id);
921                 if let ExprKind::Block(block, _) = &body.value.kind {
922                     return Some(block.span);
923                 }
924             }
925             _ => {}
926         }
927         None
928     }
929
930     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
931     fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
932         let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id));
933         self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
934     }
935
936     /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
937     /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
938     /// when given code like the following:
939     /// ```text
940     /// if false { return 0i32; } else { 1u32 }
941     /// //                               ^^^^ point at this instead of the whole `if` expression
942     /// ```
943     fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
944         let check_in_progress = |elem: &hir::Expr<'_>| {
945             self.in_progress_typeck_results
946                 .and_then(|typeck_results| typeck_results.borrow().node_type_opt(elem.hir_id))
947                 .and_then(|ty| {
948                     if ty.is_never() {
949                         None
950                     } else {
951                         Some(match elem.kind {
952                             // Point at the tail expression when possible.
953                             hir::ExprKind::Block(block, _) => {
954                                 block.expr.map_or(block.span, |e| e.span)
955                             }
956                             _ => elem.span,
957                         })
958                     }
959                 })
960         };
961
962         if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
963             if let Some(rslt) = check_in_progress(el) {
964                 return rslt;
965             }
966         }
967
968         if let hir::ExprKind::Match(_, arms, _) = expr.kind {
969             let mut iter = arms.iter().filter_map(|arm| check_in_progress(arm.body));
970             if let Some(span) = iter.next() {
971                 if iter.next().is_none() {
972                     return span;
973                 }
974             }
975         }
976
977         expr.span
978     }
979
980     fn overwrite_local_ty_if_err(
981         &self,
982         hir_id: hir::HirId,
983         pat: &'tcx hir::Pat<'tcx>,
984         decl_ty: Ty<'tcx>,
985         ty: Ty<'tcx>,
986     ) {
987         if ty.references_error() {
988             // Override the types everywhere with `err()` to avoid knock on errors.
989             self.write_ty(hir_id, ty);
990             self.write_ty(pat.hir_id, ty);
991             let local_ty = LocalTy { decl_ty, revealed_ty: ty };
992             self.locals.borrow_mut().insert(hir_id, local_ty);
993             self.locals.borrow_mut().insert(pat.hir_id, local_ty);
994         }
995     }
996
997     // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
998     // The newly resolved definition is written into `type_dependent_defs`.
999     fn finish_resolving_struct_path(
1000         &self,
1001         qpath: &QPath<'_>,
1002         path_span: Span,
1003         hir_id: hir::HirId,
1004     ) -> (Res, Ty<'tcx>) {
1005         match *qpath {
1006             QPath::Resolved(ref maybe_qself, ref path) => {
1007                 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
1008                 let ty = <dyn AstConv<'_>>::res_to_ty(self, self_ty, path, true);
1009                 (path.res, ty)
1010             }
1011             QPath::TypeRelative(ref qself, ref segment) => {
1012                 let ty = self.to_ty(qself);
1013
1014                 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
1015                     path.res
1016                 } else {
1017                     Res::Err
1018                 };
1019                 let result = <dyn AstConv<'_>>::associated_path_to_ty(
1020                     self, hir_id, path_span, ty, res, segment, true,
1021                 );
1022                 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
1023                 let result = result.map(|(_, kind, def_id)| (kind, def_id));
1024
1025                 // Write back the new resolution.
1026                 self.write_resolution(hir_id, result);
1027
1028                 (result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
1029             }
1030             QPath::LangItem(lang_item, span, id) => {
1031                 self.resolve_lang_item_path(lang_item, span, hir_id, id)
1032             }
1033         }
1034     }
1035
1036     /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
1037     /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
1038     /// reference a type argument. The reason to walk also the checked type is that the coerced type
1039     /// can be not easily comparable with predicate type (because of coercion). If the types match
1040     /// for either checked or coerced type, and there's only *one* argument that does, we point at
1041     /// the corresponding argument's expression span instead of the `fn` call path span.
1042     fn point_at_arg_instead_of_call_if_possible(
1043         &self,
1044         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1045         final_arg_types: &[Option<(Ty<'tcx>, Ty<'tcx>)>],
1046         expr: &'tcx hir::Expr<'tcx>,
1047         call_sp: Span,
1048         args: &'tcx [hir::Expr<'tcx>],
1049     ) {
1050         // We *do not* do this for desugared call spans to keep good diagnostics when involving
1051         // the `?` operator.
1052         if call_sp.desugaring_kind().is_some() {
1053             return;
1054         }
1055
1056         for error in errors {
1057             // Only if the cause is somewhere inside the expression we want try to point at arg.
1058             // Otherwise, it means that the cause is somewhere else and we should not change
1059             // anything because we can break the correct span.
1060             if !call_sp.contains(error.obligation.cause.span) {
1061                 continue;
1062             }
1063
1064             // Peel derived obligation, because it's the type that originally
1065             // started this inference chain that matters, not the one we wound
1066             // up with at the end.
1067             fn unpeel_to_top(
1068                 mut code: Lrc<ObligationCauseCode<'_>>,
1069             ) -> Lrc<ObligationCauseCode<'_>> {
1070                 let mut result_code = code.clone();
1071                 loop {
1072                     let parent = match &*code {
1073                         ObligationCauseCode::BuiltinDerivedObligation(c)
1074                         | ObligationCauseCode::ImplDerivedObligation(c)
1075                         | ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(),
1076                         _ => break,
1077                     };
1078                     result_code = std::mem::replace(&mut code, parent);
1079                 }
1080                 result_code
1081             }
1082             let self_: ty::subst::GenericArg<'_> = match &*unpeel_to_top(error.obligation.cause.clone_code()) {
1083                 ObligationCauseCode::BuiltinDerivedObligation(code) |
1084                 ObligationCauseCode::ImplDerivedObligation(code) |
1085                 ObligationCauseCode::DerivedObligation(code) => {
1086                     code.parent_trait_pred.self_ty().skip_binder().into()
1087                 }
1088                 _ if let ty::PredicateKind::Trait(predicate) =
1089                     error.obligation.predicate.kind().skip_binder() => {
1090                         predicate.self_ty().into()
1091                     }
1092                 _ =>  continue,
1093             };
1094             let self_ = self.resolve_vars_if_possible(self_);
1095
1096             // Collect the argument position for all arguments that could have caused this
1097             // `FulfillmentError`.
1098             let mut referenced_in = final_arg_types
1099                 .iter()
1100                 .enumerate()
1101                 .filter_map(|(i, arg)| match arg {
1102                     Some((checked_ty, coerce_ty)) => Some([(i, *checked_ty), (i, *coerce_ty)]),
1103                     _ => None,
1104                 })
1105                 .flatten()
1106                 .flat_map(|(i, ty)| {
1107                     let ty = self.resolve_vars_if_possible(ty);
1108                     // We walk the argument type because the argument's type could have
1109                     // been `Option<T>`, but the `FulfillmentError` references `T`.
1110                     if ty.walk().any(|arg| arg == self_) { Some(i) } else { None }
1111                 })
1112                 .collect::<Vec<usize>>();
1113
1114             // Both checked and coerced types could have matched, thus we need to remove
1115             // duplicates.
1116
1117             // We sort primitive type usize here and can use unstable sort
1118             referenced_in.sort_unstable();
1119             referenced_in.dedup();
1120
1121             if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
1122                 // Do not point at the inside of a macro.
1123                 // That would often result in poor error messages.
1124                 if args[ref_in].span.from_expansion() {
1125                     return;
1126                 }
1127                 // We make sure that only *one* argument matches the obligation failure
1128                 // and we assign the obligation's span to its expression's.
1129                 error.obligation.cause.span = args[ref_in].span;
1130                 let parent_code = error.obligation.cause.clone_code();
1131                 *error.obligation.cause.make_mut_code() =
1132                     ObligationCauseCode::FunctionArgumentObligation {
1133                         arg_hir_id: args[ref_in].hir_id,
1134                         call_hir_id: expr.hir_id,
1135                         parent_code,
1136                     };
1137             } else if error.obligation.cause.span == call_sp {
1138                 // Make function calls point at the callee, not the whole thing.
1139                 if let hir::ExprKind::Call(callee, _) = expr.kind {
1140                     error.obligation.cause.span = callee.span;
1141                 }
1142             }
1143         }
1144     }
1145
1146     /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
1147     /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
1148     /// were caused by them. If they were, we point at the corresponding type argument's span
1149     /// instead of the `fn` call path span.
1150     fn point_at_type_arg_instead_of_call_if_possible(
1151         &self,
1152         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1153         call_expr: &'tcx hir::Expr<'tcx>,
1154     ) {
1155         if let hir::ExprKind::Call(path, _) = &call_expr.kind {
1156             if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind {
1157                 for error in errors {
1158                     if let ty::PredicateKind::Trait(predicate) =
1159                         error.obligation.predicate.kind().skip_binder()
1160                     {
1161                         // If any of the type arguments in this path segment caused the
1162                         // `FulfillmentError`, point at its span (#61860).
1163                         for arg in path
1164                             .segments
1165                             .iter()
1166                             .filter_map(|seg| seg.args.as_ref())
1167                             .flat_map(|a| a.args.iter())
1168                         {
1169                             if let hir::GenericArg::Type(hir_ty) = &arg {
1170                                 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
1171                                     &hir_ty.kind
1172                                 {
1173                                     // Avoid ICE with associated types. As this is best
1174                                     // effort only, it's ok to ignore the case. It
1175                                     // would trigger in `is_send::<T::AssocType>();`
1176                                     // from `typeck-default-trait-impl-assoc-type.rs`.
1177                                 } else {
1178                                     let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, hir_ty);
1179                                     let ty = self.resolve_vars_if_possible(ty);
1180                                     if ty == predicate.self_ty() {
1181                                         error.obligation.cause.span = hir_ty.span;
1182                                     }
1183                                 }
1184                             }
1185                         }
1186                     }
1187                 }
1188             }
1189         }
1190     }
1191 }