mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Rollup merge of #96065 - TaKO8Ki:use-format-args-capture
-and-remove-unnecessary-nested-blocks, r=compiler-errors
Refactor: Use `format-args-capture` and remove unnecessary nested blocks in rustc_typeck
This commit is contained in:
commit
fa281fdf65
@ -260,10 +260,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&mut |err| {
|
&mut |err| {
|
||||||
if let Some((span, msg)) = &ret_reason {
|
if let Some((span, msg)) = &ret_reason {
|
||||||
err.span_label(*span, msg.as_str());
|
err.span_label(*span, msg.as_str());
|
||||||
} else if let ExprKind::Block(block, _) = &then_expr.kind {
|
} else if let ExprKind::Block(block, _) = &then_expr.kind
|
||||||
if let Some(expr) = &block.expr {
|
&& let Some(expr) = &block.expr
|
||||||
err.span_label(expr.span, "found here".to_string());
|
{
|
||||||
}
|
err.span_label(expr.span, "found here".to_string());
|
||||||
}
|
}
|
||||||
err.note("`if` expressions without `else` evaluate to `()`");
|
err.note("`if` expressions without `else` evaluate to `()`");
|
||||||
err.help("consider adding an `else` block that evaluates to the expected type");
|
err.help("consider adding an `else` block that evaluates to the expected type");
|
||||||
@ -293,7 +293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| {
|
return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| {
|
||||||
let span = fn_decl.output.span();
|
let span = fn_decl.output.span();
|
||||||
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
|
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
|
||||||
Some((span, format!("expected `{}` because of this return type", snippet)))
|
Some((span, format!("expected `{snippet}` because of this return type")))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ pub fn check_legal_trait_for_method_call(
|
|||||||
let (sp, suggestion) = receiver
|
let (sp, suggestion) = receiver
|
||||||
.and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
|
.and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
|
||||||
.filter(|snippet| !snippet.is_empty())
|
.filter(|snippet| !snippet.is_empty())
|
||||||
.map(|snippet| (expr_span, format!("drop({})", snippet)))
|
.map(|snippet| (expr_span, format!("drop({snippet})")))
|
||||||
.unwrap_or_else(|| (span, "drop".to_string()));
|
.unwrap_or_else(|| (span, "drop".to_string()));
|
||||||
|
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
@ -315,17 +315,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
hir::ExprKind::Tup(exp),
|
hir::ExprKind::Tup(exp),
|
||||||
hir::ExprKind::Call(_, args),
|
hir::ExprKind::Call(_, args),
|
||||||
) = (parent_node, &callee_expr.kind, &call_expr.kind)
|
) = (parent_node, &callee_expr.kind, &call_expr.kind)
|
||||||
|
&& args.len() == exp.len()
|
||||||
{
|
{
|
||||||
if args.len() == exp.len() {
|
let start = callee_expr.span.shrink_to_hi();
|
||||||
let start = callee_expr.span.shrink_to_hi();
|
err.span_suggestion(
|
||||||
err.span_suggestion(
|
start,
|
||||||
start,
|
"consider separating array elements with a comma",
|
||||||
"consider separating array elements with a comma",
|
",".to_string(),
|
||||||
",".to_string(),
|
Applicability::MaybeIncorrect,
|
||||||
Applicability::MaybeIncorrect,
|
);
|
||||||
);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -373,15 +372,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
ref t => {
|
ref t => {
|
||||||
let mut unit_variant = None;
|
let mut unit_variant = None;
|
||||||
let mut removal_span = call_expr.span;
|
let mut removal_span = call_expr.span;
|
||||||
if let ty::Adt(adt_def, ..) = t {
|
if let ty::Adt(adt_def, ..) = t
|
||||||
if adt_def.is_enum() {
|
&& adt_def.is_enum()
|
||||||
if let hir::ExprKind::Call(expr, _) = call_expr.kind {
|
&& let hir::ExprKind::Call(expr, _) = call_expr.kind
|
||||||
removal_span =
|
{
|
||||||
expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
|
removal_span =
|
||||||
unit_variant =
|
expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
|
||||||
self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
|
unit_variant =
|
||||||
}
|
self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let callee_ty = self.resolve_vars_if_possible(callee_ty);
|
let callee_ty = self.resolve_vars_if_possible(callee_ty);
|
||||||
@ -392,8 +390,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
E0618,
|
E0618,
|
||||||
"expected function, found {}",
|
"expected function, found {}",
|
||||||
match unit_variant {
|
match unit_variant {
|
||||||
Some(ref path) => format!("enum variant `{}`", path),
|
Some(ref path) => format!("enum variant `{path}`"),
|
||||||
None => format!("`{}`", callee_ty),
|
None => format!("`{callee_ty}`"),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
removal_span,
|
removal_span,
|
||||||
&format!(
|
&format!(
|
||||||
"`{}` is a unit variant, you need to write it without the parentheses",
|
"`{path}` is a unit variant, you need to write it without the parentheses",
|
||||||
path
|
|
||||||
),
|
),
|
||||||
String::new(),
|
String::new(),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
@ -452,14 +449,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if let Some(span) = self.tcx.hir().res_span(def) {
|
if let Some(span) = self.tcx.hir().res_span(def) {
|
||||||
let callee_ty = callee_ty.to_string();
|
let callee_ty = callee_ty.to_string();
|
||||||
let label = match (unit_variant, inner_callee_path) {
|
let label = match (unit_variant, inner_callee_path) {
|
||||||
(Some(path), _) => Some(format!("`{}` defined here", path)),
|
(Some(path), _) => Some(format!("`{path}` defined here")),
|
||||||
(_, Some(hir::QPath::Resolved(_, path))) => self
|
(_, Some(hir::QPath::Resolved(_, path))) => self
|
||||||
.tcx
|
.tcx
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(path.span)
|
.span_to_snippet(path.span)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|p| format!("`{}` defined here returns `{}`", p, callee_ty)),
|
.map(|p| format!("`{p}` defined here returns `{callee_ty}`")),
|
||||||
_ => {
|
_ => {
|
||||||
match def {
|
match def {
|
||||||
// Emit a different diagnostic for local variables, as they are not
|
// Emit a different diagnostic for local variables, as they are not
|
||||||
@ -475,7 +472,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.tcx.def_path_str(def_id),
|
self.tcx.def_path_str(def_id),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => Some(format!("`{}` defined here", callee_ty)),
|
_ => Some(format!("`{callee_ty}` defined here")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -322,7 +322,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.span,
|
self.span,
|
||||||
"compare with zero instead",
|
"compare with zero instead",
|
||||||
format!("{} != 0", snippet),
|
format!("{snippet} != 0"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -373,8 +373,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
let mut sugg = None;
|
let mut sugg = None;
|
||||||
let mut sugg_mutref = false;
|
let mut sugg_mutref = false;
|
||||||
if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
|
if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
|
||||||
if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind() {
|
if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind()
|
||||||
if fcx
|
&& fcx
|
||||||
.try_coerce(
|
.try_coerce(
|
||||||
self.expr,
|
self.expr,
|
||||||
fcx.tcx.mk_ref(
|
fcx.tcx.mk_ref(
|
||||||
@ -386,27 +386,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty));
|
sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty));
|
||||||
}
|
} else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind()
|
||||||
} else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() {
|
&& expr_mutbl == Mutability::Not
|
||||||
if expr_mutbl == Mutability::Not
|
&& mutbl == Mutability::Mut
|
||||||
&& mutbl == Mutability::Mut
|
&& fcx
|
||||||
&& fcx
|
.try_coerce(
|
||||||
.try_coerce(
|
self.expr,
|
||||||
self.expr,
|
fcx.tcx.mk_ref(
|
||||||
fcx.tcx.mk_ref(
|
expr_reg,
|
||||||
expr_reg,
|
TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
|
||||||
TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
|
),
|
||||||
),
|
self.cast_ty,
|
||||||
self.cast_ty,
|
AllowTwoPhase::No,
|
||||||
AllowTwoPhase::No,
|
None,
|
||||||
None,
|
)
|
||||||
)
|
.is_ok()
|
||||||
.is_ok()
|
{
|
||||||
{
|
sugg_mutref = true;
|
||||||
sugg_mutref = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sugg_mutref
|
if !sugg_mutref
|
||||||
@ -423,8 +421,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
{
|
{
|
||||||
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
|
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
|
||||||
}
|
}
|
||||||
} else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind() {
|
} else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind()
|
||||||
if fcx
|
&& fcx
|
||||||
.try_coerce(
|
.try_coerce(
|
||||||
self.expr,
|
self.expr,
|
||||||
fcx.tcx.mk_ref(
|
fcx.tcx.mk_ref(
|
||||||
@ -436,9 +434,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
|
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if sugg_mutref {
|
if sugg_mutref {
|
||||||
err.span_label(self.span, "invalid cast");
|
err.span_label(self.span, "invalid cast");
|
||||||
@ -483,28 +480,28 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
) {
|
) {
|
||||||
let mut label = true;
|
let mut label = true;
|
||||||
// Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
|
// Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
|
||||||
if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) {
|
if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span)
|
||||||
if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) {
|
&& let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From)
|
||||||
let ty = fcx.resolve_vars_if_possible(self.cast_ty);
|
{
|
||||||
// Erase regions to avoid panic in `prove_value` when calling
|
let ty = fcx.resolve_vars_if_possible(self.cast_ty);
|
||||||
// `type_implements_trait`.
|
// Erase regions to avoid panic in `prove_value` when calling
|
||||||
let ty = fcx.tcx.erase_regions(ty);
|
// `type_implements_trait`.
|
||||||
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
|
let ty = fcx.tcx.erase_regions(ty);
|
||||||
let expr_ty = fcx.tcx.erase_regions(expr_ty);
|
let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
|
||||||
let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
|
let expr_ty = fcx.tcx.erase_regions(expr_ty);
|
||||||
if fcx
|
let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
|
||||||
.infcx
|
if fcx
|
||||||
.type_implements_trait(from_trait, ty, ty_params, fcx.param_env)
|
.infcx
|
||||||
.must_apply_modulo_regions()
|
.type_implements_trait(from_trait, ty, ty_params, fcx.param_env)
|
||||||
{
|
.must_apply_modulo_regions()
|
||||||
label = false;
|
{
|
||||||
err.span_suggestion(
|
label = false;
|
||||||
self.span,
|
err.span_suggestion(
|
||||||
"consider using the `From` trait instead",
|
self.span,
|
||||||
format!("{}::from({})", self.cast_ty, snippet),
|
"consider using the `From` trait instead",
|
||||||
Applicability::MaybeIncorrect,
|
format!("{}::from({})", self.cast_ty, snippet),
|
||||||
);
|
Applicability::MaybeIncorrect,
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let msg = "an `as` expression can only be used to convert between primitive \
|
let msg = "an `as` expression can only be used to convert between primitive \
|
||||||
@ -627,10 +624,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = &format!(
|
let msg =
|
||||||
"consider using an implicit coercion to `&{}{}` instead",
|
&format!("consider using an implicit coercion to `&{mtstr}{tstr}` instead");
|
||||||
mtstr, tstr
|
|
||||||
);
|
|
||||||
err.span_help(self.span, msg);
|
err.span_help(self.span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,14 +635,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.cast_span,
|
self.cast_span,
|
||||||
"you can cast to a `Box` instead",
|
"you can cast to a `Box` instead",
|
||||||
format!("Box<{}>", s),
|
format!("Box<{s}>"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
err.span_help(
|
err.span_help(
|
||||||
self.cast_span,
|
self.cast_span,
|
||||||
&format!("you might have meant `Box<{}>`", tstr),
|
&format!("you might have meant `Box<{tstr}>`"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -678,8 +673,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
))
|
))
|
||||||
.help(&format!(
|
.help(&format!(
|
||||||
"cast can be replaced by coercion; this might \
|
"cast can be replaced by coercion; this might \
|
||||||
require {}a temporary variable",
|
require {type_asc_or}a temporary variable"
|
||||||
type_asc_or
|
|
||||||
))
|
))
|
||||||
.emit();
|
.emit();
|
||||||
});
|
});
|
||||||
@ -969,21 +963,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
||||||
if let ty::Adt(d, _) = self.expr_ty.kind() {
|
if let ty::Adt(d, _) = self.expr_ty.kind()
|
||||||
if d.has_dtor(fcx.tcx) {
|
&& d.has_dtor(fcx.tcx)
|
||||||
fcx.tcx.struct_span_lint_hir(
|
{
|
||||||
lint::builtin::CENUM_IMPL_DROP_CAST,
|
fcx.tcx.struct_span_lint_hir(
|
||||||
self.expr.hir_id,
|
lint::builtin::CENUM_IMPL_DROP_CAST,
|
||||||
self.span,
|
self.expr.hir_id,
|
||||||
|err| {
|
self.span,
|
||||||
err.build(&format!(
|
|err| {
|
||||||
"cannot cast enum `{}` into integer `{}` because it implements `Drop`",
|
err.build(&format!(
|
||||||
self.expr_ty, self.cast_ty
|
"cannot cast enum `{}` into integer `{}` because it implements `Drop`",
|
||||||
))
|
self.expr_ty, self.cast_ty
|
||||||
.emit();
|
))
|
||||||
},
|
.emit();
|
||||||
);
|
},
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,7 +1001,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.span,
|
self.span,
|
||||||
msg,
|
msg,
|
||||||
format!("({}).addr(){}", snippet, scalar_cast),
|
format!("({snippet}).addr(){scalar_cast}"),
|
||||||
Applicability::MaybeIncorrect
|
Applicability::MaybeIncorrect
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -1038,7 +1032,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.span,
|
self.span,
|
||||||
msg,
|
msg,
|
||||||
format!("(...).with_addr({})", snippet),
|
format!("(...).with_addr({snippet})"),
|
||||||
Applicability::HasPlaceholders,
|
Applicability::HasPlaceholders,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,8 +43,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
|
|||||||
tcx.sess,
|
tcx.sess,
|
||||||
span,
|
span,
|
||||||
E0570,
|
E0570,
|
||||||
"`{}` is not a supported ABI for the current target",
|
"`{abi}` is not a supported ABI for the current target",
|
||||||
abi
|
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
@ -249,84 +248,84 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||||||
fcx.demand_suptype(span, declared_ret_ty, actual_return_ty);
|
fcx.demand_suptype(span, declared_ret_ty, actual_return_ty);
|
||||||
|
|
||||||
// Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
|
// Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
|
||||||
if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
|
if let Some(panic_impl_did) = tcx.lang_items().panic_impl()
|
||||||
if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
|
&& panic_impl_did == hir.local_def_id(fn_id).to_def_id()
|
||||||
if let Some(panic_info_did) = tcx.lang_items().panic_info() {
|
{
|
||||||
if *declared_ret_ty.kind() != ty::Never {
|
if let Some(panic_info_did) = tcx.lang_items().panic_info() {
|
||||||
sess.span_err(decl.output.span(), "return type should be `!`");
|
if *declared_ret_ty.kind() != ty::Never {
|
||||||
}
|
sess.span_err(decl.output.span(), "return type should be `!`");
|
||||||
|
|
||||||
let inputs = fn_sig.inputs();
|
|
||||||
let span = hir.span(fn_id);
|
|
||||||
if inputs.len() == 1 {
|
|
||||||
let arg_is_panic_info = match *inputs[0].kind() {
|
|
||||||
ty::Ref(region, ty, mutbl) => match *ty.kind() {
|
|
||||||
ty::Adt(ref adt, _) => {
|
|
||||||
adt.did() == panic_info_did
|
|
||||||
&& mutbl == hir::Mutability::Not
|
|
||||||
&& !region.is_static()
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !arg_is_panic_info {
|
|
||||||
sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Node::Item(item) = hir.get(fn_id)
|
|
||||||
&& let ItemKind::Fn(_, ref generics, _) = item.kind
|
|
||||||
&& !generics.params.is_empty()
|
|
||||||
{
|
|
||||||
sess.span_err(span, "should have no type parameters");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let span = sess.source_map().guess_head_span(span);
|
|
||||||
sess.span_err(span, "function should have one argument");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sess.err("language item required, but not found: `panic_info`");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inputs = fn_sig.inputs();
|
||||||
|
let span = hir.span(fn_id);
|
||||||
|
if inputs.len() == 1 {
|
||||||
|
let arg_is_panic_info = match *inputs[0].kind() {
|
||||||
|
ty::Ref(region, ty, mutbl) => match *ty.kind() {
|
||||||
|
ty::Adt(ref adt, _) => {
|
||||||
|
adt.did() == panic_info_did
|
||||||
|
&& mutbl == hir::Mutability::Not
|
||||||
|
&& !region.is_static()
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !arg_is_panic_info {
|
||||||
|
sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Node::Item(item) = hir.get(fn_id)
|
||||||
|
&& let ItemKind::Fn(_, ref generics, _) = item.kind
|
||||||
|
&& !generics.params.is_empty()
|
||||||
|
{
|
||||||
|
sess.span_err(span, "should have no type parameters");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let span = sess.source_map().guess_head_span(span);
|
||||||
|
sess.span_err(span, "function should have one argument");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sess.err("language item required, but not found: `panic_info`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
|
// Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
|
||||||
if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
|
if let Some(alloc_error_handler_did) = tcx.lang_items().oom()
|
||||||
if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
|
&& alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id()
|
||||||
if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
|
{
|
||||||
if *declared_ret_ty.kind() != ty::Never {
|
if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
|
||||||
sess.span_err(decl.output.span(), "return type should be `!`");
|
if *declared_ret_ty.kind() != ty::Never {
|
||||||
}
|
sess.span_err(decl.output.span(), "return type should be `!`");
|
||||||
|
|
||||||
let inputs = fn_sig.inputs();
|
|
||||||
let span = hir.span(fn_id);
|
|
||||||
if inputs.len() == 1 {
|
|
||||||
let arg_is_alloc_layout = match inputs[0].kind() {
|
|
||||||
ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !arg_is_alloc_layout {
|
|
||||||
sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Node::Item(item) = hir.get(fn_id)
|
|
||||||
&& let ItemKind::Fn(_, ref generics, _) = item.kind
|
|
||||||
&& !generics.params.is_empty()
|
|
||||||
{
|
|
||||||
sess.span_err(
|
|
||||||
span,
|
|
||||||
"`#[alloc_error_handler]` function should have no type parameters",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let span = sess.source_map().guess_head_span(span);
|
|
||||||
sess.span_err(span, "function should have one argument");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sess.err("language item required, but not found: `alloc_layout`");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inputs = fn_sig.inputs();
|
||||||
|
let span = hir.span(fn_id);
|
||||||
|
if inputs.len() == 1 {
|
||||||
|
let arg_is_alloc_layout = match inputs[0].kind() {
|
||||||
|
ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !arg_is_alloc_layout {
|
||||||
|
sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Node::Item(item) = hir.get(fn_id)
|
||||||
|
&& let ItemKind::Fn(_, ref generics, _) = item.kind
|
||||||
|
&& !generics.params.is_empty()
|
||||||
|
{
|
||||||
|
sess.span_err(
|
||||||
|
span,
|
||||||
|
"`#[alloc_error_handler]` function should have no type parameters",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let span = sess.source_map().guess_head_span(span);
|
||||||
|
sess.span_err(span, "function should have one argument");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sess.err("language item required, but not found: `alloc_layout`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +669,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||||||
Err(ty_err) => {
|
Err(ty_err) => {
|
||||||
tcx.sess.delay_span_bug(
|
tcx.sess.delay_span_bug(
|
||||||
span,
|
span,
|
||||||
&format!("could not unify `{}` with revealed type:\n{}", hidden_type, ty_err,),
|
&format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -817,10 +816,9 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
|
|||||||
tcx.sess,
|
tcx.sess,
|
||||||
item.span,
|
item.span,
|
||||||
E0044,
|
E0044,
|
||||||
"foreign items may not have {} parameters",
|
"foreign items may not have {kinds} parameters",
|
||||||
kinds,
|
|
||||||
)
|
)
|
||||||
.span_label(item.span, &format!("can't have {} parameters", kinds))
|
.span_label(item.span, &format!("can't have {kinds} parameters"))
|
||||||
.help(
|
.help(
|
||||||
// FIXME: once we start storing spans for type arguments, turn this
|
// FIXME: once we start storing spans for type arguments, turn this
|
||||||
// into a suggestion.
|
// into a suggestion.
|
||||||
@ -1065,68 +1063,67 @@ pub(super) fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalD
|
|||||||
|
|
||||||
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
|
||||||
let t = tcx.type_of(def_id);
|
let t = tcx.type_of(def_id);
|
||||||
if let ty::Adt(def, substs) = t.kind() {
|
if let ty::Adt(def, substs) = t.kind()
|
||||||
if def.is_struct() {
|
&& def.is_struct()
|
||||||
let fields = &def.non_enum_variant().fields;
|
{
|
||||||
if fields.is_empty() {
|
let fields = &def.non_enum_variant().fields;
|
||||||
|
if fields.is_empty() {
|
||||||
|
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let e = fields[0].ty(tcx, substs);
|
||||||
|
if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
|
||||||
|
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
|
||||||
|
.span_label(sp, "SIMD elements must have the same type")
|
||||||
|
.emit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = if let ty::Array(_ty, c) = e.kind() {
|
||||||
|
c.try_eval_usize(tcx, tcx.param_env(def.did()))
|
||||||
|
} else {
|
||||||
|
Some(fields.len() as u64)
|
||||||
|
};
|
||||||
|
if let Some(len) = len {
|
||||||
|
if len == 0 {
|
||||||
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
|
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
|
||||||
return;
|
return;
|
||||||
}
|
} else if len > MAX_SIMD_LANES {
|
||||||
let e = fields[0].ty(tcx, substs);
|
struct_span_err!(
|
||||||
if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
|
tcx.sess,
|
||||||
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
|
sp,
|
||||||
.span_label(sp, "SIMD elements must have the same type")
|
E0075,
|
||||||
.emit();
|
"SIMD vector cannot have more than {MAX_SIMD_LANES} elements",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let len = if let ty::Array(_ty, c) = e.kind() {
|
// Check that we use types valid for use in the lanes of a SIMD "vector register"
|
||||||
c.try_eval_usize(tcx, tcx.param_env(def.did()))
|
// These are scalar types which directly match a "machine" type
|
||||||
} else {
|
// Yes: Integers, floats, "thin" pointers
|
||||||
Some(fields.len() as u64)
|
// No: char, "fat" pointers, compound types
|
||||||
};
|
match e.kind() {
|
||||||
if let Some(len) = len {
|
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
|
||||||
if len == 0 {
|
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
|
||||||
struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
|
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
|
||||||
return;
|
ty::Array(t, _clen)
|
||||||
} else if len > MAX_SIMD_LANES {
|
if matches!(
|
||||||
struct_span_err!(
|
t.kind(),
|
||||||
tcx.sess,
|
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)
|
||||||
sp,
|
) =>
|
||||||
E0075,
|
{ /* struct([f32; 4]) is ok */ }
|
||||||
"SIMD vector cannot have more than {} elements",
|
_ => {
|
||||||
MAX_SIMD_LANES,
|
struct_span_err!(
|
||||||
)
|
tcx.sess,
|
||||||
.emit();
|
sp,
|
||||||
return;
|
E0077,
|
||||||
}
|
"SIMD vector element type should be a \
|
||||||
}
|
primitive scalar (integer/float/pointer) type"
|
||||||
|
)
|
||||||
// Check that we use types valid for use in the lanes of a SIMD "vector register"
|
.emit();
|
||||||
// These are scalar types which directly match a "machine" type
|
return;
|
||||||
// Yes: Integers, floats, "thin" pointers
|
|
||||||
// No: char, "fat" pointers, compound types
|
|
||||||
match e.kind() {
|
|
||||||
ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
|
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
|
|
||||||
ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
|
|
||||||
ty::Array(t, _clen)
|
|
||||||
if matches!(
|
|
||||||
t.kind(),
|
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)
|
|
||||||
) =>
|
|
||||||
{ /* struct([f32; 4]) is ok */ }
|
|
||||||
_ => {
|
|
||||||
struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
sp,
|
|
||||||
E0077,
|
|
||||||
"SIMD vector element type should be a \
|
|
||||||
primitive scalar (integer/float/pointer) type"
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1189,7 +1186,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
|
|||||||
ident
|
ident
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!("...which contains a field of type `{}`", ident)
|
format!("...which contains a field of type `{ident}`")
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
first = false;
|
first = false;
|
||||||
@ -1215,13 +1212,12 @@ pub(super) fn check_packed_inner(
|
|||||||
|
|
||||||
stack.push(def_id);
|
stack.push(def_id);
|
||||||
for field in &def.non_enum_variant().fields {
|
for field in &def.non_enum_variant().fields {
|
||||||
if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
|
if let ty::Adt(def, _) = field.ty(tcx, substs).kind()
|
||||||
if !stack.contains(&def.did()) {
|
&& !stack.contains(&def.did())
|
||||||
if let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) {
|
&& let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
|
||||||
defs.push((def.did(), field.ident(tcx).span));
|
{
|
||||||
return Some(defs);
|
defs.push((def.did(), field.ident(tcx).span));
|
||||||
}
|
return Some(defs);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack.pop();
|
stack.pop();
|
||||||
@ -1370,8 +1366,8 @@ fn check_enum<'tcx>(
|
|||||||
"discriminant value `{}` already exists",
|
"discriminant value `{}` already exists",
|
||||||
discr.val,
|
discr.val,
|
||||||
)
|
)
|
||||||
.span_label(i_span, format!("first use of {}", display_discr_i))
|
.span_label(i_span, format!("first use of {display_discr_i}"))
|
||||||
.span_label(span, format!("enum already has {}", display_discr))
|
.span_label(span, format!("enum already has {display_discr}"))
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
disr_vals.push(discr);
|
disr_vals.push(discr);
|
||||||
@ -1393,7 +1389,7 @@ fn display_discriminant_value<'tcx>(
|
|||||||
&& let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
|
&& let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
|
||||||
&& evaluated != *lit_value
|
&& evaluated != *lit_value
|
||||||
{
|
{
|
||||||
return format!("`{}` (overflowed from `{}`)", evaluated, lit_value);
|
return format!("`{evaluated}` (overflowed from `{lit_value}`)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
format!("`{}`", evaluated)
|
format!("`{}`", evaluated)
|
||||||
@ -1422,28 +1418,28 @@ pub(super) fn check_type_params_are_used<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for leaf in ty.walk() {
|
for leaf in ty.walk() {
|
||||||
if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
|
if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
|
||||||
if let ty::Param(param) = leaf_ty.kind() {
|
&& let ty::Param(param) = leaf_ty.kind()
|
||||||
debug!("found use of ty param {:?}", param);
|
{
|
||||||
params_used.insert(param.index);
|
debug!("found use of ty param {:?}", param);
|
||||||
}
|
params_used.insert(param.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for param in &generics.params {
|
for param in &generics.params {
|
||||||
if !params_used.contains(param.index) {
|
if !params_used.contains(param.index)
|
||||||
if let ty::GenericParamDefKind::Type { .. } = param.kind {
|
&& let ty::GenericParamDefKind::Type { .. } = param.kind
|
||||||
let span = tcx.def_span(param.def_id);
|
{
|
||||||
struct_span_err!(
|
let span = tcx.def_span(param.def_id);
|
||||||
tcx.sess,
|
struct_span_err!(
|
||||||
span,
|
tcx.sess,
|
||||||
E0091,
|
span,
|
||||||
"type parameter `{}` is unused",
|
E0091,
|
||||||
param.name,
|
"type parameter `{}` is unused",
|
||||||
)
|
param.name,
|
||||||
.span_label(span, "unused type parameter")
|
)
|
||||||
.emit();
|
.span_label(span, "unused type parameter")
|
||||||
}
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1534,10 +1530,10 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E
|
|||||||
for def_id in visitor.0 {
|
for def_id in visitor.0 {
|
||||||
let ty_span = tcx.def_span(def_id);
|
let ty_span = tcx.def_span(def_id);
|
||||||
if !seen.contains(&ty_span) {
|
if !seen.contains(&ty_span) {
|
||||||
err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
|
err.span_label(ty_span, &format!("returning this opaque type `{ty}`"));
|
||||||
seen.insert(ty_span);
|
seen.insert(ty_span);
|
||||||
}
|
}
|
||||||
err.span_label(sp, &format!("returning here with type `{}`", ty));
|
err.span_label(sp, &format!("returning here with type `{ty}`"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -632,11 +632,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
|
let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
|
||||||
if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) =
|
if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) =
|
||||||
(self_ty.kind(), unsize_ty.kind())
|
(self_ty.kind(), unsize_ty.kind())
|
||||||
|
&& data_a.principal_def_id() != data_b.principal_def_id()
|
||||||
{
|
{
|
||||||
if data_a.principal_def_id() != data_b.principal_def_id() {
|
debug!("coerce_unsized: found trait upcasting coercion");
|
||||||
debug!("coerce_unsized: found trait upcasting coercion");
|
has_trait_upcasting_coercion = true;
|
||||||
has_trait_upcasting_coercion = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let ty::Tuple(..) = unsize_ty.kind() {
|
if let ty::Tuple(..) = unsize_ty.kind() {
|
||||||
debug!("coerce_unsized: found unsized tuple coercion");
|
debug!("coerce_unsized: found unsized tuple coercion");
|
||||||
@ -732,13 +731,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
||||||
G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
||||||
{
|
{
|
||||||
if let ty::FnPtr(fn_ty_b) = b.kind() {
|
if let ty::FnPtr(fn_ty_b) = b.kind()
|
||||||
if let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) =
|
&& let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) =
|
||||||
(fn_ty_a.unsafety(), fn_ty_b.unsafety())
|
(fn_ty_a.unsafety(), fn_ty_b.unsafety())
|
||||||
{
|
{
|
||||||
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
|
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
|
||||||
return self.unify_and(unsafe_a, b, to_unsafe);
|
return self.unify_and(unsafe_a, b, to_unsafe);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.unify_and(a, b, normal)
|
self.unify_and(a, b, normal)
|
||||||
}
|
}
|
||||||
@ -783,12 +781,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
|
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
|
||||||
if let ty::FnDef(def_id, _) = *a.kind() {
|
if let ty::FnDef(def_id, _) = *a.kind()
|
||||||
if b_sig.unsafety() == hir::Unsafety::Normal
|
&& b_sig.unsafety() == hir::Unsafety::Normal
|
||||||
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
|
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
|
||||||
{
|
{
|
||||||
return Err(TypeError::TargetFeatureCast(def_id));
|
return Err(TypeError::TargetFeatureCast(def_id));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let InferOk { value: a_sig, obligations: o1 } =
|
let InferOk { value: a_sig, obligations: o1 } =
|
||||||
@ -1540,11 +1537,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||||||
fcx.tcx.hir().get_if_cause(expr.hir_id),
|
fcx.tcx.hir().get_if_cause(expr.hir_id),
|
||||||
expected.is_unit(),
|
expected.is_unit(),
|
||||||
pointing_at_return_type,
|
pointing_at_return_type,
|
||||||
) {
|
)
|
||||||
// If the block is from an external macro or try (`?`) desugaring, then
|
// If the block is from an external macro or try (`?`) desugaring, then
|
||||||
// do not suggest adding a semicolon, because there's nowhere to put it.
|
// do not suggest adding a semicolon, because there's nowhere to put it.
|
||||||
// See issues #81943 and #87051.
|
// See issues #81943 and #87051.
|
||||||
if matches!(
|
&& matches!(
|
||||||
cond_expr.span.desugaring_kind(),
|
cond_expr.span.desugaring_kind(),
|
||||||
None | Some(DesugaringKind::WhileLoop)
|
None | Some(DesugaringKind::WhileLoop)
|
||||||
) && !in_external_macro(fcx.tcx.sess, cond_expr.span)
|
) && !in_external_macro(fcx.tcx.sess, cond_expr.span)
|
||||||
@ -1552,11 +1549,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||||||
cond_expr.kind,
|
cond_expr.kind,
|
||||||
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
|
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
err.span_label(cond_expr.span, "expected this to be `()`");
|
err.span_label(cond_expr.span, "expected this to be `()`");
|
||||||
if expr.can_have_side_effects() {
|
if expr.can_have_side_effects() {
|
||||||
fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);
|
fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
|
fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
|
||||||
@ -1636,28 +1632,27 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||||||
let has_impl = snippet_iter.next().map_or(false, |s| s == "impl");
|
let has_impl = snippet_iter.next().map_or(false, |s| s == "impl");
|
||||||
// Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
|
// Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
|
||||||
let mut is_object_safe = false;
|
let mut is_object_safe = false;
|
||||||
if let hir::FnRetTy::Return(ty) = fn_output {
|
if let hir::FnRetTy::Return(ty) = fn_output
|
||||||
// Get the return type.
|
// Get the return type.
|
||||||
if let hir::TyKind::OpaqueDef(..) = ty.kind {
|
&& let hir::TyKind::OpaqueDef(..) = ty.kind
|
||||||
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty);
|
{
|
||||||
// Get the `impl Trait`'s `DefId`.
|
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty);
|
||||||
if let ty::Opaque(def_id, _) = ty.kind() {
|
// Get the `impl Trait`'s `DefId`.
|
||||||
// Get the `impl Trait`'s `Item` so that we can get its trait bounds and
|
if let ty::Opaque(def_id, _) = ty.kind()
|
||||||
// get the `Trait`'s `DefId`.
|
// Get the `impl Trait`'s `Item` so that we can get its trait bounds and
|
||||||
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) =
|
// get the `Trait`'s `DefId`.
|
||||||
fcx.tcx.hir().expect_item(def_id.expect_local()).kind
|
&& let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) =
|
||||||
{
|
fcx.tcx.hir().expect_item(def_id.expect_local()).kind
|
||||||
// Are of this `impl Trait`'s traits object safe?
|
{
|
||||||
is_object_safe = bounds.iter().all(|bound| {
|
// Are of this `impl Trait`'s traits object safe?
|
||||||
bound
|
is_object_safe = bounds.iter().all(|bound| {
|
||||||
.trait_ref()
|
bound
|
||||||
.and_then(|t| t.trait_def_id())
|
.trait_ref()
|
||||||
.map_or(false, |def_id| {
|
.and_then(|t| t.trait_def_id())
|
||||||
fcx.tcx.object_safety_violations(def_id).is_empty()
|
.map_or(false, |def_id| {
|
||||||
})
|
fcx.tcx.object_safety_violations(def_id).is_empty()
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if has_impl {
|
if has_impl {
|
||||||
@ -1703,7 +1698,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
|||||||
&& let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty)
|
&& let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty)
|
||||||
&& let ty::Dynamic(..) = ty.kind()
|
&& let ty::Dynamic(..) = ty.kind()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ fn compare_predicate_entailment<'tcx>(
|
|||||||
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => {
|
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => {
|
||||||
"&mut self".to_owned()
|
"&mut self".to_owned()
|
||||||
}
|
}
|
||||||
_ => format!("self: {}", ty),
|
_ => format!("self: {ty}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
|
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
|
||||||
@ -526,7 +526,7 @@ fn compare_self_type<'tcx>(
|
|||||||
ExplicitSelf::ByValue => "self".to_owned(),
|
ExplicitSelf::ByValue => "self".to_owned(),
|
||||||
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
||||||
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
|
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
|
||||||
_ => format!("self: {}", self_arg_ty),
|
_ => format!("self: {self_arg_ty}"),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -544,9 +544,9 @@ fn compare_self_type<'tcx>(
|
|||||||
trait_m.name,
|
trait_m.name,
|
||||||
self_descr
|
self_descr
|
||||||
);
|
);
|
||||||
err.span_label(impl_m_span, format!("`{}` used in impl", self_descr));
|
err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
|
||||||
if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
|
if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
|
||||||
err.span_label(span, format!("trait method declared without `{}`", self_descr));
|
err.span_label(span, format!("trait method declared without `{self_descr}`"));
|
||||||
} else {
|
} else {
|
||||||
err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
|
err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
|
||||||
}
|
}
|
||||||
@ -564,9 +564,9 @@ fn compare_self_type<'tcx>(
|
|||||||
trait_m.name,
|
trait_m.name,
|
||||||
self_descr
|
self_descr
|
||||||
);
|
);
|
||||||
err.span_label(impl_m_span, format!("expected `{}` in impl", self_descr));
|
err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
|
||||||
if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
|
if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
|
||||||
err.span_label(span, format!("`{}` used in trait", self_descr));
|
err.span_label(span, format!("`{self_descr}` used in trait"));
|
||||||
} else {
|
} else {
|
||||||
err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
|
err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
|
||||||
}
|
}
|
||||||
@ -668,7 +668,7 @@ fn compare_number_of_generics<'tcx>(
|
|||||||
err.span_label(*span, "");
|
err.span_label(*span, "");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
suffix = Some(format!(", expected {}", trait_count));
|
suffix = Some(format!(", expected {trait_count}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(span) = span {
|
if let Some(span) = span {
|
||||||
@ -873,12 +873,10 @@ fn compare_synthetic_generics<'tcx>(
|
|||||||
intravisit::walk_ty(self, ty);
|
intravisit::walk_ty(self, ty);
|
||||||
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) =
|
if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) =
|
||||||
ty.kind
|
ty.kind
|
||||||
|
&& let Res::Def(DefKind::TyParam, def_id) = path.res
|
||||||
|
&& def_id == self.1
|
||||||
{
|
{
|
||||||
if let Res::Def(DefKind::TyParam, def_id) = path.res {
|
self.0 = Some(ty.span);
|
||||||
if def_id == self.1 {
|
|
||||||
self.0 = Some(ty.span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -908,7 +906,7 @@ fn compare_synthetic_generics<'tcx>(
|
|||||||
// delete generic parameters
|
// delete generic parameters
|
||||||
(impl_m.generics.span, String::new()),
|
(impl_m.generics.span, String::new()),
|
||||||
// replace param usage with `impl Trait`
|
// replace param usage with `impl Trait`
|
||||||
(span, format!("impl {}", bounds)),
|
(span, format!("impl {bounds}")),
|
||||||
],
|
],
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
@ -972,7 +970,7 @@ fn compare_const_param_types<'tcx>(
|
|||||||
&format!(
|
&format!(
|
||||||
"the const parameter{} has type `{}`, but the declaration \
|
"the const parameter{} has type `{}`, but the declaration \
|
||||||
in trait `{}` has type `{}`",
|
in trait `{}` has type `{}`",
|
||||||
&impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{}`", ident)),
|
&impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{ident}`")),
|
||||||
impl_ty,
|
impl_ty,
|
||||||
tcx.def_path_str(trait_m.def_id),
|
tcx.def_path_str(trait_m.def_id),
|
||||||
trait_ty
|
trait_ty
|
||||||
|
@ -241,13 +241,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// We are pointing at the binding's type or initializer value, but it's pattern
|
// We are pointing at the binding's type or initializer value, but it's pattern
|
||||||
// is in a different line, so we point at both.
|
// is in a different line, so we point at both.
|
||||||
err.span_label(secondary_span, "expected due to the type of this binding");
|
err.span_label(secondary_span, "expected due to the type of this binding");
|
||||||
err.span_label(primary_span, &format!("expected due to this{}", post_message));
|
err.span_label(primary_span, &format!("expected due to this{post_message}"));
|
||||||
} else if post_message == "" {
|
} else if post_message == "" {
|
||||||
// We are pointing at either the assignment lhs or the binding def pattern.
|
// We are pointing at either the assignment lhs or the binding def pattern.
|
||||||
err.span_label(primary_span, "expected due to the type of this binding");
|
err.span_label(primary_span, "expected due to the type of this binding");
|
||||||
} else {
|
} else {
|
||||||
// We are pointing at the binding's type or initializer value.
|
// We are pointing at the binding's type or initializer value.
|
||||||
err.span_label(primary_span, &format!("expected due to this{}", post_message));
|
err.span_label(primary_span, &format!("expected due to this{post_message}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !lhs.is_syntactic_place_expr() {
|
if !lhs.is_syntactic_place_expr() {
|
||||||
@ -321,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
"try adding an expression at the end of the block",
|
"try adding an expression at the end of the block",
|
||||||
return_suggestions
|
return_suggestions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| format!("{}\n{}{}", semicolon, indent, r)),
|
.map(|r| format!("{semicolon}\n{indent}{r}")),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -344,10 +344,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let variant_path =
|
let variant_path =
|
||||||
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
|
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
|
||||||
// FIXME #56861: DRYer prelude filtering
|
// FIXME #56861: DRYer prelude filtering
|
||||||
if let Some(path) = variant_path.strip_prefix("std::prelude::") {
|
if let Some(path) = variant_path.strip_prefix("std::prelude::")
|
||||||
if let Some((_, path)) = path.split_once("::") {
|
&& let Some((_, path)) = path.split_once("::")
|
||||||
return Some(path.to_string());
|
{
|
||||||
}
|
return Some(path.to_string());
|
||||||
}
|
}
|
||||||
Some(variant_path)
|
Some(variant_path)
|
||||||
} else {
|
} else {
|
||||||
@ -357,7 +357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
||||||
Some(ident) => format!("{}: ", ident),
|
Some(ident) => format!("{ident}: "),
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -366,9 +366,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
[variant] => {
|
[variant] => {
|
||||||
// Just a single matching variant.
|
// Just a single matching variant.
|
||||||
err.multipart_suggestion_verbose(
|
err.multipart_suggestion_verbose(
|
||||||
&format!("try wrapping the expression in `{}`", variant),
|
&format!("try wrapping the expression in `{variant}`"),
|
||||||
vec![
|
vec![
|
||||||
(expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)),
|
(expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
|
||||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||||
],
|
],
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
@ -383,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
),
|
),
|
||||||
compatible_variants.into_iter().map(|variant| {
|
compatible_variants.into_iter().map(|variant| {
|
||||||
vec![
|
vec![
|
||||||
(expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)),
|
(expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
|
||||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
@ -680,7 +680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
_ if is_range_literal(expr) => true,
|
_ if is_range_literal(expr) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
let sugg_expr = if needs_parens { format!("({})", src) } else { src };
|
let sugg_expr = if needs_parens { format!("({src})") } else { src };
|
||||||
|
|
||||||
if let Some(sugg) = self.can_use_as_ref(expr) {
|
if let Some(sugg) = self.can_use_as_ref(expr) {
|
||||||
return Some((
|
return Some((
|
||||||
@ -693,7 +693,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
||||||
Some(ident) => format!("{}: ", ident),
|
Some(ident) => format!("{ident}: "),
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -727,14 +727,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
hir::Mutability::Mut => (
|
hir::Mutability::Mut => (
|
||||||
sp,
|
sp,
|
||||||
"consider mutably borrowing here".to_string(),
|
"consider mutably borrowing here".to_string(),
|
||||||
format!("{}&mut {}", prefix, sugg_expr),
|
format!("{prefix}&mut {sugg_expr}"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
hir::Mutability::Not => (
|
hir::Mutability::Not => (
|
||||||
sp,
|
sp,
|
||||||
"consider borrowing here".to_string(),
|
"consider borrowing here".to_string(),
|
||||||
format!("{}&{}", prefix, sugg_expr),
|
format!("{prefix}&{sugg_expr}"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
@ -758,29 +758,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if let Some(call_span) =
|
if let Some(call_span) =
|
||||||
iter::successors(Some(expr.span), |s| s.parent_callsite())
|
iter::successors(Some(expr.span), |s| s.parent_callsite())
|
||||||
.find(|&s| sp.contains(s))
|
.find(|&s| sp.contains(s))
|
||||||
|
&& sm.span_to_snippet(call_span).is_ok()
|
||||||
{
|
{
|
||||||
if sm.span_to_snippet(call_span).is_ok() {
|
|
||||||
return Some((
|
|
||||||
sp.with_hi(call_span.lo()),
|
|
||||||
"consider removing the borrow".to_string(),
|
|
||||||
String::new(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if sp.contains(expr.span) {
|
|
||||||
if sm.span_to_snippet(expr.span).is_ok() {
|
|
||||||
return Some((
|
return Some((
|
||||||
sp.with_hi(expr.span.lo()),
|
sp.with_hi(call_span.lo()),
|
||||||
"consider removing the borrow".to_string(),
|
"consider removing the borrow".to_string(),
|
||||||
String::new(),
|
String::new(),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
true,
|
true,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if sp.contains(expr.span)
|
||||||
|
&& sm.span_to_snippet(expr.span).is_ok()
|
||||||
|
{
|
||||||
|
return Some((
|
||||||
|
sp.with_hi(expr.span.lo()),
|
||||||
|
"consider removing the borrow".to_string(),
|
||||||
|
String::new(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
true,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
@ -788,66 +787,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&ty::RawPtr(TypeAndMut { ty: ty_b, mutbl: mutbl_b }),
|
&ty::RawPtr(TypeAndMut { ty: ty_b, mutbl: mutbl_b }),
|
||||||
&ty::Ref(_, ty_a, mutbl_a),
|
&ty::Ref(_, ty_a, mutbl_a),
|
||||||
) => {
|
) => {
|
||||||
if let Some(steps) = self.deref_steps(ty_a, ty_b) {
|
if let Some(steps) = self.deref_steps(ty_a, ty_b)
|
||||||
// Only suggest valid if dereferencing needed.
|
// Only suggest valid if dereferencing needed.
|
||||||
if steps > 0 {
|
&& steps > 0
|
||||||
// The pointer type implements `Copy` trait so the suggestion is always valid.
|
// The pointer type implements `Copy` trait so the suggestion is always valid.
|
||||||
if let Ok(src) = sm.span_to_snippet(sp) {
|
&& let Ok(src) = sm.span_to_snippet(sp)
|
||||||
let derefs = "*".repeat(steps);
|
{
|
||||||
if let Some((span, src, applicability)) = match mutbl_b {
|
let derefs = "*".repeat(steps);
|
||||||
|
if let Some((span, src, applicability)) = match mutbl_b {
|
||||||
|
hir::Mutability::Mut => {
|
||||||
|
let new_prefix = "&mut ".to_owned() + &derefs;
|
||||||
|
match mutbl_a {
|
||||||
hir::Mutability::Mut => {
|
hir::Mutability::Mut => {
|
||||||
let new_prefix = "&mut ".to_owned() + &derefs;
|
replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
|
||||||
match mutbl_a {
|
let pos = sp.lo() + BytePos(5);
|
||||||
hir::Mutability::Mut => {
|
let sp = sp.with_lo(pos).with_hi(pos);
|
||||||
replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
|
(sp, derefs, Applicability::MachineApplicable)
|
||||||
let pos = sp.lo() + BytePos(5);
|
})
|
||||||
let sp = sp.with_lo(pos).with_hi(pos);
|
|
||||||
(sp, derefs, Applicability::MachineApplicable)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
hir::Mutability::Not => {
|
|
||||||
replace_prefix(&src, "&", &new_prefix).map(|_| {
|
|
||||||
let pos = sp.lo() + BytePos(1);
|
|
||||||
let sp = sp.with_lo(pos).with_hi(pos);
|
|
||||||
(
|
|
||||||
sp,
|
|
||||||
format!("mut {}", derefs),
|
|
||||||
Applicability::Unspecified,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hir::Mutability::Not => {
|
hir::Mutability::Not => {
|
||||||
let new_prefix = "&".to_owned() + &derefs;
|
replace_prefix(&src, "&", &new_prefix).map(|_| {
|
||||||
match mutbl_a {
|
let pos = sp.lo() + BytePos(1);
|
||||||
hir::Mutability::Mut => {
|
let sp = sp.with_lo(pos).with_hi(pos);
|
||||||
replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
|
(
|
||||||
let lo = sp.lo() + BytePos(1);
|
sp,
|
||||||
let hi = sp.lo() + BytePos(5);
|
format!("mut {derefs}"),
|
||||||
let sp = sp.with_lo(lo).with_hi(hi);
|
Applicability::Unspecified,
|
||||||
(sp, derefs, Applicability::MachineApplicable)
|
)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
hir::Mutability::Not => {
|
|
||||||
replace_prefix(&src, "&", &new_prefix).map(|_| {
|
|
||||||
let pos = sp.lo() + BytePos(1);
|
|
||||||
let sp = sp.with_lo(pos).with_hi(pos);
|
|
||||||
(sp, derefs, Applicability::MachineApplicable)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} {
|
|
||||||
return Some((
|
|
||||||
span,
|
|
||||||
"consider dereferencing".to_string(),
|
|
||||||
src,
|
|
||||||
applicability,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::Mutability::Not => {
|
||||||
|
let new_prefix = "&".to_owned() + &derefs;
|
||||||
|
match mutbl_a {
|
||||||
|
hir::Mutability::Mut => {
|
||||||
|
replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
|
||||||
|
let lo = sp.lo() + BytePos(1);
|
||||||
|
let hi = sp.lo() + BytePos(5);
|
||||||
|
let sp = sp.with_lo(lo).with_hi(hi);
|
||||||
|
(sp, derefs, Applicability::MachineApplicable)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
hir::Mutability::Not => {
|
||||||
|
replace_prefix(&src, "&", &new_prefix).map(|_| {
|
||||||
|
let pos = sp.lo() + BytePos(1);
|
||||||
|
let sp = sp.with_lo(pos).with_hi(pos);
|
||||||
|
(sp, derefs, Applicability::MachineApplicable)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
return Some((
|
||||||
|
span,
|
||||||
|
"consider dereferencing".to_string(),
|
||||||
|
src,
|
||||||
|
applicability,
|
||||||
|
true,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -908,7 +906,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// Suggest removing `&` if we have removed any, otherwise suggest just
|
// Suggest removing `&` if we have removed any, otherwise suggest just
|
||||||
// dereferencing the remaining number of steps.
|
// dereferencing the remaining number of steps.
|
||||||
let message = if remove.is_empty() {
|
let message = if remove.is_empty() {
|
||||||
format!("consider {}", deref_kind)
|
format!("consider {deref_kind}")
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"consider removing the `{}` and {} instead",
|
"consider removing the `{}` and {} instead",
|
||||||
@ -918,7 +916,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
|
||||||
Some(ident) => format!("{}: ", ident),
|
Some(ident) => format!("{ident}: "),
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -994,35 +992,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let hir::ExprKind::Call(path, args) = &expr.kind {
|
if let hir::ExprKind::Call(path, args) = &expr.kind
|
||||||
if let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) =
|
&& let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) =
|
||||||
(&path.kind, args.len())
|
(&path.kind, args.len())
|
||||||
{
|
// `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697).
|
||||||
// `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697).
|
&& let (hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)), sym::from) =
|
||||||
if let (hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)), sym::from) =
|
(&base_ty.kind, path_segment.ident.name)
|
||||||
(&base_ty.kind, path_segment.ident.name)
|
{
|
||||||
{
|
if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() {
|
||||||
if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() {
|
match ident.name {
|
||||||
match ident.name {
|
sym::i128
|
||||||
sym::i128
|
| sym::i64
|
||||||
| sym::i64
|
| sym::i32
|
||||||
| sym::i32
|
| sym::i16
|
||||||
| sym::i16
|
| sym::i8
|
||||||
| sym::i8
|
| sym::u128
|
||||||
| sym::u128
|
| sym::u64
|
||||||
| sym::u64
|
| sym::u32
|
||||||
| sym::u32
|
| sym::u16
|
||||||
| sym::u16
|
| sym::u8
|
||||||
| sym::u8
|
| sym::isize
|
||||||
| sym::isize
|
| sym::usize
|
||||||
| sym::usize
|
if base_ty_path.segments.len() == 1 =>
|
||||||
if base_ty_path.segments.len() == 1 =>
|
{
|
||||||
{
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1042,8 +1037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expected_ty,
|
expected_ty,
|
||||||
);
|
);
|
||||||
let lit_msg = format!(
|
let lit_msg = format!(
|
||||||
"change the type of the numeric literal from `{}` to `{}`",
|
"change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
|
||||||
checked_ty, expected_ty,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let close_paren = if expr.precedence().order() < PREC_POSTFIX {
|
let close_paren = if expr.precedence().order() < PREC_POSTFIX {
|
||||||
@ -1054,10 +1048,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut cast_suggestion = sugg.clone();
|
let mut cast_suggestion = sugg.clone();
|
||||||
cast_suggestion
|
cast_suggestion.push((expr.span.shrink_to_hi(), format!("{close_paren} as {expected_ty}")));
|
||||||
.push((expr.span.shrink_to_hi(), format!("{} as {}", close_paren, expected_ty)));
|
|
||||||
let mut into_suggestion = sugg.clone();
|
let mut into_suggestion = sugg.clone();
|
||||||
into_suggestion.push((expr.span.shrink_to_hi(), format!("{}.into()", close_paren)));
|
into_suggestion.push((expr.span.shrink_to_hi(), format!("{close_paren}.into()")));
|
||||||
let mut suffix_suggestion = sugg.clone();
|
let mut suffix_suggestion = sugg.clone();
|
||||||
suffix_suggestion.push((
|
suffix_suggestion.push((
|
||||||
if matches!(
|
if matches!(
|
||||||
@ -1074,7 +1067,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
},
|
},
|
||||||
if expr.precedence().order() < PREC_POSTFIX {
|
if expr.precedence().order() < PREC_POSTFIX {
|
||||||
// Readd `)`
|
// Readd `)`
|
||||||
format!("{})", expected_ty)
|
format!("{expected_ty})")
|
||||||
} else {
|
} else {
|
||||||
expected_ty.to_string()
|
expected_ty.to_string()
|
||||||
},
|
},
|
||||||
@ -1108,20 +1101,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
(lhs_expr_and_src, exp_to_found_is_fallible)
|
(lhs_expr_and_src, exp_to_found_is_fallible)
|
||||||
{
|
{
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"you can convert `{}` from `{}` to `{}`, matching the type of `{}`",
|
"you can convert `{lhs_src}` from `{expected_ty}` to `{checked_ty}`, matching the type of `{src}`",
|
||||||
lhs_src, expected_ty, checked_ty, src
|
|
||||||
);
|
);
|
||||||
let suggestion = vec![
|
let suggestion = vec![
|
||||||
(lhs_expr.span.shrink_to_lo(), format!("{}::from(", checked_ty)),
|
(lhs_expr.span.shrink_to_lo(), format!("{checked_ty}::from(")),
|
||||||
(lhs_expr.span.shrink_to_hi(), ")".to_string()),
|
(lhs_expr.span.shrink_to_hi(), ")".to_string()),
|
||||||
];
|
];
|
||||||
(msg, suggestion)
|
(msg, suggestion)
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("{} and panic if the converted value doesn't fit", msg);
|
let msg = format!("{msg} and panic if the converted value doesn't fit");
|
||||||
let mut suggestion = sugg.clone();
|
let mut suggestion = sugg.clone();
|
||||||
suggestion.push((
|
suggestion.push((
|
||||||
expr.span.shrink_to_hi(),
|
expr.span.shrink_to_hi(),
|
||||||
format!("{}.try_into().unwrap()", close_paren),
|
format!("{close_paren}.try_into().unwrap()"),
|
||||||
));
|
));
|
||||||
(msg, suggestion)
|
(msg, suggestion)
|
||||||
};
|
};
|
||||||
@ -1151,7 +1143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// We now know that converting either the lhs or rhs is fallible. Before we
|
// We now know that converting either the lhs or rhs is fallible. Before we
|
||||||
// suggest a fallible conversion, check if the value can never fit in the
|
// suggest a fallible conversion, check if the value can never fit in the
|
||||||
// expected type.
|
// expected type.
|
||||||
let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty);
|
let msg = format!("`{src}` cannot fit into type `{expected_ty}`");
|
||||||
err.note(&msg);
|
err.note(&msg);
|
||||||
return;
|
return;
|
||||||
} else if in_const_context {
|
} else if in_const_context {
|
||||||
@ -1229,7 +1221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
} else if can_cast {
|
} else if can_cast {
|
||||||
// Missing try_into implementation for `f64` to `f32`
|
// Missing try_into implementation for `f64` to `f32`
|
||||||
err.multipart_suggestion_verbose(
|
err.multipart_suggestion_verbose(
|
||||||
&format!("{}, producing the closest possible value", cast_msg),
|
&format!("{cast_msg}, producing the closest possible value"),
|
||||||
cast_suggestion,
|
cast_suggestion,
|
||||||
Applicability::MaybeIncorrect, // lossy conversion
|
Applicability::MaybeIncorrect, // lossy conversion
|
||||||
);
|
);
|
||||||
@ -1246,7 +1238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
} else if can_cast {
|
} else if can_cast {
|
||||||
// Missing try_into implementation for `{float}` to `{integer}`
|
// Missing try_into implementation for `{float}` to `{integer}`
|
||||||
err.multipart_suggestion_verbose(
|
err.multipart_suggestion_verbose(
|
||||||
&format!("{}, rounding the float towards zero", msg),
|
&format!("{msg}, rounding the float towards zero"),
|
||||||
cast_suggestion,
|
cast_suggestion,
|
||||||
Applicability::MaybeIncorrect, // lossy conversion
|
Applicability::MaybeIncorrect, // lossy conversion
|
||||||
);
|
);
|
||||||
@ -1258,8 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if exp.bit_width() > found.bit_width().unwrap_or(256) {
|
if exp.bit_width() > found.bit_width().unwrap_or(256) {
|
||||||
err.multipart_suggestion_verbose(
|
err.multipart_suggestion_verbose(
|
||||||
&format!(
|
&format!(
|
||||||
"{}, producing the floating point representation of the integer",
|
"{msg}, producing the floating point representation of the integer",
|
||||||
msg,
|
|
||||||
),
|
),
|
||||||
into_suggestion,
|
into_suggestion,
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
@ -1274,9 +1265,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// Missing try_into implementation for `{integer}` to `{float}`
|
// Missing try_into implementation for `{integer}` to `{float}`
|
||||||
err.multipart_suggestion_verbose(
|
err.multipart_suggestion_verbose(
|
||||||
&format!(
|
&format!(
|
||||||
"{}, producing the floating point representation of the integer, \
|
"{cast_msg}, producing the floating point representation of the integer, \
|
||||||
rounded if necessary",
|
rounded if necessary",
|
||||||
cast_msg,
|
|
||||||
),
|
),
|
||||||
cast_suggestion,
|
cast_suggestion,
|
||||||
Applicability::MaybeIncorrect, // lossy conversion
|
Applicability::MaybeIncorrect, // lossy conversion
|
||||||
@ -1321,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&ty::Char,
|
&ty::Char,
|
||||||
) => {
|
) => {
|
||||||
err.multipart_suggestion_verbose(
|
err.multipart_suggestion_verbose(
|
||||||
&format!("{}, since a `char` always occupies 4 bytes", cast_msg,),
|
&format!("{cast_msg}, since a `char` always occupies 4 bytes"),
|
||||||
cast_suggestion,
|
cast_suggestion,
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
@ -1333,22 +1323,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
// Report the type inferred by the return statement.
|
// Report the type inferred by the return statement.
|
||||||
fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) {
|
fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) {
|
||||||
if let Some(sp) = self.ret_coercion_span.get() {
|
if let Some(sp) = self.ret_coercion_span.get()
|
||||||
// If the closure has an explicit return type annotation, or if
|
// If the closure has an explicit return type annotation, or if
|
||||||
// the closure's return type has been inferred from outside
|
// the closure's return type has been inferred from outside
|
||||||
// requirements (such as an Fn* trait bound), then a type error
|
// requirements (such as an Fn* trait bound), then a type error
|
||||||
// may occur at the first return expression we see in the closure
|
// may occur at the first return expression we see in the closure
|
||||||
// (if it conflicts with the declared return type). Skip adding a
|
// (if it conflicts with the declared return type). Skip adding a
|
||||||
// note in this case, since it would be incorrect.
|
// note in this case, since it would be incorrect.
|
||||||
if !self.return_type_pre_known {
|
&& !self.return_type_pre_known
|
||||||
err.span_note(
|
{
|
||||||
sp,
|
err.span_note(
|
||||||
&format!(
|
sp,
|
||||||
"return type inferred to be `{}` here",
|
&format!(
|
||||||
self.resolve_vars_if_possible(expected)
|
"return type inferred to be `{}` here",
|
||||||
),
|
self.resolve_vars_if_possible(expected)
|
||||||
);
|
),
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
|
|||||||
let span = tcx.def_span(drop_impl_did);
|
let span = tcx.def_span(drop_impl_did);
|
||||||
let reported = tcx.sess.delay_span_bug(
|
let reported = tcx.sess.delay_span_bug(
|
||||||
span,
|
span,
|
||||||
&format!("should have been rejected by coherence check: {}", dtor_self_type),
|
&format!("should have been rejected by coherence check: {dtor_self_type}"),
|
||||||
);
|
);
|
||||||
Err(reported)
|
Err(reported)
|
||||||
}
|
}
|
||||||
@ -104,8 +104,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
|||||||
item_span,
|
item_span,
|
||||||
&format!(
|
&format!(
|
||||||
"use the same sequence of generic type, lifetime and const parameters \
|
"use the same sequence of generic type, lifetime and const parameters \
|
||||||
as the {} definition",
|
as the {self_descr} definition",
|
||||||
self_descr,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
@ -262,9 +261,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
|||||||
tcx.sess,
|
tcx.sess,
|
||||||
predicate_sp,
|
predicate_sp,
|
||||||
E0367,
|
E0367,
|
||||||
"`Drop` impl requires `{}` but the {} it is implemented for does not",
|
"`Drop` impl requires `{predicate}` but the {self_descr} it is implemented for does not",
|
||||||
predicate,
|
|
||||||
self_descr,
|
|
||||||
)
|
)
|
||||||
.span_note(item_span, "the implementor must specify the same requirement")
|
.span_note(item_span, "the implementor must specify the same requirement")
|
||||||
.emit();
|
.emit();
|
||||||
|
@ -181,13 +181,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// make this code only run with -Zverbose because it is probably slow
|
// make this code only run with -Zverbose because it is probably slow
|
||||||
if let Ok(lint_str) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
|
if let Ok(lint_str) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
|
||||||
if !lint_str.contains('\n') {
|
if !lint_str.contains('\n') {
|
||||||
debug!("expr text: {}", lint_str);
|
debug!("expr text: {lint_str}");
|
||||||
} else {
|
} else {
|
||||||
let mut lines = lint_str.lines();
|
let mut lines = lint_str.lines();
|
||||||
if let Some(line0) = lines.next() {
|
if let Some(line0) = lines.next() {
|
||||||
let remaining_lines = lines.count();
|
let remaining_lines = lines.count();
|
||||||
debug!("expr text: {}", line0);
|
debug!("expr text: {line0}");
|
||||||
debug!("expr text: ...(and {} more lines)", remaining_lines);
|
debug!("expr text: ...(and {remaining_lines} more lines)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,8 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expr.span,
|
expr.span,
|
||||||
oprnd_t,
|
oprnd_t,
|
||||||
E0614,
|
E0614,
|
||||||
"type `{}` cannot be dereferenced",
|
"type `{oprnd_t}` cannot be dereferenced",
|
||||||
oprnd_t,
|
|
||||||
);
|
);
|
||||||
let sp = tcx.sess.source_map().start_point(expr.span);
|
let sp = tcx.sess.source_map().start_point(expr.span);
|
||||||
if let Some(sp) =
|
if let Some(sp) =
|
||||||
@ -652,7 +651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
expr.span,
|
expr.span,
|
||||||
"give it a value of the expected type",
|
"give it a value of the expected type",
|
||||||
format!("break{} {}", label, val),
|
format!("break{label} {val}"),
|
||||||
Applicability::HasPlaceholders,
|
Applicability::HasPlaceholders,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -780,7 +779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
db.span_label(
|
db.span_label(
|
||||||
span,
|
span,
|
||||||
format!("expected `{}` because of this return type", snippet),
|
format!("expected `{snippet}` because of this return type"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1611,15 +1610,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let mut truncated_fields_error = String::new();
|
let mut truncated_fields_error = String::new();
|
||||||
let remaining_fields_names = match &displayable_field_names[..] {
|
let remaining_fields_names = match &displayable_field_names[..] {
|
||||||
[field1] => format!("`{}`", field1),
|
[field1] => format!("`{}`", field1),
|
||||||
[field1, field2] => format!("`{}` and `{}`", field1, field2),
|
[field1, field2] => format!("`{field1}` and `{field2}`"),
|
||||||
[field1, field2, field3] => format!("`{}`, `{}` and `{}`", field1, field2, field3),
|
[field1, field2, field3] => format!("`{field1}`, `{field2}` and `{field3}`"),
|
||||||
_ => {
|
_ => {
|
||||||
truncated_fields_error =
|
truncated_fields_error =
|
||||||
format!(" and {} other field{}", len - 3, pluralize!(len - 3));
|
format!(" and {} other field{}", len - 3, pluralize!(len - 3));
|
||||||
displayable_field_names
|
displayable_field_names
|
||||||
.iter()
|
.iter()
|
||||||
.take(3)
|
.take(3)
|
||||||
.map(|n| format!("`{}`", n))
|
.map(|n| format!("`{n}`"))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ")
|
.join(", ")
|
||||||
}
|
}
|
||||||
@ -1635,10 +1634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
truncated_fields_error,
|
truncated_fields_error,
|
||||||
adt_ty
|
adt_ty
|
||||||
);
|
);
|
||||||
err.span_label(
|
err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
|
||||||
span,
|
|
||||||
format!("missing {}{}", remaining_fields_names, truncated_fields_error),
|
|
||||||
);
|
|
||||||
|
|
||||||
// If the last field is a range literal, but it isn't supposed to be, then they probably
|
// If the last field is a range literal, but it isn't supposed to be, then they probably
|
||||||
// meant to use functional update syntax.
|
// meant to use functional update syntax.
|
||||||
@ -1693,8 +1689,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.tcx.sess.span_err(
|
self.tcx.sess.span_err(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
"cannot construct `{}` with struct literal syntax due to inaccessible fields",
|
"cannot construct `{adt_ty}` with struct literal syntax due to inaccessible fields",
|
||||||
adt_ty,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1807,7 +1802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
field.ident.span,
|
field.ident.span,
|
||||||
format!("`{}` does not have this field", ty),
|
format!("`{ty}` does not have this field"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let available_field_names =
|
let available_field_names =
|
||||||
@ -1973,8 +1968,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
field.span,
|
field.span,
|
||||||
expr_t,
|
expr_t,
|
||||||
E0610,
|
E0610,
|
||||||
"`{}` is a primitive type and therefore doesn't have fields",
|
"`{expr_t}` is a primitive type and therefore doesn't have fields",
|
||||||
expr_t
|
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
@ -2018,7 +2012,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if add_label {
|
if add_label {
|
||||||
err.span_label(field_ident.span, &format!("field not found in `{}`", ty));
|
err.span_label(field_ident.span, &format!("field not found in `{ty}`"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2077,10 +2071,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.tcx().sess,
|
self.tcx().sess,
|
||||||
field.span,
|
field.span,
|
||||||
E0616,
|
E0616,
|
||||||
"field `{}` of {} `{}` is private",
|
"field `{field}` of {kind_name} `{struct_path}` is private",
|
||||||
field,
|
|
||||||
kind_name,
|
|
||||||
struct_path
|
|
||||||
);
|
);
|
||||||
err.span_label(field.span, "private field");
|
err.span_label(field.span, "private field");
|
||||||
// Also check if an accessible method exists, which is often what is meant.
|
// Also check if an accessible method exists, which is often what is meant.
|
||||||
@ -2088,7 +2079,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
{
|
{
|
||||||
self.suggest_method_call(
|
self.suggest_method_call(
|
||||||
&mut err,
|
&mut err,
|
||||||
&format!("a method `{}` also exists, call it with parentheses", field),
|
&format!("a method `{field}` also exists, call it with parentheses"),
|
||||||
field,
|
field,
|
||||||
expr_t,
|
expr_t,
|
||||||
expr,
|
expr,
|
||||||
@ -2104,9 +2095,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
field.span,
|
field.span,
|
||||||
expr_t,
|
expr_t,
|
||||||
E0615,
|
E0615,
|
||||||
"attempted to take value of method `{}` on type `{}`",
|
"attempted to take value of method `{field}` on type `{expr_t}`",
|
||||||
field,
|
|
||||||
expr_t
|
|
||||||
);
|
);
|
||||||
err.span_label(field.span, "method, not a field");
|
err.span_label(field.span, "method, not a field");
|
||||||
let expr_is_call =
|
let expr_is_call =
|
||||||
@ -2150,27 +2139,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
|
|
||||||
if let ty::RawPtr(ty_and_mut) = expr_t.kind() {
|
if let ty::RawPtr(ty_and_mut) = expr_t.kind()
|
||||||
if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() {
|
&& let ty::Adt(adt_def, _) = ty_and_mut.ty.kind()
|
||||||
if adt_def.variants().len() == 1
|
{
|
||||||
&& adt_def
|
if adt_def.variants().len() == 1
|
||||||
.variants()
|
&& adt_def
|
||||||
.iter()
|
.variants()
|
||||||
.next()
|
.iter()
|
||||||
.unwrap()
|
.next()
|
||||||
.fields
|
.unwrap()
|
||||||
.iter()
|
.fields
|
||||||
.any(|f| f.ident(self.tcx) == field)
|
.iter()
|
||||||
{
|
.any(|f| f.ident(self.tcx) == field)
|
||||||
if let Some(dot_loc) = expr_snippet.rfind('.') {
|
{
|
||||||
found = true;
|
if let Some(dot_loc) = expr_snippet.rfind('.') {
|
||||||
err.span_suggestion(
|
found = true;
|
||||||
expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
|
err.span_suggestion(
|
||||||
"to access the field, dereference first",
|
expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
|
||||||
format!("(*{})", &expr_snippet[0..dot_loc]),
|
"to access the field, dereference first",
|
||||||
Applicability::MaybeIncorrect,
|
format!("(*{})", &expr_snippet[0..dot_loc]),
|
||||||
);
|
Applicability::MaybeIncorrect,
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2197,7 +2186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let param_span = self.tcx.hir().span(param_hir_id);
|
let param_span = self.tcx.hir().span(param_hir_id);
|
||||||
let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local());
|
let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local());
|
||||||
|
|
||||||
err.span_label(param_span, &format!("type parameter '{}' declared here", param_name));
|
err.span_label(param_span, &format!("type parameter '{param_name}' declared here"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_fields_on_recordish(
|
fn suggest_fields_on_recordish(
|
||||||
@ -2239,17 +2228,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
) {
|
) {
|
||||||
if let (Some(len), Ok(user_index)) =
|
if let (Some(len), Ok(user_index)) =
|
||||||
(len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
|
(len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
|
||||||
|
&& let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
|
||||||
{
|
{
|
||||||
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
|
let help = "instead of using tuple indexing, use array indexing";
|
||||||
let help = "instead of using tuple indexing, use array indexing";
|
let suggestion = format!("{base}[{field}]");
|
||||||
let suggestion = format!("{}[{}]", base, field);
|
let applicability = if len < user_index {
|
||||||
let applicability = if len < user_index {
|
Applicability::MachineApplicable
|
||||||
Applicability::MachineApplicable
|
} else {
|
||||||
} else {
|
Applicability::MaybeIncorrect
|
||||||
Applicability::MaybeIncorrect
|
};
|
||||||
};
|
err.span_suggestion(expr.span, help, suggestion, applicability);
|
||||||
err.span_suggestion(expr.span, help, suggestion, applicability);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2261,8 +2249,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
field: Ident,
|
field: Ident,
|
||||||
) {
|
) {
|
||||||
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
|
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
|
||||||
let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
|
let msg = format!("`{base}` is a raw pointer; try dereferencing it");
|
||||||
let suggestion = format!("(*{}).{}", base, field);
|
let suggestion = format!("(*{base}).{field}");
|
||||||
err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect);
|
err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2281,9 +2269,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
field.span,
|
field.span,
|
||||||
expr_t,
|
expr_t,
|
||||||
E0609,
|
E0609,
|
||||||
"no field `{}` on type `{}`",
|
"no field `{field}` on type `{expr_t}`",
|
||||||
field,
|
|
||||||
expr_t
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// try to add a suggestion in case the field is a nested field of a field of the Adt
|
// try to add a suggestion in case the field is a nested field of a field of the Adt
|
||||||
@ -2307,7 +2293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
field.span.shrink_to_lo(),
|
field.span.shrink_to_lo(),
|
||||||
"one of the expressions' fields has a field of the same name",
|
"one of the expressions' fields has a field of the same name",
|
||||||
format!("{}.", field_path_str),
|
format!("{field_path_str}."),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2419,8 +2405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expr.span,
|
expr.span,
|
||||||
base_t,
|
base_t,
|
||||||
E0608,
|
E0608,
|
||||||
"cannot index into a value of type `{}`",
|
"cannot index into a value of type `{base_t}`",
|
||||||
base_t
|
|
||||||
);
|
);
|
||||||
// Try to give some advice about indexing tuples.
|
// Try to give some advice about indexing tuples.
|
||||||
if let ty::Tuple(..) = base_t.kind() {
|
if let ty::Tuple(..) = base_t.kind() {
|
||||||
@ -2434,7 +2419,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
expr.span,
|
expr.span,
|
||||||
"to access tuple elements, use",
|
"to access tuple elements, use",
|
||||||
format!("{}.{}", snip, i),
|
format!("{snip}.{i}"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
needs_note = false;
|
needs_note = false;
|
||||||
|
@ -567,7 +567,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
for (i, ty) in fields.iter().enumerate() {
|
for (i, ty) in fields.iter().enumerate() {
|
||||||
let descr_post = &format!(" in tuple element {}", i);
|
let descr_post = &format!(" in tuple element {i}");
|
||||||
let span = comps.and_then(|c| c.get(i)).map(|e| e.span).unwrap_or(data.source_span);
|
let span = comps.and_then(|c| c.get(i)).map(|e| e.span).unwrap_or(data.source_span);
|
||||||
if check_must_not_suspend_ty(
|
if check_must_not_suspend_ty(
|
||||||
fcx,
|
fcx,
|
||||||
|
@ -484,14 +484,14 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
|
|||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let msg =
|
let msg =
|
||||||
format!("unrecognized platform-specific intrinsic function: `{}`", name);
|
format!("unrecognized platform-specific intrinsic function: `{name}`");
|
||||||
tcx.sess.struct_span_err(it.span, &msg).emit();
|
tcx.sess.struct_span_err(it.span, &msg).emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let msg = format!("unrecognized platform-specific intrinsic function: `{}`", name);
|
let msg = format!("unrecognized platform-specific intrinsic function: `{name}`");
|
||||||
tcx.sess.struct_span_err(it.span, &msg).emit();
|
tcx.sess.struct_span_err(it.span, &msg).emit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -553,13 +553,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S
|
|||||||
// `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
|
// `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
|
||||||
// the consumer's responsibility to ensure all bytes that have been read
|
// the consumer's responsibility to ensure all bytes that have been read
|
||||||
// have defined values.
|
// have defined values.
|
||||||
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) {
|
if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
|
||||||
if alloc.inner().relocations().len() != 0 {
|
&& alloc.inner().relocations().len() != 0
|
||||||
let msg = "statics with a custom `#[link_section]` must be a \
|
{
|
||||||
simple list of bytes on the wasm target with no \
|
let msg = "statics with a custom `#[link_section]` must be a \
|
||||||
extra levels of indirection such as references";
|
simple list of bytes on the wasm target with no \
|
||||||
tcx.sess.span_err(span, msg);
|
extra levels of indirection such as references";
|
||||||
}
|
tcx.sess.span_err(span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,7 +587,7 @@ fn report_forbidden_specialization(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
Err(cname) => {
|
Err(cname) => {
|
||||||
err.note(&format!("parent implementation is in crate `{}`", cname));
|
err.note(&format!("parent implementation is in crate `{cname}`"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,10 +610,9 @@ fn missing_items_err(
|
|||||||
tcx.sess,
|
tcx.sess,
|
||||||
impl_span,
|
impl_span,
|
||||||
E0046,
|
E0046,
|
||||||
"not all trait items implemented, missing: `{}`",
|
"not all trait items implemented, missing: `{missing_items_msg}`",
|
||||||
missing_items_msg
|
|
||||||
);
|
);
|
||||||
err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
|
err.span_label(impl_span, format!("missing `{missing_items_msg}` in implementation"));
|
||||||
|
|
||||||
// `Span` before impl block closing brace.
|
// `Span` before impl block closing brace.
|
||||||
let hi = full_impl_span.hi() - BytePos(1);
|
let hi = full_impl_span.hi() - BytePos(1);
|
||||||
@ -628,7 +627,7 @@ fn missing_items_err(
|
|||||||
for trait_item in missing_items {
|
for trait_item in missing_items {
|
||||||
let snippet = suggestion_signature(trait_item, tcx);
|
let snippet = suggestion_signature(trait_item, tcx);
|
||||||
let code = format!("{}{}\n{}", padding, snippet, padding);
|
let code = format!("{}{}\n{}", padding, snippet, padding);
|
||||||
let msg = format!("implement the missing item: `{}`", snippet);
|
let msg = format!("implement the missing item: `{snippet}`");
|
||||||
let appl = Applicability::HasPlaceholders;
|
let appl = Applicability::HasPlaceholders;
|
||||||
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
|
if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
|
||||||
err.span_label(span, format!("`{}` from trait", trait_item.name));
|
err.span_label(span, format!("`{}` from trait", trait_item.name));
|
||||||
@ -653,10 +652,9 @@ fn missing_items_must_implement_one_of_err(
|
|||||||
tcx.sess,
|
tcx.sess,
|
||||||
impl_span,
|
impl_span,
|
||||||
E0046,
|
E0046,
|
||||||
"not all trait items implemented, missing one of: `{}`",
|
"not all trait items implemented, missing one of: `{missing_items_msg}`",
|
||||||
missing_items_msg
|
|
||||||
);
|
);
|
||||||
err.span_label(impl_span, format!("missing one of `{}` in implementation", missing_items_msg));
|
err.span_label(impl_span, format!("missing one of `{missing_items_msg}` in implementation"));
|
||||||
|
|
||||||
if let Some(annotation_span) = annotation_span {
|
if let Some(annotation_span) = annotation_span {
|
||||||
err.span_note(annotation_span, "required because of this annotation");
|
err.span_note(annotation_span, "required because of this annotation");
|
||||||
@ -749,9 +747,10 @@ fn fn_sig_suggestion<'tcx>(
|
|||||||
Some(match ty.kind() {
|
Some(match ty.kind() {
|
||||||
ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
|
ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
|
||||||
ty::Ref(reg, ref_ty, mutability) if i == 0 => {
|
ty::Ref(reg, ref_ty, mutability) if i == 0 => {
|
||||||
let reg = match &format!("{}", reg)[..] {
|
let reg = format!("{reg} ");
|
||||||
"'_" | "" => String::new(),
|
let reg = match ®[..] {
|
||||||
reg => format!("{} ", reg),
|
"'_ " | " " => "",
|
||||||
|
reg => reg,
|
||||||
};
|
};
|
||||||
if assoc.fn_has_self_parameter {
|
if assoc.fn_has_self_parameter {
|
||||||
match ref_ty.kind() {
|
match ref_ty.kind() {
|
||||||
@ -759,17 +758,17 @@ fn fn_sig_suggestion<'tcx>(
|
|||||||
format!("&{}{}self", reg, mutability.prefix_str())
|
format!("&{}{}self", reg, mutability.prefix_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => format!("self: {}", ty),
|
_ => format!("self: {ty}"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
format!("_: {}", ty)
|
format!("_: {ty}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if assoc.fn_has_self_parameter && i == 0 {
|
if assoc.fn_has_self_parameter && i == 0 {
|
||||||
format!("self: {}", ty)
|
format!("self: {ty}")
|
||||||
} else {
|
} else {
|
||||||
format!("_: {}", ty)
|
format!("_: {ty}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -779,7 +778,7 @@ fn fn_sig_suggestion<'tcx>(
|
|||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
let output = sig.output();
|
let output = sig.output();
|
||||||
let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() };
|
let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
|
||||||
|
|
||||||
let unsafety = sig.unsafety.prefix_str();
|
let unsafety = sig.unsafety.prefix_str();
|
||||||
let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
|
let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
|
||||||
@ -789,10 +788,7 @@ fn fn_sig_suggestion<'tcx>(
|
|||||||
// lifetimes between the `impl` and the `trait`, but this should be good enough to
|
// lifetimes between the `impl` and the `trait`, but this should be good enough to
|
||||||
// fill in a significant portion of the missing code, and other subsequent
|
// fill in a significant portion of the missing code, and other subsequent
|
||||||
// suggestions can help the user fix the code.
|
// suggestions can help the user fix the code.
|
||||||
format!(
|
format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}")
|
||||||
"{}fn {}{}({}){}{} {{ todo!() }}",
|
|
||||||
unsafety, ident, generics, args, output, where_clauses
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return placeholder code for the given associated item.
|
/// Return placeholder code for the given associated item.
|
||||||
@ -830,7 +826,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d
|
|||||||
.map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
|
.map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
|
let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
|
||||||
let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
|
let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {msg}");
|
||||||
err.span_label(sp, &msg);
|
err.span_label(sp, &msg);
|
||||||
if let [start @ .., end] = &*variant_spans {
|
if let [start @ .., end] = &*variant_spans {
|
||||||
for variant_span in start {
|
for variant_span in start {
|
||||||
@ -850,7 +846,7 @@ fn bad_non_zero_sized_fields<'tcx>(
|
|||||||
field_spans: impl Iterator<Item = Span>,
|
field_spans: impl Iterator<Item = Span>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
) {
|
) {
|
||||||
let msg = format!("needs at most one non-zero-sized field, but has {}", field_count);
|
let msg = format!("needs at most one non-zero-sized field, but has {field_count}");
|
||||||
let mut err = struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
sp,
|
sp,
|
||||||
@ -877,7 +873,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
|
|||||||
tcx.sess
|
tcx.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(span)
|
.span_to_snippet(span)
|
||||||
.map_or_else(|_| String::new(), |s| format!(" `{}`", s)),
|
.map_or_else(|_| String::new(), |s| format!(" `{s}`",)),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
@ -405,16 +405,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let mut pat_ty = ty;
|
let mut pat_ty = ty;
|
||||||
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind {
|
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind {
|
||||||
let expected = self.structurally_resolved_type(span, expected);
|
let expected = self.structurally_resolved_type(span, expected);
|
||||||
if let ty::Ref(_, inner_ty, _) = expected.kind() {
|
if let ty::Ref(_, inner_ty, _) = expected.kind()
|
||||||
if matches!(inner_ty.kind(), ty::Slice(_)) {
|
&& matches!(inner_ty.kind(), ty::Slice(_))
|
||||||
let tcx = self.tcx;
|
{
|
||||||
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
|
let tcx = self.tcx;
|
||||||
self.typeck_results
|
trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
|
||||||
.borrow_mut()
|
self.typeck_results
|
||||||
.treat_byte_string_as_slice
|
.borrow_mut()
|
||||||
.insert(lt.hir_id.local_id);
|
.treat_byte_string_as_slice
|
||||||
pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
|
.insert(lt.hir_id.local_id);
|
||||||
}
|
pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,14 +481,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
// Unify each side with `expected`.
|
// Unify each side with `expected`.
|
||||||
// Subtyping doesn't matter here, as the value is some kind of scalar.
|
// Subtyping doesn't matter here, as the value is some kind of scalar.
|
||||||
let demand_eqtype = |x: &mut _, y| {
|
let demand_eqtype = |x: &mut _, y| {
|
||||||
if let Some((ref mut fail, x_ty, x_span)) = *x {
|
if let Some((ref mut fail, x_ty, x_span)) = *x
|
||||||
if let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) {
|
&& let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti)
|
||||||
if let Some((_, y_ty, y_span)) = y {
|
{
|
||||||
self.endpoint_has_type(&mut err, y_span, y_ty);
|
if let Some((_, y_ty, y_span)) = y {
|
||||||
}
|
self.endpoint_has_type(&mut err, y_span, y_ty);
|
||||||
err.emit();
|
}
|
||||||
*fail = true;
|
err.emit();
|
||||||
};
|
*fail = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
demand_eqtype(&mut lhs, rhs);
|
demand_eqtype(&mut lhs, rhs);
|
||||||
@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
|
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
|
||||||
let hir = self.tcx.hir();
|
let hir = self.tcx.hir();
|
||||||
let var_ty = self.resolve_vars_with_obligations(var_ty);
|
let var_ty = self.resolve_vars_with_obligations(var_ty);
|
||||||
let msg = format!("first introduced with type `{}` here", var_ty);
|
let msg = format!("first introduced with type `{var_ty}` here");
|
||||||
err.span_label(hir.span(var_id), msg);
|
err.span_label(hir.span(var_id), msg);
|
||||||
let in_match = hir.parent_iter(var_id).any(|(_, n)| {
|
let in_match = hir.parent_iter(var_id).any(|(_, n)| {
|
||||||
matches!(
|
matches!(
|
||||||
@ -665,8 +665,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
{
|
{
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
*span,
|
*span,
|
||||||
&format!("did you mean `{}`", snippet),
|
&format!("did you mean `{snippet}`"),
|
||||||
format!(" &{}", expected),
|
format!(" &{expected}"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -701,7 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
"type `{}` cannot be dereferenced",
|
"type `{}` cannot be dereferenced",
|
||||||
type_str
|
type_str
|
||||||
);
|
);
|
||||||
err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
|
err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
|
||||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||||
err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
|
err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
|
||||||
}
|
}
|
||||||
@ -918,7 +918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
path_str
|
path_str
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
|
let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}");
|
||||||
match res {
|
match res {
|
||||||
Res::Def(DefKind::Fn | DefKind::AssocFn, _) => {
|
Res::Def(DefKind::Fn | DefKind::AssocFn, _) => {
|
||||||
err.span_label(pat.span, "`fn` calls are not allowed in patterns");
|
err.span_label(pat.span, "`fn` calls are not allowed in patterns");
|
||||||
@ -1396,8 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
pat.span,
|
pat.span,
|
||||||
E0769,
|
E0769,
|
||||||
"tuple variant `{}` written as struct variant",
|
"tuple variant `{path}` written as struct variant",
|
||||||
path
|
|
||||||
);
|
);
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
qpath.span().shrink_to_hi().to(pat.span.shrink_to_hi()),
|
qpath.span().shrink_to_hi().to(pat.span.shrink_to_hi()),
|
||||||
@ -1422,8 +1421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
sess,
|
sess,
|
||||||
pat.span,
|
pat.span,
|
||||||
E0638,
|
E0638,
|
||||||
"`..` required with {} marked as non-exhaustive",
|
"`..` required with {descr} marked as non-exhaustive",
|
||||||
descr
|
|
||||||
);
|
);
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
sp_comma,
|
sp_comma,
|
||||||
@ -1442,8 +1440,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
"field `{}` bound multiple times in the pattern",
|
"field `{}` bound multiple times in the pattern",
|
||||||
ident
|
ident
|
||||||
)
|
)
|
||||||
.span_label(span, format!("multiple uses of `{}` in pattern", ident))
|
.span_label(span, format!("multiple uses of `{ident}` in pattern"))
|
||||||
.span_label(other_field, format!("first use of `{}`", ident))
|
.span_label(other_field, format!("first use of `{ident}`"))
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let ty = self.resolve_vars_if_possible(ty);
|
let ty = self.resolve_vars_if_possible(ty);
|
||||||
let mut err = self.tcx.sess.struct_span_err(
|
let mut err = self.tcx.sess.struct_span_err(
|
||||||
span,
|
span,
|
||||||
&format!("negative integers cannot be used to index on a `{}`", ty),
|
&format!("negative integers cannot be used to index on a `{ty}`"),
|
||||||
);
|
);
|
||||||
err.span_label(span, &format!("cannot use a negative integer for indexing on `{}`", ty));
|
err.span_label(span, &format!("cannot use a negative integer for indexing on `{ty}`"));
|
||||||
if let (hir::ExprKind::Path(..), Ok(snippet)) =
|
if let (hir::ExprKind::Path(..), Ok(snippet)) =
|
||||||
(&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
|
(&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
|
||||||
{
|
{
|
||||||
@ -84,10 +84,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span.shrink_to_lo(),
|
span.shrink_to_lo(),
|
||||||
&format!(
|
&format!(
|
||||||
"to access an element starting from the end of the `{}`, compute the index",
|
"to access an element starting from the end of the `{ty}`, compute the index",
|
||||||
ty,
|
|
||||||
),
|
),
|
||||||
format!("{}.len() ", snippet),
|
format!("{snippet}.len() "),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -314,32 +313,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id);
|
self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id);
|
||||||
if let Some(mut adjustments) = previous_adjustments {
|
if let Some(mut adjustments) = previous_adjustments {
|
||||||
for adjustment in &mut adjustments {
|
for adjustment in &mut adjustments {
|
||||||
if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
|
if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind
|
||||||
if let Some(ok) = self.try_mutable_overloaded_place_op(
|
&& let Some(ok) = self.try_mutable_overloaded_place_op(
|
||||||
expr.span,
|
expr.span,
|
||||||
source,
|
source,
|
||||||
&[],
|
&[],
|
||||||
PlaceOp::Deref,
|
PlaceOp::Deref,
|
||||||
) {
|
)
|
||||||
let method = self.register_infer_ok_obligations(ok);
|
{
|
||||||
if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
|
let method = self.register_infer_ok_obligations(ok);
|
||||||
*deref = OverloadedDeref { region, mutbl, span: deref.span };
|
if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
|
||||||
}
|
*deref = OverloadedDeref { region, mutbl, span: deref.span };
|
||||||
// If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
|
}
|
||||||
// This helps avoid accidental drops.
|
// If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
|
||||||
if inside_union
|
// This helps avoid accidental drops.
|
||||||
&& source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop())
|
if inside_union
|
||||||
{
|
&& source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop())
|
||||||
let mut err = self.tcx.sess.struct_span_err(
|
{
|
||||||
expr.span,
|
let mut err = self.tcx.sess.struct_span_err(
|
||||||
"not automatically applying `DerefMut` on `ManuallyDrop` union field",
|
expr.span,
|
||||||
);
|
"not automatically applying `DerefMut` on `ManuallyDrop` union field",
|
||||||
err.help(
|
);
|
||||||
"writing to this reference calls the destructor for the old value",
|
err.help(
|
||||||
);
|
"writing to this reference calls the destructor for the old value",
|
||||||
err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor");
|
);
|
||||||
err.emit();
|
err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor");
|
||||||
}
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
source = adjustment.target;
|
source = adjustment.target;
|
||||||
|
@ -317,13 +317,8 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
|||||||
self.body_id = body_id.hir_id;
|
self.body_id = body_id.hir_id;
|
||||||
self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
|
self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
|
||||||
|
|
||||||
let fn_sig = {
|
let Some(fn_sig) = self.typeck_results.borrow().liberated_fn_sigs().get(id) else {
|
||||||
match self.typeck_results.borrow().liberated_fn_sigs().get(id) {
|
bug!("No fn-sig entry for id={:?}", id);
|
||||||
Some(f) => *f,
|
|
||||||
None => {
|
|
||||||
bug!("No fn-sig entry for id={:?}", id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Collect the types from which we create inferred bounds.
|
// Collect the types from which we create inferred bounds.
|
||||||
@ -642,12 +637,9 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
|||||||
ignore_err!(self.with_mc(|mc| {
|
ignore_err!(self.with_mc(|mc| {
|
||||||
mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id, .. }| {
|
mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id, .. }| {
|
||||||
// `ref x` pattern
|
// `ref x` pattern
|
||||||
if let PatKind::Binding(..) = kind {
|
if let PatKind::Binding(..) = kind
|
||||||
if let Some(ty::BindByReference(mutbl)) =
|
&& let Some(ty::BindByReference(mutbl)) = mc.typeck_results.extract_binding_mode(self.tcx.sess, *hir_id, *span) {
|
||||||
mc.typeck_results.extract_binding_mode(self.tcx.sess, *hir_id, *span)
|
self.link_region_from_node_type(*span, *hir_id, mutbl, sub_cmt);
|
||||||
{
|
|
||||||
self.link_region_from_node_type(*span, *hir_id, mutbl, sub_cmt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
@ -862,7 +862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
diagnostics_builder.span_suggestion(
|
diagnostics_builder.span_suggestion(
|
||||||
closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(),
|
closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(),
|
||||||
&diagnostic_msg,
|
&diagnostic_msg,
|
||||||
format!("\n{}{};", indent, migration_string),
|
format!("\n{indent}{migration_string};"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
} else if line1.starts_with('{') {
|
} else if line1.starts_with('{') {
|
||||||
@ -873,7 +873,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
diagnostics_builder.span_suggestion(
|
diagnostics_builder.span_suggestion(
|
||||||
closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(),
|
closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(),
|
||||||
&diagnostic_msg,
|
&diagnostic_msg,
|
||||||
format!(" {};", migration_string),
|
format!(" {migration_string};"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -882,7 +882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
diagnostics_builder.multipart_suggestion(
|
diagnostics_builder.multipart_suggestion(
|
||||||
&diagnostic_msg,
|
&diagnostic_msg,
|
||||||
vec![
|
vec![
|
||||||
(closure_body_span.shrink_to_lo(), format!("{{ {}; ", migration_string)),
|
(closure_body_span.shrink_to_lo(), format!("{{ {migration_string}; ")),
|
||||||
(closure_body_span.shrink_to_hi(), " }".to_string()),
|
(closure_body_span.shrink_to_hi(), " }".to_string()),
|
||||||
],
|
],
|
||||||
Applicability::MachineApplicable
|
Applicability::MachineApplicable
|
||||||
@ -1527,7 +1527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
self.tcx.sess.struct_span_err(closure_span, "First Pass analysis includes:");
|
self.tcx.sess.struct_span_err(closure_span, "First Pass analysis includes:");
|
||||||
for (place, capture_info) in capture_information {
|
for (place, capture_info) in capture_information {
|
||||||
let capture_str = construct_capture_info_string(self.tcx, place, capture_info);
|
let capture_str = construct_capture_info_string(self.tcx, place, capture_info);
|
||||||
let output_str = format!("Capturing {}", capture_str);
|
let output_str = format!("Capturing {capture_str}");
|
||||||
|
|
||||||
let span =
|
let span =
|
||||||
capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
|
capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
|
||||||
@ -1552,7 +1552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
let capture_str =
|
let capture_str =
|
||||||
construct_capture_info_string(self.tcx, place, capture_info);
|
construct_capture_info_string(self.tcx, place, capture_info);
|
||||||
let output_str = format!("Min Capture {}", capture_str);
|
let output_str = format!("Min Capture {capture_str}");
|
||||||
|
|
||||||
if capture.info.path_expr_id != capture.info.capture_kind_expr_id {
|
if capture.info.path_expr_id != capture.info.capture_kind_expr_id {
|
||||||
let path_span = capture_info
|
let path_span = capture_info
|
||||||
@ -1969,7 +1969,7 @@ fn construct_place_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String
|
|||||||
projections_str.push_str(proj.as_str());
|
projections_str.push_str(proj.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
format!("{}[{}]", variable_name, projections_str)
|
format!("{variable_name}[{projections_str}]")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_capture_kind_reason_string<'tcx>(
|
fn construct_capture_kind_reason_string<'tcx>(
|
||||||
@ -1984,13 +1984,13 @@ fn construct_capture_kind_reason_string<'tcx>(
|
|||||||
ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind),
|
ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind),
|
||||||
};
|
};
|
||||||
|
|
||||||
format!("{} captured as {} here", place_str, capture_kind_str)
|
format!("{place_str} captured as {capture_kind_str} here")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_path_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String {
|
fn construct_path_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String {
|
||||||
let place_str = construct_place_string(tcx, place);
|
let place_str = construct_place_string(tcx, place);
|
||||||
|
|
||||||
format!("{} used here", place_str)
|
format!("{place_str} used here")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_capture_info_string<'tcx>(
|
fn construct_capture_info_string<'tcx>(
|
||||||
@ -2004,7 +2004,7 @@ fn construct_capture_info_string<'tcx>(
|
|||||||
ty::UpvarCapture::ByValue => "ByValue".into(),
|
ty::UpvarCapture::ByValue => "ByValue".into(),
|
||||||
ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind),
|
ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind),
|
||||||
};
|
};
|
||||||
format!("{} -> {}", place_str, capture_kind_str)
|
format!("{place_str} -> {capture_kind_str}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
|
fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
|
||||||
@ -2035,16 +2035,16 @@ fn migration_suggestion_for_2229(
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let migration_ref_concat =
|
let migration_ref_concat =
|
||||||
need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::<Vec<_>>().join(", ");
|
need_migrations_variables.iter().map(|v| format!("&{v}")).collect::<Vec<_>>().join(", ");
|
||||||
|
|
||||||
let migration_string = if 1 == need_migrations.len() {
|
let migration_string = if 1 == need_migrations.len() {
|
||||||
format!("let _ = {}", migration_ref_concat)
|
format!("let _ = {migration_ref_concat}")
|
||||||
} else {
|
} else {
|
||||||
format!("let _ = ({})", migration_ref_concat)
|
format!("let _ = ({migration_ref_concat})")
|
||||||
};
|
};
|
||||||
|
|
||||||
let migrated_variables_concat =
|
let migrated_variables_concat =
|
||||||
need_migrations_variables.iter().map(|v| format!("`{}`", v)).collect::<Vec<_>>().join(", ");
|
need_migrations_variables.iter().map(|v| format!("`{v}`")).collect::<Vec<_>>().join(", ");
|
||||||
|
|
||||||
(migration_string, migrated_variables_concat)
|
(migration_string, migrated_variables_concat)
|
||||||
}
|
}
|
||||||
|
@ -230,8 +230,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
self_ty.span,
|
self_ty.span,
|
||||||
&format!(
|
&format!(
|
||||||
"first argument of `call` in `{}` lang item must be a reference",
|
"first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
|
||||||
fn_lang_item_name
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
@ -241,8 +240,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
*span,
|
*span,
|
||||||
&format!(
|
&format!(
|
||||||
"`call` function in `{}` lang item takes exactly two arguments",
|
"`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
|
||||||
fn_lang_item_name
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
@ -252,8 +250,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
trait_item.span,
|
trait_item.span,
|
||||||
&format!(
|
&format!(
|
||||||
"`call` trait item in `{}` lang item must be a function",
|
"`call` trait item in `{fn_lang_item_name}` lang item must be a function",
|
||||||
fn_lang_item_name
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
@ -432,7 +429,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
|
|||||||
);
|
);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
gat_item_hir.generics.where_clause.tail_span_for_suggestion(),
|
gat_item_hir.generics.where_clause.tail_span_for_suggestion(),
|
||||||
&format!("add the required where clause{}", plural),
|
&format!("add the required where clause{plural}"),
|
||||||
suggestion,
|
suggestion,
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
@ -523,7 +520,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
|
|||||||
// In our example, requires that `Self: 'a`
|
// In our example, requires that `Self: 'a`
|
||||||
if ty_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *ty, *region_a) {
|
if ty_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *ty, *region_a) {
|
||||||
debug!(?ty_idx, ?region_a_idx);
|
debug!(?ty_idx, ?region_a_idx);
|
||||||
debug!("required clause: {} must outlive {}", ty, region_a);
|
debug!("required clause: {ty} must outlive {region_a}");
|
||||||
// Translate into the generic parameters of the GAT. In
|
// Translate into the generic parameters of the GAT. In
|
||||||
// our example, the type was `Self`, which will also be
|
// our example, the type was `Self`, which will also be
|
||||||
// `Self` in the GAT.
|
// `Self` in the GAT.
|
||||||
@ -560,7 +557,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
|
|||||||
}
|
}
|
||||||
if region_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *region_a, *region_b) {
|
if region_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *region_a, *region_b) {
|
||||||
debug!(?region_a_idx, ?region_b_idx);
|
debug!(?region_a_idx, ?region_b_idx);
|
||||||
debug!("required clause: {} must outlive {}", region_a, region_b);
|
debug!("required clause: {region_a} must outlive {region_b}");
|
||||||
// Translate into the generic parameters of the GAT.
|
// Translate into the generic parameters of the GAT.
|
||||||
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
|
||||||
let region_a_param =
|
let region_a_param =
|
||||||
@ -869,7 +866,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
|||||||
)
|
)
|
||||||
.span_label(
|
.span_label(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
|
format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
@ -884,7 +881,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
|||||||
ty::RawPtr(_) => Some("raw pointers"),
|
ty::RawPtr(_) => Some("raw pointers"),
|
||||||
_ => {
|
_ => {
|
||||||
is_ptr = false;
|
is_ptr = false;
|
||||||
err_ty_str = format!("`{}`", ty);
|
err_ty_str = format!("`{ty}`");
|
||||||
Some(err_ty_str.as_str())
|
Some(err_ty_str.as_str())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -894,16 +891,14 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
|||||||
tcx.sess.span_err(
|
tcx.sess.span_err(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
&format!(
|
&format!(
|
||||||
"using {} as const generic parameters is forbidden",
|
"using {unsupported_type} as const generic parameters is forbidden",
|
||||||
unsupported_type
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let mut err = tcx.sess.struct_span_err(
|
let mut err = tcx.sess.struct_span_err(
|
||||||
hir_ty.span,
|
hir_ty.span,
|
||||||
&format!(
|
&format!(
|
||||||
"{} is forbidden as the type of a const generic parameter",
|
"{unsupported_type} is forbidden as the type of a const generic parameter",
|
||||||
unsupported_type
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
err.note("the only supported types are integers, `bool` and `char`");
|
err.note("the only supported types are integers, `bool` and `char`");
|
||||||
@ -1567,9 +1562,8 @@ fn check_method_receiver<'fcx, 'tcx>(
|
|||||||
sym::arbitrary_self_types,
|
sym::arbitrary_self_types,
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
"`{}` cannot be used as the type of `self` without \
|
"`{receiver_ty}` cannot be used as the type of `self` without \
|
||||||
the `arbitrary_self_types` feature",
|
the `arbitrary_self_types` feature",
|
||||||
receiver_ty,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.help(HELP_FOR_SELF_TYPE)
|
.help(HELP_FOR_SELF_TYPE)
|
||||||
@ -1587,8 +1581,7 @@ fn e0307<'tcx>(fcx: &FnCtxt<'_, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
|
|||||||
fcx.tcx.sess.diagnostic(),
|
fcx.tcx.sess.diagnostic(),
|
||||||
span,
|
span,
|
||||||
E0307,
|
E0307,
|
||||||
"invalid `self` parameter type: {}",
|
"invalid `self` parameter type: {receiver_ty}"
|
||||||
receiver_ty,
|
|
||||||
)
|
)
|
||||||
.note("type of `self` must be `Self` or a type that dereferences to it")
|
.note("type of `self` must be `Self` or a type that dereferences to it")
|
||||||
.help(HELP_FOR_SELF_TYPE)
|
.help(HELP_FOR_SELF_TYPE)
|
||||||
@ -1793,7 +1786,7 @@ fn report_bivariance(
|
|||||||
tcx.def_path_str(def_id),
|
tcx.def_path_str(def_id),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!("consider removing `{}` or referring to it in a field", param_name)
|
format!("consider removing `{param_name}` or referring to it in a field")
|
||||||
};
|
};
|
||||||
err.help(&msg);
|
err.help(&msg);
|
||||||
|
|
||||||
@ -1993,8 +1986,7 @@ fn error_392(
|
|||||||
span: Span,
|
span: Span,
|
||||||
param_name: Symbol,
|
param_name: Symbol,
|
||||||
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||||
let mut err =
|
let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{param_name}` is never used");
|
||||||
struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name);
|
|
||||||
err.span_label(span, "unused parameter");
|
err.span_label(span, "unused parameter");
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user