1 use crate::astconv
::AstConv
;
2 use crate::check
::coercion
::CoerceMany
;
3 use crate::check
::method
::MethodCallee
;
4 use crate::check
::Expectation
::*;
5 use crate::check
::TupleArgumentsFlag
::*;
7 potentially_plural_count
, struct_span_err
, BreakableCtxt
, Diverges
, Expectation
, FnCtxt
,
8 LocalTy
, Needs
, TupleArgumentsFlag
,
12 use rustc_errors
::{Applicability, DiagnosticBuilder, DiagnosticId}
;
14 use rustc_hir
::def
::{DefKind, Res}
;
15 use rustc_hir
::def_id
::DefId
;
16 use rustc_hir
::{ExprKind, Node, QPath}
;
17 use rustc_middle
::ty
::adjustment
::AllowTwoPhase
;
18 use rustc_middle
::ty
::fold
::TypeFoldable
;
19 use rustc_middle
::ty
::{self, Ty}
;
20 use rustc_session
::Session
;
21 use rustc_span
::symbol
::{sym, Ident}
;
22 use rustc_span
::{self, MultiSpan, Span}
;
23 use rustc_trait_selection
::traits
::{self, ObligationCauseCode, StatementAsExpression}
;
25 use crate::structured_errors
::StructuredDiagnostic
;
28 impl<'a
, 'tcx
> FnCtxt
<'a
, 'tcx
> {
29 pub(in super::super) fn check_casts(&self) {
30 let mut deferred_cast_checks
= self.deferred_cast_checks
.borrow_mut();
31 for cast
in deferred_cast_checks
.drain(..) {
36 pub(in super::super) fn check_method_argument_types(
39 expr
: &'tcx hir
::Expr
<'tcx
>,
40 method
: Result
<MethodCallee
<'tcx
>, ()>,
41 args_no_rcvr
: &'tcx
[hir
::Expr
<'tcx
>],
42 tuple_arguments
: TupleArgumentsFlag
,
43 expected
: Expectation
<'tcx
>,
45 let has_error
= match method
{
46 Ok(method
) => method
.substs
.references_error() || method
.sig
.references_error(),
50 let err_inputs
= self.err_args(args_no_rcvr
.len());
52 let err_inputs
= match tuple_arguments
{
53 DontTupleArguments
=> err_inputs
,
54 TupleArguments
=> vec
![self.tcx
.intern_tup(&err_inputs
[..])],
57 self.check_argument_types(
67 return self.tcx
.ty_error();
70 let method
= method
.unwrap();
71 // HACK(eddyb) ignore self in the definition (see above).
72 let expected_arg_tys
= self.expected_inputs_for_expected_output(
76 &method
.sig
.inputs()[1..],
78 self.check_argument_types(
81 &method
.sig
.inputs()[1..],
82 &expected_arg_tys
[..],
84 method
.sig
.c_variadic
,
91 /// Generic function that factors out common logic from function calls,
92 /// method calls and overloaded operators.
93 pub(in super::super) fn check_argument_types(
96 expr
: &'tcx hir
::Expr
<'tcx
>,
97 fn_inputs
: &[Ty
<'tcx
>],
98 expected_arg_tys
: &[Ty
<'tcx
>],
99 args
: &'tcx
[hir
::Expr
<'tcx
>],
101 tuple_arguments
: TupleArgumentsFlag
,
102 def_id
: Option
<DefId
>,
105 // Grab the argument types, supplying fresh type variables
106 // if the wrong number of arguments were supplied
107 let supplied_arg_count
= if tuple_arguments
== DontTupleArguments { args.len() }
else { 1 }
;
109 // All the input types from the fn signature must outlive the call
110 // so as to validate implied bounds.
111 for (&fn_input_ty
, arg_expr
) in fn_inputs
.iter().zip(args
.iter()) {
112 self.register_wf_obligation(fn_input_ty
.into(), arg_expr
.span
, traits
::MiscObligation
);
115 let expected_arg_count
= fn_inputs
.len();
117 let param_count_error
= |expected_count
: usize,
122 let (span
, start_span
, args
) = match &expr
.kind
{
123 hir
::ExprKind
::Call(hir
::Expr { span, .. }
, args
) => (*span
, *span
, &args
[..]),
124 hir
::ExprKind
::MethodCall(path_segment
, span
, args
, _
) => (
126 // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
129 .and_then(|args
| args
.args
.iter().last())
130 // Account for `foo.bar::<T>()`.
132 // Skip the closing `>`.
135 .next_point(tcx
.sess
.source_map().next_point(arg
.span()))
138 &args
[1..], // Skip the receiver.
140 k
=> span_bug
!(sp
, "checking argument types on a non-call: `{:?}`", k
),
142 let arg_spans
= if args
.is_empty() {
144 // ^^^-- supplied 0 arguments
146 // expected 2 arguments
147 vec
![tcx
.sess
.source_map().next_point(start_span
).with_hi(sp
.hi())]
150 // ^^^ - - - supplied 3 arguments
152 // expected 2 arguments
153 args
.iter().map(|arg
| arg
.span
).collect
::<Vec
<Span
>>()
156 let mut err
= tcx
.sess
.struct_span_err_with_code(
159 "this function takes {}{} but {} {} supplied",
160 if c_variadic { "at least " }
else { "" }
,
161 potentially_plural_count(expected_count
, "argument"),
162 potentially_plural_count(arg_count
, "argument"),
163 if arg_count
== 1 { "was" }
else { "were" }
165 DiagnosticId
::Error(error_code
.to_owned()),
167 let label
= format
!("supplied {}", potentially_plural_count(arg_count
, "argument"));
168 for (i
, span
) in arg_spans
.into_iter().enumerate() {
171 if arg_count
== 0 || i
+ 1 == arg_count { &label }
else { "" }
,
175 if let Some(def_id
) = def_id
{
176 if let Some(def_span
) = tcx
.def_ident_span(def_id
) {
177 let mut spans
: MultiSpan
= def_span
.into();
181 .get_if_local(def_id
)
182 .and_then(|node
| node
.body_id())
184 .map(|id
| tcx
.hir().body(id
).params
)
187 for param
in params
{
188 spans
.push_span_label(param
.span
, String
::new());
191 let def_kind
= tcx
.def_kind(def_id
);
192 err
.span_note(spans
, &format
!("{} defined here", def_kind
.descr(def_id
)));
197 let sugg_span
= tcx
.sess
.source_map().end_point(expr
.span
);
198 // remove closing `)` from the span
199 let sugg_span
= sugg_span
.shrink_to_lo();
202 "expected the unit value `()`; create it with empty parentheses",
204 Applicability
::MachineApplicable
,
211 if c_variadic { "at least " }
else { "" }
,
212 potentially_plural_count(expected_count
, "argument")
219 let mut expected_arg_tys
= expected_arg_tys
.to_vec();
221 let formal_tys
= if tuple_arguments
== TupleArguments
{
222 let tuple_type
= self.structurally_resolved_type(sp
, fn_inputs
[0]);
223 match tuple_type
.kind() {
224 ty
::Tuple(arg_types
) if arg_types
.len() != args
.len() => {
225 param_count_error(arg_types
.len(), args
.len(), "E0057", false, false);
226 expected_arg_tys
= vec
![];
227 self.err_args(args
.len())
229 ty
::Tuple(arg_types
) => {
230 expected_arg_tys
= match expected_arg_tys
.get(0) {
231 Some(&ty
) => match ty
.kind() {
232 ty
::Tuple(ref tys
) => tys
.iter().map(|k
| k
.expect_ty()).collect(),
237 arg_types
.iter().map(|k
| k
.expect_ty()).collect()
244 "cannot use call notation; the first type parameter \
245 for the function trait is neither a tuple nor unit"
248 expected_arg_tys
= vec
![];
249 self.err_args(args
.len())
252 } else if expected_arg_count
== supplied_arg_count
{
254 } else if c_variadic
{
255 if supplied_arg_count
>= expected_arg_count
{
258 param_count_error(expected_arg_count
, supplied_arg_count
, "E0060", true, false);
259 expected_arg_tys
= vec
![];
260 self.err_args(supplied_arg_count
)
263 // is the missing argument of type `()`?
264 let sugg_unit
= if expected_arg_tys
.len() == 1 && supplied_arg_count
== 0 {
265 self.resolve_vars_if_possible(expected_arg_tys
[0]).is_unit()
266 } else if fn_inputs
.len() == 1 && supplied_arg_count
== 0 {
267 self.resolve_vars_if_possible(fn_inputs
[0]).is_unit()
271 param_count_error(expected_arg_count
, supplied_arg_count
, "E0061", false, sugg_unit
);
273 expected_arg_tys
= vec
![];
274 self.err_args(supplied_arg_count
)
278 "check_argument_types: formal_tys={:?}",
279 formal_tys
.iter().map(|t
| self.ty_to_string(*t
)).collect
::<Vec
<String
>>()
282 // If there is no expectation, expect formal_tys.
283 let expected_arg_tys
=
284 if !expected_arg_tys
.is_empty() { expected_arg_tys }
else { formal_tys.clone() }
;
286 let mut final_arg_types
: Vec
<(usize, Ty
<'_
>, Ty
<'_
>)> = vec
![];
288 // Check the arguments.
289 // We do this in a pretty awful way: first we type-check any arguments
290 // that are not closures, then we type-check the closures. This is so
291 // that we have more information about the types of arguments when we
292 // type-check the functions. This isn't really the right way to do this.
293 for &check_closures
in &[false, true] {
294 debug
!("check_closures={}", check_closures
);
296 // More awful hacks: before we check argument types, try to do
297 // an "opportunistic" trait resolution of any trait bounds on
298 // the call. This helps coercions.
300 self.select_obligations_where_possible(false, |errors
| {
301 self.point_at_type_arg_instead_of_call_if_possible(errors
, expr
);
302 self.point_at_arg_instead_of_call_if_possible(
304 &final_arg_types
[..],
311 // For C-variadic functions, we don't have a declared type for all of
312 // the arguments hence we only do our usual type checking with
313 // the arguments who's types we do know.
314 let t
= if c_variadic
{
316 } else if tuple_arguments
== TupleArguments
{
321 for (i
, arg
) in args
.iter().take(t
).enumerate() {
322 // Warn only for the first loop (the "no closures" one).
323 // Closure arguments themselves can't be diverging, but
324 // a previous argument can, e.g., `foo(panic!(), || {})`.
326 self.warn_if_unreachable(arg
.hir_id
, arg
.span
, "expression");
329 let is_closure
= matches
!(arg
.kind
, ExprKind
::Closure(..));
331 if is_closure
!= check_closures
{
335 debug
!("checking the argument");
336 let formal_ty
= formal_tys
[i
];
338 // The special-cased logic below has three functions:
339 // 1. Provide as good of an expected type as possible.
340 let expected
= Expectation
::rvalue_hint(self, expected_arg_tys
[i
]);
342 let checked_ty
= self.check_expr_with_expectation(&arg
, expected
);
344 // 2. Coerce to the most detailed type that could be coerced
345 // to, which is `expected_ty` if `rvalue_hint` returns an
346 // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
347 let coerce_ty
= expected
.only_has_type(self).unwrap_or(formal_ty
);
348 // We're processing function arguments so we definitely want to use
349 // two-phase borrows.
350 self.demand_coerce(&arg
, checked_ty
, coerce_ty
, None
, AllowTwoPhase
::Yes
);
351 final_arg_types
.push((i
, checked_ty
, coerce_ty
));
353 // 3. Relate the expected type and the formal one,
354 // if the expected type was used for the coercion.
355 self.demand_suptype(arg
.span
, formal_ty
, coerce_ty
);
359 // We also need to make sure we at least write the ty of the other
360 // arguments which we skipped above.
362 fn variadic_error
<'tcx
>(sess
: &Session
, span
: Span
, ty
: Ty
<'tcx
>, cast_ty
: &str) {
363 use crate::structured_errors
::MissingCastForVariadicArg
;
365 MissingCastForVariadicArg { sess, span, ty, cast_ty }
.diagnostic().emit()
368 for arg
in args
.iter().skip(expected_arg_count
) {
369 let arg_ty
= self.check_expr(&arg
);
371 // There are a few types which get autopromoted when passed via varargs
372 // in C but we just error out instead and require explicit casts.
373 let arg_ty
= self.structurally_resolved_type(arg
.span
, arg_ty
);
374 match arg_ty
.kind() {
375 ty
::Float(ty
::FloatTy
::F32
) => {
376 variadic_error(tcx
.sess
, arg
.span
, arg_ty
, "c_double");
378 ty
::Int(ty
::IntTy
::I8
| ty
::IntTy
::I16
) | ty
::Bool
=> {
379 variadic_error(tcx
.sess
, arg
.span
, arg_ty
, "c_int");
381 ty
::Uint(ty
::UintTy
::U8
| ty
::UintTy
::U16
) => {
382 variadic_error(tcx
.sess
, arg
.span
, arg_ty
, "c_uint");
385 let ptr_ty
= self.tcx
.mk_fn_ptr(arg_ty
.fn_sig(self.tcx
));
386 let ptr_ty
= self.resolve_vars_if_possible(ptr_ty
);
387 variadic_error(tcx
.sess
, arg
.span
, arg_ty
, &ptr_ty
.to_string());
395 // AST fragment checking
396 pub(in super::super) fn check_lit(
399 expected
: Expectation
<'tcx
>,
404 ast
::LitKind
::Str(..) => tcx
.mk_static_str(),
405 ast
::LitKind
::ByteStr(ref v
) => {
406 tcx
.mk_imm_ref(tcx
.lifetimes
.re_static
, tcx
.mk_array(tcx
.types
.u8, v
.len() as u64))
408 ast
::LitKind
::Byte(_
) => tcx
.types
.u8,
409 ast
::LitKind
::Char(_
) => tcx
.types
.char,
410 ast
::LitKind
::Int(_
, ast
::LitIntType
::Signed(t
)) => tcx
.mk_mach_int(ty
::int_ty(t
)),
411 ast
::LitKind
::Int(_
, ast
::LitIntType
::Unsigned(t
)) => tcx
.mk_mach_uint(ty
::uint_ty(t
)),
412 ast
::LitKind
::Int(_
, ast
::LitIntType
::Unsuffixed
) => {
413 let opt_ty
= expected
.to_option(self).and_then(|ty
| match ty
.kind() {
414 ty
::Int(_
) | ty
::Uint(_
) => Some(ty
),
415 ty
::Char
=> Some(tcx
.types
.u8),
416 ty
::RawPtr(..) => Some(tcx
.types
.usize),
417 ty
::FnDef(..) | ty
::FnPtr(_
) => Some(tcx
.types
.usize),
420 opt_ty
.unwrap_or_else(|| self.next_int_var())
422 ast
::LitKind
::Float(_
, ast
::LitFloatType
::Suffixed(t
)) => {
423 tcx
.mk_mach_float(ty
::float_ty(t
))
425 ast
::LitKind
::Float(_
, ast
::LitFloatType
::Unsuffixed
) => {
426 let opt_ty
= expected
.to_option(self).and_then(|ty
| match ty
.kind() {
427 ty
::Float(_
) => Some(ty
),
430 opt_ty
.unwrap_or_else(|| self.next_float_var())
432 ast
::LitKind
::Bool(_
) => tcx
.types
.bool
,
433 ast
::LitKind
::Err(_
) => tcx
.ty_error(),
437 pub fn check_struct_path(
441 ) -> Option
<(&'tcx ty
::VariantDef
, Ty
<'tcx
>)> {
442 let path_span
= qpath
.qself_span();
443 let (def
, ty
) = self.finish_resolving_struct_path(qpath
, path_span
, hir_id
);
444 let variant
= match def
{
446 self.set_tainted_by_errors();
449 Res
::Def(DefKind
::Variant
, _
) => match ty
.kind() {
450 ty
::Adt(adt
, substs
) => Some((adt
.variant_of_res(def
), adt
.did
, substs
)),
451 _
=> bug
!("unexpected type: {:?}", ty
),
453 Res
::Def(DefKind
::Struct
| DefKind
::Union
| DefKind
::TyAlias
| DefKind
::AssocTy
, _
)
454 | Res
::SelfTy(..) => match ty
.kind() {
455 ty
::Adt(adt
, substs
) if !adt
.is_enum() => {
456 Some((adt
.non_enum_variant(), adt
.did
, substs
))
460 _
=> bug
!("unexpected definition: {:?}", def
),
463 if let Some((variant
, did
, substs
)) = variant
{
464 debug
!("check_struct_path: did={:?} substs={:?}", did
, substs
);
465 self.write_user_type_annotation_from_substs(hir_id
, did
, substs
, None
);
467 // Check bounds on type arguments used in the path.
468 let (bounds
, _
) = self.instantiate_bounds(path_span
, did
, substs
);
470 traits
::ObligationCause
::new(path_span
, self.body_id
, traits
::ItemObligation(did
));
471 self.add_obligations_for_parameters(cause
, bounds
);
479 "expected struct, variant or union type, found {}",
480 ty
.sort_string(self.tcx
)
482 .span_label(path_span
, "not a struct")
488 pub fn check_decl_initializer(
490 local
: &'tcx hir
::Local
<'tcx
>,
491 init
: &'tcx hir
::Expr
<'tcx
>,
493 // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
494 // for #42640 (default match binding modes).
497 let ref_bindings
= local
.pat
.contains_explicit_ref_binding();
499 let local_ty
= self.local_ty(init
.span
, local
.hir_id
).revealed_ty
;
500 if let Some(m
) = ref_bindings
{
501 // Somewhat subtle: if we have a `ref` binding in the pattern,
502 // we want to avoid introducing coercions for the RHS. This is
503 // both because it helps preserve sanity and, in the case of
504 // ref mut, for soundness (issue #23116). In particular, in
505 // the latter case, we need to be clear that the type of the
506 // referent for the reference that results is *equal to* the
507 // type of the place it is referencing, and not some
508 // supertype thereof.
509 let init_ty
= self.check_expr_with_needs(init
, Needs
::maybe_mut_place(m
));
510 self.demand_eqtype(init
.span
, local_ty
, init_ty
);
513 self.check_expr_coercable_to_type(init
, local_ty
, None
)
517 /// Type check a `let` statement.
518 pub fn check_decl_local(&self, local
: &'tcx hir
::Local
<'tcx
>) {
519 // Determine and write the type which we'll check the pattern against.
520 let ty
= self.local_ty(local
.span
, local
.hir_id
).decl_ty
;
521 self.write_ty(local
.hir_id
, ty
);
523 // Type check the initializer.
524 if let Some(ref init
) = local
.init
{
525 let init_ty
= self.check_decl_initializer(local
, &init
);
526 self.overwrite_local_ty_if_err(local
, ty
, init_ty
);
529 // Does the expected pattern type originate from an expression and what is the span?
530 let (origin_expr
, ty_span
) = match (local
.ty
, local
.init
) {
531 (Some(ty
), _
) => (false, Some(ty
.span
)), // Bias towards the explicit user type.
532 (_
, Some(init
)) => (true, Some(init
.span
)), // No explicit type; so use the scrutinee.
533 _
=> (false, None
), // We have `let $pat;`, so the expected type is unconstrained.
536 // Type check the pattern. Override if necessary to avoid knock-on errors.
537 self.check_pat_top(&local
.pat
, ty
, ty_span
, origin_expr
);
538 let pat_ty
= self.node_ty(local
.pat
.hir_id
);
539 self.overwrite_local_ty_if_err(local
, ty
, pat_ty
);
542 pub fn check_stmt(&self, stmt
: &'tcx hir
::Stmt
<'tcx
>) {
543 // Don't do all the complex logic below for `DeclItem`.
545 hir
::StmtKind
::Item(..) => return,
546 hir
::StmtKind
::Local(..) | hir
::StmtKind
::Expr(..) | hir
::StmtKind
::Semi(..) => {}
549 self.warn_if_unreachable(stmt
.hir_id
, stmt
.span
, "statement");
551 // Hide the outer diverging and `has_errors` flags.
552 let old_diverges
= self.diverges
.replace(Diverges
::Maybe
);
553 let old_has_errors
= self.has_errors
.replace(false);
556 hir
::StmtKind
::Local(ref l
) => {
557 self.check_decl_local(&l
);
560 hir
::StmtKind
::Item(_
) => {}
561 hir
::StmtKind
::Expr(ref expr
) => {
562 // Check with expected type of `()`.
563 self.check_expr_has_type_or_error(&expr
, self.tcx
.mk_unit(), |err
| {
564 self.suggest_semicolon_at_end(expr
.span
, err
);
567 hir
::StmtKind
::Semi(ref expr
) => {
568 self.check_expr(&expr
);
572 // Combine the diverging and `has_error` flags.
573 self.diverges
.set(self.diverges
.get() | old_diverges
);
574 self.has_errors
.set(self.has_errors
.get() | old_has_errors
);
577 pub fn check_block_no_value(&self, blk
: &'tcx hir
::Block
<'tcx
>) {
578 let unit
= self.tcx
.mk_unit();
579 let ty
= self.check_block_with_expected(blk
, ExpectHasType(unit
));
581 // if the block produces a `!` value, that can always be
582 // (effectively) coerced to unit.
584 self.demand_suptype(blk
.span
, unit
, ty
);
588 pub(in super::super) fn check_block_with_expected(
590 blk
: &'tcx hir
::Block
<'tcx
>,
591 expected
: Expectation
<'tcx
>,
593 let prev
= self.ps
.replace(self.ps
.get().recurse(blk
));
595 // In some cases, blocks have just one exit, but other blocks
596 // can be targeted by multiple breaks. This can happen both
597 // with labeled blocks as well as when we desugar
598 // a `try { ... }` expression.
602 // 'a: { if true { break 'a Err(()); } Ok(()) }
604 // Here we would wind up with two coercions, one from
605 // `Err(())` and the other from the tail expression
606 // `Ok(())`. If the tail expression is omitted, that's a
607 // "forced unit" -- unless the block diverges, in which
608 // case we can ignore the tail expression (e.g., `'a: {
609 // break 'a 22; }` would not force the type of the block
611 let tail_expr
= blk
.expr
.as_ref();
612 let coerce_to_ty
= expected
.coercion_target_type(self, blk
.span
);
613 let coerce
= if blk
.targeted_by_break
{
614 CoerceMany
::new(coerce_to_ty
)
616 let tail_expr
: &[&hir
::Expr
<'_
>] = match tail_expr
{
617 Some(e
) => slice
::from_ref(e
),
620 CoerceMany
::with_coercion_sites(coerce_to_ty
, tail_expr
)
623 let prev_diverges
= self.diverges
.get();
624 let ctxt
= BreakableCtxt { coerce: Some(coerce), may_break: false }
;
626 let (ctxt
, ()) = self.with_breakable_ctxt(blk
.hir_id
, ctxt
, || {
631 // check the tail expression **without** holding the
632 // `enclosing_breakables` lock below.
633 let tail_expr_ty
= tail_expr
.map(|t
| self.check_expr_with_expectation(t
, expected
));
635 let mut enclosing_breakables
= self.enclosing_breakables
.borrow_mut();
636 let ctxt
= enclosing_breakables
.find_breakable(blk
.hir_id
);
637 let coerce
= ctxt
.coerce
.as_mut().unwrap();
638 if let Some(tail_expr_ty
) = tail_expr_ty
{
639 let tail_expr
= tail_expr
.unwrap();
640 let span
= self.get_expr_coercion_span(tail_expr
);
641 let cause
= self.cause(span
, ObligationCauseCode
::BlockTailExpression(blk
.hir_id
));
642 coerce
.coerce(self, &cause
, tail_expr
, tail_expr_ty
);
644 // Subtle: if there is no explicit tail expression,
645 // that is typically equivalent to a tail expression
646 // of `()` -- except if the block diverges. In that
647 // case, there is no value supplied from the tail
648 // expression (assuming there are no other breaks,
649 // this implies that the type of the block will be
652 // #41425 -- label the implicit `()` as being the
653 // "found type" here, rather than the "expected type".
654 if !self.diverges
.get().is_always() {
655 // #50009 -- Do not point at the entire fn block span, point at the return type
656 // span, as it is the cause of the requirement, and
657 // `consider_hint_about_removing_semicolon` will point at the last expression
658 // if it were a relevant part of the error. This improves usability in editors
659 // that highlight errors inline.
660 let mut sp
= blk
.span
;
661 let mut fn_span
= None
;
662 if let Some((decl
, ident
)) = self.get_parent_fn_decl(blk
.hir_id
) {
663 let ret_sp
= decl
.output
.span();
664 if let Some(block_sp
) = self.parent_item_span(blk
.hir_id
) {
665 // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
666 // output would otherwise be incorrect and even misleading. Make sure
667 // the span we're aiming at correspond to a `fn` body.
668 if block_sp
== blk
.span
{
670 fn_span
= Some(ident
.span
);
674 coerce
.coerce_forced_unit(
678 if let Some(expected_ty
) = expected
.only_has_type(self) {
679 self.consider_hint_about_removing_semicolon(blk
, expected_ty
, err
);
681 if let Some(fn_span
) = fn_span
{
684 "implicitly returns `()` as its body has no tail or `return` \
696 // If we can break from the block, then the block's exit is always reachable
697 // (... as long as the entry is reachable) - regardless of the tail of the block.
698 self.diverges
.set(prev_diverges
);
701 let mut ty
= ctxt
.coerce
.unwrap().complete(self);
703 if self.has_errors
.get() || ty
.references_error() {
704 ty
= self.tcx
.ty_error()
707 self.write_ty(blk
.hir_id
, ty
);
713 pub(in super::super) fn check_rustc_args_require_const(
719 // We're only interested in functions tagged with
720 // #[rustc_args_required_const], so ignore anything that's not.
721 if !self.tcx
.has_attr(def_id
, sym
::rustc_args_required_const
) {
725 // If our calling expression is indeed the function itself, we're good!
726 // If not, generate an error that this can only be called directly.
727 if let Node
::Expr(expr
) = self.tcx
.hir().get(self.tcx
.hir().get_parent_node(hir_id
)) {
728 if let ExprKind
::Call(ref callee
, ..) = expr
.kind
{
729 if callee
.hir_id
== hir_id
{
735 self.tcx
.sess
.span_err(
737 "this function can only be invoked directly, not through a function pointer",
741 /// A common error is to add an extra semicolon:
744 /// fn foo() -> usize {
749 /// This routine checks if the final statement in a block is an
750 /// expression with an explicit semicolon whose type is compatible
751 /// with `expected_ty`. If so, it suggests removing the semicolon.
752 fn consider_hint_about_removing_semicolon(
754 blk
: &'tcx hir
::Block
<'tcx
>,
755 expected_ty
: Ty
<'tcx
>,
756 err
: &mut DiagnosticBuilder
<'_
>,
758 if let Some((span_semi
, boxed
)) = self.could_remove_semicolon(blk
, expected_ty
) {
759 if let StatementAsExpression
::NeedsBoxing
= boxed
{
760 err
.span_suggestion_verbose(
762 "consider removing this semicolon and boxing the expression",
764 Applicability
::HasPlaceholders
,
767 err
.span_suggestion_short(
769 "consider removing this semicolon",
771 Applicability
::MachineApplicable
,
777 fn parent_item_span(&self, id
: hir
::HirId
) -> Option
<Span
> {
778 let node
= self.tcx
.hir().get(self.tcx
.hir().get_parent_item(id
));
780 Node
::Item(&hir
::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }
)
781 | Node
::ImplItem(&hir
::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }
) => {
782 let body
= self.tcx
.hir().body(body_id
);
783 if let ExprKind
::Block(block
, _
) = &body
.value
.kind
{
784 return Some(block
.span
);
792 /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
793 fn get_parent_fn_decl(&self, blk_id
: hir
::HirId
) -> Option
<(&'tcx hir
::FnDecl
<'tcx
>, Ident
)> {
794 let parent
= self.tcx
.hir().get(self.tcx
.hir().get_parent_item(blk_id
));
795 self.get_node_fn_decl(parent
).map(|(fn_decl
, ident
, _
)| (fn_decl
, ident
))
798 /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
799 /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
800 /// when given code like the following:
802 /// if false { return 0i32; } else { 1u32 }
803 /// // ^^^^ point at this instead of the whole `if` expression
805 fn get_expr_coercion_span(&self, expr
: &hir
::Expr
<'_
>) -> rustc_span
::Span
{
806 let check_in_progress
= |elem
: &hir
::Expr
<'_
>| {
807 self.in_progress_typeck_results
808 .and_then(|typeck_results
| typeck_results
.borrow().node_type_opt(elem
.hir_id
))
813 Some(match elem
.kind
{
814 // Point at the tail expression when possible.
815 hir
::ExprKind
::Block(block
, _
) => {
816 block
.expr
.map_or(block
.span
, |e
| e
.span
)
824 if let hir
::ExprKind
::If(_
, _
, Some(el
)) = expr
.kind
{
825 if let Some(rslt
) = check_in_progress(el
) {
830 if let hir
::ExprKind
::Match(_
, arms
, _
) = expr
.kind
{
831 let mut iter
= arms
.iter().filter_map(|arm
| check_in_progress(arm
.body
));
832 if let Some(span
) = iter
.next() {
833 if iter
.next().is_none() {
842 fn overwrite_local_ty_if_err(
844 local
: &'tcx hir
::Local
<'tcx
>,
848 if ty
.references_error() {
849 // Override the types everywhere with `err()` to avoid knock on errors.
850 self.write_ty(local
.hir_id
, ty
);
851 self.write_ty(local
.pat
.hir_id
, ty
);
852 let local_ty
= LocalTy { decl_ty, revealed_ty: ty }
;
853 self.locals
.borrow_mut().insert(local
.hir_id
, local_ty
);
854 self.locals
.borrow_mut().insert(local
.pat
.hir_id
, local_ty
);
858 // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
859 // The newly resolved definition is written into `type_dependent_defs`.
860 fn finish_resolving_struct_path(
865 ) -> (Res
, Ty
<'tcx
>) {
867 QPath
::Resolved(ref maybe_qself
, ref path
) => {
868 let self_ty
= maybe_qself
.as_ref().map(|qself
| self.to_ty(qself
));
869 let ty
= AstConv
::res_to_ty(self, self_ty
, path
, true);
872 QPath
::TypeRelative(ref qself
, ref segment
) => {
873 let ty
= self.to_ty(qself
);
875 let res
= if let hir
::TyKind
::Path(QPath
::Resolved(_
, ref path
)) = qself
.kind
{
881 AstConv
::associated_path_to_ty(self, hir_id
, path_span
, ty
, res
, segment
, true);
882 let ty
= result
.map(|(ty
, _
, _
)| ty
).unwrap_or_else(|_
| self.tcx().ty_error());
883 let result
= result
.map(|(_
, kind
, def_id
)| (kind
, def_id
));
885 // Write back the new resolution.
886 self.write_resolution(hir_id
, result
);
888 (result
.map_or(Res
::Err
, |(kind
, def_id
)| Res
::Def(kind
, def_id
)), ty
)
890 QPath
::LangItem(lang_item
, span
) => {
891 self.resolve_lang_item_path(lang_item
, span
, hir_id
)
896 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
897 /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
898 /// reference a type argument. The reason to walk also the checked type is that the coerced type
899 /// can be not easily comparable with predicate type (because of coercion). If the types match
900 /// for either checked or coerced type, and there's only *one* argument that does, we point at
901 /// the corresponding argument's expression span instead of the `fn` call path span.
902 fn point_at_arg_instead_of_call_if_possible(
904 errors
: &mut Vec
<traits
::FulfillmentError
<'tcx
>>,
905 final_arg_types
: &[(usize, Ty
<'tcx
>, Ty
<'tcx
>)],
907 args
: &'tcx
[hir
::Expr
<'tcx
>],
909 // We *do not* do this for desugared call spans to keep good diagnostics when involving
911 if call_sp
.desugaring_kind().is_some() {
915 for error
in errors
{
916 // Only if the cause is somewhere inside the expression we want try to point at arg.
917 // Otherwise, it means that the cause is somewhere else and we should not change
918 // anything because we can break the correct span.
919 if !call_sp
.contains(error
.obligation
.cause
.span
) {
923 if let ty
::PredicateKind
::Trait(predicate
, _
) =
924 error
.obligation
.predicate
.kind().skip_binder()
926 // Collect the argument position for all arguments that could have caused this
927 // `FulfillmentError`.
928 let mut referenced_in
= final_arg_types
930 .map(|&(i
, checked_ty
, _
)| (i
, checked_ty
))
931 .chain(final_arg_types
.iter().map(|&(i
, _
, coerced_ty
)| (i
, coerced_ty
)))
932 .flat_map(|(i
, ty
)| {
933 let ty
= self.resolve_vars_if_possible(ty
);
934 // We walk the argument type because the argument's type could have
935 // been `Option<T>`, but the `FulfillmentError` references `T`.
936 if ty
.walk().any(|arg
| arg
== predicate
.self_ty().into()) {
942 .collect
::<Vec
<usize>>();
944 // Both checked and coerced types could have matched, thus we need to remove
947 // We sort primitive type usize here and can use unstable sort
948 referenced_in
.sort_unstable();
949 referenced_in
.dedup();
951 if let (Some(ref_in
), None
) = (referenced_in
.pop(), referenced_in
.pop()) {
952 // We make sure that only *one* argument matches the obligation failure
953 // and we assign the obligation's span to its expression's.
954 error
.obligation
.cause
.make_mut().span
= args
[ref_in
].span
;
955 error
.points_at_arg_span
= true;
961 /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
962 /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
963 /// were caused by them. If they were, we point at the corresponding type argument's span
964 /// instead of the `fn` call path span.
965 fn point_at_type_arg_instead_of_call_if_possible(
967 errors
: &mut Vec
<traits
::FulfillmentError
<'tcx
>>,
968 call_expr
: &'tcx hir
::Expr
<'tcx
>,
970 if let hir
::ExprKind
::Call(path
, _
) = &call_expr
.kind
{
971 if let hir
::ExprKind
::Path(qpath
) = &path
.kind
{
972 if let hir
::QPath
::Resolved(_
, path
) = &qpath
{
973 for error
in errors
{
974 if let ty
::PredicateKind
::Trait(predicate
, _
) =
975 error
.obligation
.predicate
.kind().skip_binder()
977 // If any of the type arguments in this path segment caused the
978 // `FullfillmentError`, point at its span (#61860).
982 .filter_map(|seg
| seg
.args
.as_ref())
983 .flat_map(|a
| a
.args
.iter())
985 if let hir
::GenericArg
::Type(hir_ty
) = &arg
{
986 if let hir
::TyKind
::Path(hir
::QPath
::TypeRelative(..)) =
989 // Avoid ICE with associated types. As this is best
990 // effort only, it's ok to ignore the case. It
991 // would trigger in `is_send::<T::AssocType>();`
992 // from `typeck-default-trait-impl-assoc-type.rs`.
994 let ty
= AstConv
::ast_ty_to_ty(self, hir_ty
);
995 let ty
= self.resolve_vars_if_possible(ty
);
996 if ty
== predicate
.self_ty() {
997 error
.obligation
.cause
.make_mut().span
= hir_ty
.span
;