summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs156
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),