diff options
Diffstat (limited to 'compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs')
-rw-r--r-- | compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 156 |
1 files changed, 69 insertions, 87 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 41f5fafe7..4def78673 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -45,12 +45,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len()); for cast in deferred_cast_checks.drain(..) { - let prev_env = self.param_env; - self.param_env = self.param_env.with_constness(cast.constness); - cast.check(self); - - self.param_env = prev_env; } *self.deferred_cast_checks.borrow_mut() = deferred_cast_checks; @@ -93,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, ) -> Ty<'tcx> { let has_error = match method { - Ok(method) => method.substs.references_error() || method.sig.references_error(), + Ok(method) => method.args.references_error() || method.sig.references_error(), Err(_) => true, }; if has_error { @@ -265,9 +260,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // fulfillment error to be more accurate. let coerced_ty = self.resolve_vars_with_obligations(coerced_ty); - let coerce_error = self - .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None) - .err(); + let coerce_error = + self.coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None).err(); if coerce_error.is_some() { return Compatibility::Incompatible(coerce_error); @@ -524,7 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // suggestions and labels are (more) correct when an arg is a // macro invocation. let normalize_span = |span: Span| -> Span { - let normalized_span = span.find_ancestor_inside(error_span).unwrap_or(span); + let normalized_span = span.find_ancestor_inside_same_ctxt(error_span).unwrap_or(span); // Sometimes macros mess up the spans, so do not normalize the // arg span to equal the error span, because that's less useful // than pointing out the arg expr in the wrong context. @@ -689,7 +683,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_label( full_call_span, - format!("arguments to this {} are incorrect", call_name), + format!("arguments to this {call_name} are incorrect"), ); } else { err = tcx.sess.struct_span_err_with_code( @@ -753,11 +747,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } errors.retain(|error| { - let Error::Invalid( - provided_idx, - expected_idx, - Compatibility::Incompatible(Some(e)), - ) = error else { return true }; + let Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(e))) = + error + else { + return true; + }; let (provided_ty, provided_span) = provided_arg_tys[*provided_idx]; let trace = mk_trace(provided_span, formal_and_expected_inputs[*expected_idx], provided_ty); @@ -796,10 +790,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, None, ); - err.span_label( - full_call_span, - format!("arguments to this {} are incorrect", call_name), - ); + err.span_label(full_call_span, format!("arguments to this {call_name} are incorrect")); if let hir::ExprKind::MethodCall(_, rcvr, _, _) = call_expr.kind && provided_idx.as_usize() == expected_idx.as_usize() @@ -874,7 +865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if ty.is_unit() { "()".to_string() } else if ty.is_suggestable(tcx, false) { - format!("/* {} */", ty) + format!("/* {ty} */") } else if let Some(fn_def_id) = fn_def_id && self.tcx.def_kind(fn_def_id).is_fn_like() && let self_implicit = @@ -931,14 +922,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (provided_ty, provided_span) = provided_arg_tys[arg_idx]; let provided_ty_name = if !has_error_or_infer([provided_ty]) { // FIXME: not suggestable, use something else - format!(" of type `{}`", provided_ty) + format!(" of type `{provided_ty}`") } else { "".to_string() }; - labels - .push((provided_span, format!("unexpected argument{}", provided_ty_name))); + labels.push((provided_span, format!("unexpected argument{provided_ty_name}"))); let mut span = provided_span; - if span.can_be_used_for_suggestions() { + if span.can_be_used_for_suggestions() + && error_span.can_be_used_for_suggestions() + { if arg_idx.index() > 0 && let Some((_, prev)) = provided_arg_tys .get(ProvidedIdx::from_usize(arg_idx.index() - 1) @@ -1009,11 +1001,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { args_span }; let rendered = if !has_error_or_infer([input_ty]) { - format!(" of type `{}`", input_ty) + format!(" of type `{input_ty}`") } else { "".to_string() }; - labels.push((span, format!("an argument{} is missing", rendered))); + labels.push((span, format!("an argument{rendered} is missing"))); suggestion_text = match suggestion_text { SuggestionText::None => SuggestionText::Provide(false), SuggestionText::Provide(_) => SuggestionText::Provide(true), @@ -1034,13 +1026,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rendered = if !has_error_or_infer([first_expected_ty, second_expected_ty]) { format!( - " of type `{}` and `{}`", - first_expected_ty, second_expected_ty + " of type `{first_expected_ty}` and `{second_expected_ty}`" ) } else { "".to_string() }; - labels.push((span, format!("two arguments{} are missing", rendered))); + labels.push((span, format!("two arguments{rendered} are missing"))); suggestion_text = match suggestion_text { SuggestionText::None | SuggestionText::Provide(_) => { SuggestionText::Provide(true) @@ -1066,13 +1057,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { third_expected_ty, ]) { format!( - " of type `{}`, `{}`, and `{}`", - first_expected_ty, second_expected_ty, third_expected_ty + " of type `{first_expected_ty}`, `{second_expected_ty}`, and `{third_expected_ty}`" ) } else { "".to_string() }; - labels.push((span, format!("three arguments{} are missing", rendered))); + labels.push((span, format!("three arguments{rendered} are missing"))); suggestion_text = match suggestion_text { SuggestionText::None | SuggestionText::Provide(_) => { SuggestionText::Provide(true) @@ -1113,25 +1103,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (first_provided_ty, first_span) = provided_arg_tys[first_provided_idx]; let (_, first_expected_ty) = formal_and_expected_inputs[first_expected_idx]; let first_provided_ty_name = if !has_error_or_infer([first_provided_ty]) { - format!(", found `{}`", first_provided_ty) + format!(", found `{first_provided_ty}`") } else { String::new() }; labels.push(( first_span, - format!("expected `{}`{}", first_expected_ty, first_provided_ty_name), + format!("expected `{first_expected_ty}`{first_provided_ty_name}"), )); let (second_provided_ty, second_span) = provided_arg_tys[second_provided_idx]; let (_, second_expected_ty) = formal_and_expected_inputs[second_expected_idx]; let second_provided_ty_name = if !has_error_or_infer([second_provided_ty]) { - format!(", found `{}`", second_provided_ty) + format!(", found `{second_provided_ty}`") } else { String::new() }; labels.push(( second_span, - format!("expected `{}`{}", second_expected_ty, second_provided_ty_name), + format!("expected `{second_expected_ty}`{second_provided_ty_name}"), )); suggestion_text = match suggestion_text { @@ -1144,13 +1134,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (_, expected_ty) = formal_and_expected_inputs[dst_arg]; let (provided_ty, provided_span) = provided_arg_tys[dest_input]; let provided_ty_name = if !has_error_or_infer([provided_ty]) { - format!(", found `{}`", provided_ty) + format!(", found `{provided_ty}`") } else { String::new() }; labels.push(( provided_span, - format!("expected `{}`{}", expected_ty, provided_ty_name), + format!("expected `{expected_ty}`{provided_ty_name}"), )); } @@ -1231,22 +1221,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; if let Some(suggestion_text) = suggestion_text { let source_map = self.sess().source_map(); - let (mut suggestion, suggestion_span) = - if let Some(call_span) = full_call_span.find_ancestor_inside(error_span) { - ("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi())) - } else { - ( - format!( - "{}(", - source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| { - fn_def_id.map_or("".to_string(), |fn_def_id| { - tcx.item_name(fn_def_id).to_string() - }) + let (mut suggestion, suggestion_span) = if let Some(call_span) = + full_call_span.find_ancestor_inside_same_ctxt(error_span) + { + ("(".to_string(), call_span.shrink_to_hi().to(error_span.shrink_to_hi())) + } else { + ( + format!( + "{}(", + source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| { + fn_def_id.map_or("".to_string(), |fn_def_id| { + tcx.item_name(fn_def_id).to_string() }) - ), - error_span, - ) - }; + }) + ), + error_span, + ) + }; let mut needs_comma = false; for (expected_idx, provided_idx) in matched_inputs.iter_enumerated() { if needs_comma { @@ -1366,29 +1357,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Res::Def(DefKind::Variant, _) => match ty.normalized.ty_adt_def() { Some(adt) => { - Some((adt.variant_of_res(def), adt.did(), Self::user_substs_for_adt(ty))) + Some((adt.variant_of_res(def), adt.did(), Self::user_args_for_adt(ty))) } _ => bug!("unexpected type: {:?}", ty.normalized), }, - Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) + Res::Def( + DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy, + _, + ) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() { Some(adt) if !adt.is_enum() => { - Some((adt.non_enum_variant(), adt.did(), Self::user_substs_for_adt(ty))) + Some((adt.non_enum_variant(), adt.did(), Self::user_args_for_adt(ty))) } _ => None, }, _ => bug!("unexpected definition: {:?}", def), }; - if let Some((variant, did, ty::UserSubsts { substs, user_self_ty })) = variant { - debug!("check_struct_path: did={:?} substs={:?}", did, substs); + if let Some((variant, did, ty::UserArgs { args, user_self_ty })) = variant { + debug!("check_struct_path: did={:?} args={:?}", did, args); // Register type annotation. - self.write_user_type_annotation_from_substs(hir_id, did, substs, user_self_ty); + self.write_user_type_annotation_from_args(hir_id, did, args, user_self_ty); // Check bounds on type arguments used in the path. - self.add_required_obligations_for_hir(path_span, did, substs, hir_id); + self.add_required_obligations_for_hir(path_span, did, args, hir_id); Ok((variant, ty.normalized)) } else { @@ -1474,11 +1468,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Type check the pattern. Override if necessary to avoid knock-on errors. - self.check_pat_top(&decl.pat, decl_ty, ty_span, origin_expr); + self.check_pat_top(&decl.pat, decl_ty, ty_span, origin_expr, Some(decl.origin)); let pat_ty = self.node_ty(decl.pat.hir_id); self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, pat_ty); - if let Some(blk) = decl.els { + if let Some(blk) = decl.origin.try_get_else() { let previous_diverges = self.diverges.get(); let else_ty = self.check_block_with_expected(blk, NoExpectation); let cause = self.cause(blk.span, ObligationCauseCode::LetElse); @@ -1496,7 +1490,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_decl(local.into()); } - pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>, is_last: bool) { + pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) { // Don't do all the complex logic below for `DeclItem`. match stmt.kind { hir::StmtKind::Item(..) => return, @@ -1523,14 +1517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } hir::StmtKind::Semi(ref expr) => { - // All of this is equivalent to calling `check_expr`, but it is inlined out here - // in order to capture the fact that this `match` is the last statement in its - // function. This is done for better suggestions to remove the `;`. - let expectation = match expr.kind { - hir::ExprKind::Match(..) if is_last => IsLast(stmt.span), - _ => NoExpectation, - }; - self.check_expr_with_expectation(expr, expectation); + self.check_expr(expr); } } @@ -1581,8 +1568,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false }; let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || { - for (pos, s) in blk.stmts.iter().enumerate() { - self.check_stmt(s, blk.stmts.len() - 1 == pos); + for s in blk.stmts { + self.check_stmt(s); } // check the tail expression **without** holding the @@ -1595,7 +1582,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let coerce = ctxt.coerce.as_mut().unwrap(); if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty { let span = self.get_expr_coercion_span(tail_expr); - let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id)); + let cause = self.cause( + span, + ObligationCauseCode::BlockTailExpression(blk.hir_id, hir::MatchSource::Normal), + ); let ty_for_diagnostic = coerce.merged_ty(); // We use coerce_inner here because we want to augment the error // suggesting to wrap the block in square brackets if it might've @@ -1605,9 +1595,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &cause, Some(tail_expr), tail_expr_ty, - Some(&mut |diag: &mut Diagnostic| { + |diag| { self.suggest_block_to_brackets(diag, blk, tail_expr_ty, ty_for_diagnostic); - }), + }, false, ); } else { @@ -1644,7 +1634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { coerce.coerce_forced_unit( self, &self.misc(sp), - &mut |err| { + |err| { if let Some(expected_ty) = expected.only_has_type(self) { if blk.stmts.is_empty() && blk.expr.is_none() { self.suggest_boxing_when_appropriate( @@ -1867,19 +1857,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.adjust_fulfillment_error_for_expr_obligation(error) || before_span != error.obligation.cause.span { - // Store both the predicate and the predicate *without constness* - // since sometimes we instantiate and check both of these in a - // method call, for example. remap_cause.insert(( before_span, error.obligation.predicate, error.obligation.cause.clone(), )); - remap_cause.insert(( - before_span, - error.obligation.predicate.without_const(self.tcx), - error.obligation.cause.clone(), - )); } else { // If it failed to be adjusted once around, it may be adjusted // via the "remap cause" mapping the second time... @@ -2031,7 +2013,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { ("closure", self.tcx.def_span(def_id)) }; - err.span_note(span, format!("{} defined here", kind)); + err.span_note(span, format!("{kind} defined here")); } else { err.span_note( self.tcx.def_span(def_id), |