Auto merge of #112681 - GuillaumeGomez:rollup-rwn4086, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #112403 (Prevent `.eh_frame` from being emitted for `-C panic=abort`) - #112517 (`suspicious_double_ref_op`: don't lint on `.borrow()`) - #112529 (Extend `unused_must_use` to cover block exprs) - #112614 (tweak suggestion for argument-position `impl ?Sized`) - #112654 (normalize closure output in equate_inputs_and_outputs) - #112660 (Migrate GUI colors test to original CSS color format) - #112664 (Add support for test tmpdir to fuchsia test runner) - #112669 (Fix comment for ptr alignment checks in codegen) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0252b4093f
55 changed files with 578 additions and 213 deletions
|
@ -67,7 +67,7 @@ struct ArenaChunk<T = u8> {
|
|||
|
||||
unsafe impl<#[may_dangle] T> Drop for ArenaChunk<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe { Box::from_raw(self.storage.as_mut()) };
|
||||
unsafe { drop(Box::from_raw(self.storage.as_mut())) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,21 +124,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
// Return types are a bit more complex. They may contain opaque `impl Trait` types.
|
||||
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
|
||||
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
if let Err(terr) = self.eq_types(
|
||||
normalized_output_ty,
|
||||
mir_output_ty,
|
||||
Locations::All(output_span),
|
||||
ConstraintCategory::BoringNoLocation,
|
||||
) {
|
||||
span_mirbug!(
|
||||
self,
|
||||
Location::START,
|
||||
"equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
|
||||
normalized_output_ty,
|
||||
mir_output_ty,
|
||||
terr
|
||||
);
|
||||
};
|
||||
self.equate_normalized_input_or_output(normalized_output_ty, mir_output_ty, output_span);
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
|
|
|
@ -616,7 +616,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
AssertKind::MisalignedPointerDereference { ref required, ref found } => {
|
||||
let required = self.codegen_operand(bx, required).immediate();
|
||||
let found = self.codegen_operand(bx, found).immediate();
|
||||
// It's `fn panic_bounds_check(index: usize, len: usize)`,
|
||||
// It's `fn panic_misaligned_pointer_dereference(required: usize, found: usize)`,
|
||||
// and `#[track_caller]` adds an implicit third argument.
|
||||
(LangItem::PanicMisalignedPointerDereference, vec![required, found, location])
|
||||
}
|
||||
|
|
|
@ -479,13 +479,11 @@ lint_requested_level = requested on the command line with `{$level} {$lint_name}
|
|||
lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target
|
||||
.label = target type is set here
|
||||
|
||||
lint_suspicious_double_ref_op =
|
||||
using `.{$call}()` on a double reference, which returns `{$ty}` instead of {$op ->
|
||||
*[should_not_happen] [{$op}]
|
||||
[deref] dereferencing
|
||||
[borrow] borrowing
|
||||
[clone] cloning
|
||||
} the inner type
|
||||
lint_suspicious_double_ref_clone =
|
||||
using `.clone()` on a double reference, which returns `{$ty}` instead of cloning the inner type
|
||||
|
||||
lint_suspicious_double_ref_deref =
|
||||
using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
|
||||
|
||||
lint_trivial_untranslatable_diag = diagnostic with static strings only
|
||||
|
||||
|
|
|
@ -1231,11 +1231,15 @@ pub struct NoopMethodCallDiag<'a> {
|
|||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_suspicious_double_ref_op)]
|
||||
pub struct SuspiciousDoubleRefDiag<'a> {
|
||||
pub call: Symbol,
|
||||
#[diag(lint_suspicious_double_ref_deref)]
|
||||
pub struct SuspiciousDoubleRefDerefDiag<'a> {
|
||||
pub ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_suspicious_double_ref_clone)]
|
||||
pub struct SuspiciousDoubleRefCloneDiag<'a> {
|
||||
pub ty: Ty<'a>,
|
||||
pub op: &'static str,
|
||||
}
|
||||
|
||||
// pass_by_value.rs
|
||||
|
@ -1551,8 +1555,29 @@ pub struct UnusedOp<'a> {
|
|||
pub op: &'a str,
|
||||
#[label]
|
||||
pub label: Span,
|
||||
#[suggestion(style = "verbose", code = "let _ = ", applicability = "maybe-incorrect")]
|
||||
pub suggestion: Span,
|
||||
#[subdiagnostic]
|
||||
pub suggestion: UnusedOpSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum UnusedOpSuggestion {
|
||||
#[suggestion(
|
||||
lint_suggestion,
|
||||
style = "verbose",
|
||||
code = "let _ = ",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
NormalExpr {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
|
||||
BlockTailExpr {
|
||||
#[suggestion_part(code = "let _ = ")]
|
||||
before_span: Span,
|
||||
#[suggestion_part(code = ";")]
|
||||
after_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
|
@ -1595,15 +1620,25 @@ pub struct UnusedDef<'a, 'b> {
|
|||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
lint_suggestion,
|
||||
style = "verbose",
|
||||
code = "let _ = ",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub struct UnusedDefSuggestion {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub enum UnusedDefSuggestion {
|
||||
#[suggestion(
|
||||
lint_suggestion,
|
||||
style = "verbose",
|
||||
code = "let _ = ",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
NormalExpr {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
|
||||
BlockTailExpr {
|
||||
#[suggestion_part(code = "let _ = ")]
|
||||
before_span: Span,
|
||||
#[suggestion_part(code = ";")]
|
||||
after_span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
// Needed because of def_path_str
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::context::LintContext;
|
||||
use crate::lints::{NoopMethodCallDiag, SuspiciousDoubleRefDiag};
|
||||
use crate::lints::{
|
||||
NoopMethodCallDiag, SuspiciousDoubleRefCloneDiag, SuspiciousDoubleRefDerefDiag,
|
||||
};
|
||||
use crate::LateContext;
|
||||
use crate::LateLintPass;
|
||||
use rustc_hir::def::DefKind;
|
||||
|
@ -76,22 +78,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||
|
||||
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
|
||||
// traits and ignore any other method call.
|
||||
let did = match cx.typeck_results().type_dependent_def(expr.hir_id) {
|
||||
// Verify we are dealing with a method/associated function.
|
||||
Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) {
|
||||
// Check that we're dealing with a trait method for one of the traits we care about.
|
||||
Some(trait_id)
|
||||
if matches!(
|
||||
cx.tcx.get_diagnostic_name(trait_id),
|
||||
Some(sym::Borrow | sym::Clone | sym::Deref)
|
||||
) =>
|
||||
{
|
||||
did
|
||||
}
|
||||
_ => return,
|
||||
},
|
||||
_ => return,
|
||||
|
||||
let Some((DefKind::AssocFn, did)) =
|
||||
cx.typeck_results().type_dependent_def(expr.hir_id)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(trait_id) = cx.tcx.trait_of_item(did) else { return };
|
||||
|
||||
if !matches!(
|
||||
cx.tcx.get_diagnostic_name(trait_id),
|
||||
Some(sym::Borrow | sym::Clone | sym::Deref)
|
||||
) {
|
||||
return;
|
||||
};
|
||||
|
||||
let substs = cx
|
||||
.tcx
|
||||
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_substs(expr.hir_id));
|
||||
|
@ -102,13 +104,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||
// (Re)check that it implements the noop diagnostic.
|
||||
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
|
||||
|
||||
let op = match name {
|
||||
sym::noop_method_borrow => "borrow",
|
||||
sym::noop_method_clone => "clone",
|
||||
sym::noop_method_deref => "deref",
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let receiver_ty = cx.typeck_results().expr_ty(receiver);
|
||||
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
|
||||
let arg_adjustments = cx.typeck_results().expr_adjustments(receiver);
|
||||
|
@ -129,11 +124,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||
NoopMethodCallDiag { method: call.ident.name, receiver_ty, label: span },
|
||||
);
|
||||
} else {
|
||||
cx.emit_spanned_lint(
|
||||
SUSPICIOUS_DOUBLE_REF_OP,
|
||||
span,
|
||||
SuspiciousDoubleRefDiag { call: call.ident.name, ty: expr_ty, op },
|
||||
)
|
||||
match name {
|
||||
// If `type_of(x) == T` and `x.borrow()` is used to get `&T`,
|
||||
// then that should be allowed
|
||||
sym::noop_method_borrow => return,
|
||||
sym::noop_method_clone => cx.emit_spanned_lint(
|
||||
SUSPICIOUS_DOUBLE_REF_OP,
|
||||
span,
|
||||
SuspiciousDoubleRefCloneDiag { ty: expr_ty },
|
||||
),
|
||||
sym::noop_method_deref => cx.emit_spanned_lint(
|
||||
SUSPICIOUS_DOUBLE_REF_OP,
|
||||
span,
|
||||
SuspiciousDoubleRefDerefDiag { ty: expr_ty },
|
||||
),
|
||||
_ => return,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::lints::{
|
||||
PathStatementDrop, PathStatementDropSub, PathStatementNoEffect, UnusedAllocationDiag,
|
||||
UnusedAllocationMutDiag, UnusedClosure, UnusedDef, UnusedDefSuggestion, UnusedDelim,
|
||||
UnusedDelimSuggestion, UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedResult,
|
||||
UnusedDelimSuggestion, UnusedGenerator, UnusedImportBracesDiag, UnusedOp, UnusedOpSuggestion,
|
||||
UnusedResult,
|
||||
};
|
||||
use crate::Lint;
|
||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
|
@ -93,7 +94,15 @@ declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
|
|||
|
||||
impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
|
||||
let hir::StmtKind::Semi(expr) = s.kind else { return; };
|
||||
let hir::StmtKind::Semi(mut expr) = s.kind else { return; };
|
||||
|
||||
let mut expr_is_from_block = false;
|
||||
while let hir::ExprKind::Block(blk, ..) = expr.kind
|
||||
&& let hir::Block { expr: Some(e), .. } = blk
|
||||
{
|
||||
expr = e;
|
||||
expr_is_from_block = true;
|
||||
}
|
||||
|
||||
if let hir::ExprKind::Ret(..) = expr.kind {
|
||||
return;
|
||||
|
@ -113,6 +122,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
expr.span,
|
||||
"output of future returned by ",
|
||||
"",
|
||||
expr_is_from_block,
|
||||
)
|
||||
{
|
||||
// We have a bare `foo().await;` on an opaque type from an async function that was
|
||||
|
@ -125,13 +135,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
let must_use_result = is_ty_must_use(cx, ty, &expr, expr.span);
|
||||
let type_lint_emitted_or_suppressed = match must_use_result {
|
||||
Some(path) => {
|
||||
emit_must_use_untranslated(cx, &path, "", "", 1, false);
|
||||
emit_must_use_untranslated(cx, &path, "", "", 1, false, expr_is_from_block);
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
};
|
||||
|
||||
let fn_warned = check_fn_must_use(cx, expr);
|
||||
let fn_warned = check_fn_must_use(cx, expr, expr_is_from_block);
|
||||
|
||||
if !fn_warned && type_lint_emitted_or_suppressed {
|
||||
// We don't warn about unused unit or uninhabited types.
|
||||
|
@ -176,7 +186,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
UnusedOp {
|
||||
op: must_use_op,
|
||||
label: expr.span,
|
||||
suggestion: expr.span.shrink_to_lo(),
|
||||
suggestion: if expr_is_from_block {
|
||||
UnusedOpSuggestion::BlockTailExpr {
|
||||
before_span: expr.span.shrink_to_lo(),
|
||||
after_span: expr.span.shrink_to_hi(),
|
||||
}
|
||||
} else {
|
||||
UnusedOpSuggestion::NormalExpr { span: expr.span.shrink_to_lo() }
|
||||
},
|
||||
},
|
||||
);
|
||||
op_warned = true;
|
||||
|
@ -186,7 +203,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
cx.emit_spanned_lint(UNUSED_RESULTS, s.span, UnusedResult { ty });
|
||||
}
|
||||
|
||||
fn check_fn_must_use(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
|
||||
fn check_fn_must_use(
|
||||
cx: &LateContext<'_>,
|
||||
expr: &hir::Expr<'_>,
|
||||
expr_is_from_block: bool,
|
||||
) -> bool {
|
||||
let maybe_def_id = match expr.kind {
|
||||
hir::ExprKind::Call(ref callee, _) => {
|
||||
match callee.kind {
|
||||
|
@ -207,7 +228,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
_ => None,
|
||||
};
|
||||
if let Some(def_id) = maybe_def_id {
|
||||
check_must_use_def(cx, def_id, expr.span, "return value of ", "")
|
||||
check_must_use_def(
|
||||
cx,
|
||||
def_id,
|
||||
expr.span,
|
||||
"return value of ",
|
||||
"",
|
||||
expr_is_from_block,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -350,6 +378,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
span: Span,
|
||||
descr_pre_path: &str,
|
||||
descr_post_path: &str,
|
||||
expr_is_from_block: bool,
|
||||
) -> bool {
|
||||
is_def_must_use(cx, def_id, span)
|
||||
.map(|must_use_path| {
|
||||
|
@ -360,6 +389,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
descr_post_path,
|
||||
1,
|
||||
false,
|
||||
expr_is_from_block,
|
||||
)
|
||||
})
|
||||
.is_some()
|
||||
|
@ -373,6 +403,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
descr_post: &str,
|
||||
plural_len: usize,
|
||||
is_inner: bool,
|
||||
expr_is_from_block: bool,
|
||||
) {
|
||||
let plural_suffix = pluralize!(plural_len);
|
||||
|
||||
|
@ -380,21 +411,51 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
MustUsePath::Suppressed => {}
|
||||
MustUsePath::Boxed(path) => {
|
||||
let descr_pre = &format!("{}boxed ", descr_pre);
|
||||
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len, true);
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::Opaque(path) => {
|
||||
let descr_pre = &format!("{}implementer{} of ", descr_pre, plural_suffix);
|
||||
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len, true);
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::TraitObject(path) => {
|
||||
let descr_post = &format!(" trait object{}{}", plural_suffix, descr_post);
|
||||
emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len, true);
|
||||
emit_must_use_untranslated(
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::TupleElement(elems) => {
|
||||
for (index, path) in elems {
|
||||
let descr_post = &format!(" in tuple element {}", index);
|
||||
emit_must_use_untranslated(
|
||||
cx, path, descr_pre, descr_post, plural_len, true,
|
||||
cx,
|
||||
path,
|
||||
descr_pre,
|
||||
descr_post,
|
||||
plural_len,
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -407,6 +468,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
descr_post,
|
||||
plural_len.saturating_add(usize::try_from(*len).unwrap_or(usize::MAX)),
|
||||
true,
|
||||
expr_is_from_block,
|
||||
);
|
||||
}
|
||||
MustUsePath::Closure(span) => {
|
||||
|
@ -433,8 +495,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
|||
cx,
|
||||
def_id: *def_id,
|
||||
note: *reason,
|
||||
suggestion: (!is_inner)
|
||||
.then_some(UnusedDefSuggestion { span: span.shrink_to_lo() }),
|
||||
suggestion: (!is_inner).then_some(if expr_is_from_block {
|
||||
UnusedDefSuggestion::BlockTailExpr {
|
||||
before_span: span.shrink_to_lo(),
|
||||
after_span: span.shrink_to_hi(),
|
||||
}
|
||||
} else {
|
||||
UnusedDefSuggestion::NormalExpr { span: span.shrink_to_lo() }
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnostic
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::WherePredicate;
|
||||
use rustc_span::Span;
|
||||
use rustc_hir::{PredicateOrigin, WherePredicate};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use rustc_type_ir::sty::TyKind::*;
|
||||
|
||||
impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
|
||||
|
@ -156,10 +156,11 @@ enum SuggestChangingConstraintsMessage<'a> {
|
|||
RestrictBoundFurther,
|
||||
RestrictType { ty: &'a str },
|
||||
RestrictTypeFurther { ty: &'a str },
|
||||
RemovingQSized,
|
||||
RemoveMaybeUnsized,
|
||||
ReplaceMaybeUnsizedWithSized,
|
||||
}
|
||||
|
||||
fn suggest_removing_unsized_bound(
|
||||
fn suggest_changing_unsized_bound(
|
||||
generics: &hir::Generics<'_>,
|
||||
suggestions: &mut Vec<(Span, String, SuggestChangingConstraintsMessage<'_>)>,
|
||||
param: &hir::GenericParam<'_>,
|
||||
|
@ -183,12 +184,25 @@ fn suggest_removing_unsized_bound(
|
|||
if poly.trait_ref.trait_def_id() != def_id {
|
||||
continue;
|
||||
}
|
||||
let sp = generics.span_for_bound_removal(where_pos, pos);
|
||||
suggestions.push((
|
||||
sp,
|
||||
String::new(),
|
||||
SuggestChangingConstraintsMessage::RemovingQSized,
|
||||
));
|
||||
if predicate.origin == PredicateOrigin::ImplTrait && predicate.bounds.len() == 1 {
|
||||
// For `impl ?Sized` with no other bounds, suggest `impl Sized` instead.
|
||||
let bound_span = bound.span();
|
||||
if bound_span.can_be_used_for_suggestions() {
|
||||
let question_span = bound_span.with_hi(bound_span.lo() + BytePos(1));
|
||||
suggestions.push((
|
||||
question_span,
|
||||
String::new(),
|
||||
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
let sp = generics.span_for_bound_removal(where_pos, pos);
|
||||
suggestions.push((
|
||||
sp,
|
||||
String::new(),
|
||||
SuggestChangingConstraintsMessage::RemoveMaybeUnsized,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,14 +252,11 @@ pub fn suggest_constraining_type_params<'a>(
|
|||
{
|
||||
let mut sized_constraints =
|
||||
constraints.extract_if(|(_, def_id)| *def_id == tcx.lang_items().sized_trait());
|
||||
if let Some((constraint, def_id)) = sized_constraints.next() {
|
||||
if let Some((_, def_id)) = sized_constraints.next() {
|
||||
applicability = Applicability::MaybeIncorrect;
|
||||
|
||||
err.span_label(
|
||||
param.span,
|
||||
format!("this type parameter needs to be `{}`", constraint),
|
||||
);
|
||||
suggest_removing_unsized_bound(generics, &mut suggestions, param, def_id);
|
||||
err.span_label(param.span, "this type parameter needs to be `Sized`");
|
||||
suggest_changing_unsized_bound(generics, &mut suggestions, param, def_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,9 +406,12 @@ pub fn suggest_constraining_type_params<'a>(
|
|||
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty } => {
|
||||
Cow::from(format!("consider further restricting type parameter `{}`", ty))
|
||||
}
|
||||
SuggestChangingConstraintsMessage::RemovingQSized => {
|
||||
SuggestChangingConstraintsMessage::RemoveMaybeUnsized => {
|
||||
Cow::from("consider removing the `?Sized` bound to make the type parameter `Sized`")
|
||||
}
|
||||
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized => {
|
||||
Cow::from("consider replacing `?Sized` with `Sized`")
|
||||
}
|
||||
};
|
||||
|
||||
err.span_suggestion_verbose(span, msg, suggestion, applicability);
|
||||
|
|
|
@ -9,6 +9,7 @@ use rustc_middle::mir::{
|
|||
};
|
||||
use rustc_middle::ty::{Ty, TyCtxt, TypeAndMut};
|
||||
use rustc_session::Session;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
|
||||
pub struct CheckAlignment;
|
||||
|
||||
|
@ -236,7 +237,11 @@ fn insert_alignment_check<'tcx>(
|
|||
required: Operand::Copy(alignment),
|
||||
found: Operand::Copy(addr),
|
||||
}),
|
||||
unwind: UnwindAction::Terminate,
|
||||
unwind: if tcx.sess.panic_strategy() == PanicStrategy::Unwind {
|
||||
UnwindAction::Terminate
|
||||
} else {
|
||||
UnwindAction::Unreachable
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue