Auto merge of #133893 - fmease:rollup-11pi6fg, r=fmease
Rollup of 10 pull requests Successful merges: - #118833 (Add lint against function pointer comparisons) - #122161 (Fix suggestion when shorthand `self` has erroneous type) - #133233 (Add context to "const in pattern" errors) - #133761 (Update books) - #133843 (Do not emit empty suggestion) - #133863 (Rename `core_pattern_type` and `core_pattern_types` lib feature gates to `pattern_type_macro`) - #133872 (No need to create placeholders for GAT args in confirm_object_candidate) - #133874 (`fn_sig_for_fn_abi` should return a `ty::FnSig`, no need for a binder) - #133890 (Add a new test ui/incoherent-inherent-impls/no-other-unrelated-errors to check E0116 does not cause unrelated errors) - #133892 (Revert #133817) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0e98766a54
201 changed files with 2299 additions and 1115 deletions
|
@ -2566,6 +2566,18 @@ pub enum SelfKind {
|
||||||
Explicit(P<Ty>, Mutability),
|
Explicit(P<Ty>, Mutability),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SelfKind {
|
||||||
|
pub fn to_ref_suggestion(&self) -> String {
|
||||||
|
match self {
|
||||||
|
SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
|
||||||
|
SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
|
||||||
|
SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
|
||||||
|
unreachable!("if we had an explicit self, we wouldn't be here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type ExplicitSelf = Spanned<SelfKind>;
|
pub type ExplicitSelf = Spanned<SelfKind>;
|
||||||
|
|
||||||
impl Param {
|
impl Param {
|
||||||
|
|
|
@ -3394,7 +3394,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else {
|
let Some(ty) = self.node_ty_opt(tail_expr.hir_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if self.can_eq(self.param_env, expected_ty, ty) {
|
if self.can_eq(self.param_env, expected_ty, ty)
|
||||||
|
// FIXME: this happens with macro calls. Need to figure out why the stmt
|
||||||
|
// `println!();` doesn't include the `;` in its `Span`. (#133845)
|
||||||
|
// We filter these out to avoid ICEs with debug assertions on caused by
|
||||||
|
// empty suggestions.
|
||||||
|
&& stmt.span.hi() != tail_expr.span.hi()
|
||||||
|
{
|
||||||
err.span_suggestion_short(
|
err.span_suggestion_short(
|
||||||
stmt.span.with_lo(tail_expr.span.hi()),
|
stmt.span.with_lo(tail_expr.span.hi()),
|
||||||
"remove this semicolon",
|
"remove this semicolon",
|
||||||
|
|
|
@ -885,6 +885,12 @@ lint_unnameable_test_items = cannot test inner items
|
||||||
lint_unnecessary_qualification = unnecessary qualification
|
lint_unnecessary_qualification = unnecessary qualification
|
||||||
.suggestion = remove the unnecessary path segments
|
.suggestion = remove the unnecessary path segments
|
||||||
|
|
||||||
|
lint_unpredictable_fn_pointer_comparisons = function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
|
||||||
|
.note_duplicated_fn = the address of the same function can vary between different codegen units
|
||||||
|
.note_deduplicated_fn = furthermore, different functions could have the same address after being merged together
|
||||||
|
.note_visit_fn_addr_eq = for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
|
||||||
|
.fn_addr_eq_suggestion = refactor your code, or use `std::ptr::fn_addr_eq` to suppress the lint
|
||||||
|
|
||||||
lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::`
|
lint_unqualified_local_imports = `use` of a local item without leading `self::`, `super::`, or `crate::`
|
||||||
|
|
||||||
lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
|
lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
|
||||||
|
|
|
@ -1815,6 +1815,42 @@ pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
pub(crate) enum UnpredictableFunctionPointerComparisons<'a> {
|
||||||
|
#[diag(lint_unpredictable_fn_pointer_comparisons)]
|
||||||
|
#[note(lint_note_duplicated_fn)]
|
||||||
|
#[note(lint_note_deduplicated_fn)]
|
||||||
|
#[note(lint_note_visit_fn_addr_eq)]
|
||||||
|
Suggestion {
|
||||||
|
#[subdiagnostic]
|
||||||
|
sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a>,
|
||||||
|
},
|
||||||
|
#[diag(lint_unpredictable_fn_pointer_comparisons)]
|
||||||
|
#[note(lint_note_duplicated_fn)]
|
||||||
|
#[note(lint_note_deduplicated_fn)]
|
||||||
|
#[note(lint_note_visit_fn_addr_eq)]
|
||||||
|
Warn,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[multipart_suggestion(
|
||||||
|
lint_fn_addr_eq_suggestion,
|
||||||
|
style = "verbose",
|
||||||
|
applicability = "maybe-incorrect"
|
||||||
|
)]
|
||||||
|
pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> {
|
||||||
|
pub ne: &'a str,
|
||||||
|
pub cast_right: String,
|
||||||
|
pub deref_left: &'a str,
|
||||||
|
pub deref_right: &'a str,
|
||||||
|
#[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
|
||||||
|
pub left: Span,
|
||||||
|
#[suggestion_part(code = ", {deref_right}")]
|
||||||
|
pub middle: Span,
|
||||||
|
#[suggestion_part(code = "{cast_right})")]
|
||||||
|
pub right: Span,
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct ImproperCTypes<'a> {
|
pub(crate) struct ImproperCTypes<'a> {
|
||||||
pub ty: Ty<'a>,
|
pub ty: Ty<'a>,
|
||||||
pub desc: &'a str,
|
pub desc: &'a str,
|
||||||
|
|
|
@ -23,7 +23,9 @@ use crate::lints::{
|
||||||
AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion,
|
AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion,
|
||||||
AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad,
|
AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad,
|
||||||
AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons,
|
AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons,
|
||||||
InvalidNanComparisonsSuggestion, UnusedComparisons, VariantSizeDifferencesDiag,
|
InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons,
|
||||||
|
UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons,
|
||||||
|
VariantSizeDifferencesDiag,
|
||||||
};
|
};
|
||||||
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
|
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
|
||||||
|
|
||||||
|
@ -166,6 +168,35 @@ declare_lint! {
|
||||||
"detects ambiguous wide pointer comparisons"
|
"detects ambiguous wide pointer comparisons"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `unpredictable_function_pointer_comparisons` lint checks comparison
|
||||||
|
/// of function pointer as the operands.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// fn a() {}
|
||||||
|
/// fn b() {}
|
||||||
|
///
|
||||||
|
/// let f: fn() = a;
|
||||||
|
/// let g: fn() = b;
|
||||||
|
///
|
||||||
|
/// let _ = f == g;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// Function pointers comparisons do not produce meaningful result since
|
||||||
|
/// they are never guaranteed to be unique and could vary between different
|
||||||
|
/// code generation units. Furthermore, different functions could have the
|
||||||
|
/// same address after being merged together.
|
||||||
|
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
|
||||||
|
Warn,
|
||||||
|
"detects unpredictable function pointer comparisons"
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Default)]
|
#[derive(Copy, Clone, Default)]
|
||||||
pub(crate) struct TypeLimits {
|
pub(crate) struct TypeLimits {
|
||||||
/// Id of the last visited negated expression
|
/// Id of the last visited negated expression
|
||||||
|
@ -178,7 +209,8 @@ impl_lint_pass!(TypeLimits => [
|
||||||
UNUSED_COMPARISONS,
|
UNUSED_COMPARISONS,
|
||||||
OVERFLOWING_LITERALS,
|
OVERFLOWING_LITERALS,
|
||||||
INVALID_NAN_COMPARISONS,
|
INVALID_NAN_COMPARISONS,
|
||||||
AMBIGUOUS_WIDE_POINTER_COMPARISONS
|
AMBIGUOUS_WIDE_POINTER_COMPARISONS,
|
||||||
|
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS
|
||||||
]);
|
]);
|
||||||
|
|
||||||
impl TypeLimits {
|
impl TypeLimits {
|
||||||
|
@ -255,7 +287,7 @@ fn lint_nan<'tcx>(
|
||||||
cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint);
|
cx.emit_span_lint(INVALID_NAN_COMPARISONS, e.span, lint);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
enum ComparisonOp {
|
enum ComparisonOp {
|
||||||
BinOp(hir::BinOpKind),
|
BinOp(hir::BinOpKind),
|
||||||
Other,
|
Other,
|
||||||
|
@ -383,6 +415,100 @@ fn lint_wide_pointer<'tcx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lint_fn_pointer<'tcx>(
|
||||||
|
cx: &LateContext<'tcx>,
|
||||||
|
e: &'tcx hir::Expr<'tcx>,
|
||||||
|
cmpop: ComparisonOp,
|
||||||
|
l: &'tcx hir::Expr<'tcx>,
|
||||||
|
r: &'tcx hir::Expr<'tcx>,
|
||||||
|
) {
|
||||||
|
let peel_refs = |mut ty: Ty<'tcx>| -> (Ty<'tcx>, usize) {
|
||||||
|
let mut refs = 0;
|
||||||
|
|
||||||
|
while let ty::Ref(_, inner_ty, _) = ty.kind() {
|
||||||
|
ty = *inner_ty;
|
||||||
|
refs += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(ty, refs)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Left and right operands can have borrows, remove them
|
||||||
|
let l = l.peel_borrows();
|
||||||
|
let r = r.peel_borrows();
|
||||||
|
|
||||||
|
let Some(l_ty) = cx.typeck_results().expr_ty_opt(l) else { return };
|
||||||
|
let Some(r_ty) = cx.typeck_results().expr_ty_opt(r) else { return };
|
||||||
|
|
||||||
|
// Remove any references as `==` will deref through them (and count the
|
||||||
|
// number of references removed, for latter).
|
||||||
|
let (l_ty, l_ty_refs) = peel_refs(l_ty);
|
||||||
|
let (r_ty, r_ty_refs) = peel_refs(r_ty);
|
||||||
|
|
||||||
|
if !l_ty.is_fn() || !r_ty.is_fn() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's try to suggest `ptr::fn_addr_eq` if/when possible.
|
||||||
|
|
||||||
|
let is_eq_ne = matches!(cmpop, ComparisonOp::BinOp(hir::BinOpKind::Eq | hir::BinOpKind::Ne));
|
||||||
|
|
||||||
|
if !is_eq_ne {
|
||||||
|
// Neither `==` nor `!=`, we can't suggest `ptr::fn_addr_eq`, just show the warning.
|
||||||
|
return cx.emit_span_lint(
|
||||||
|
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
|
||||||
|
e.span,
|
||||||
|
UnpredictableFunctionPointerComparisons::Warn,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (Some(l_span), Some(r_span)) =
|
||||||
|
(l.span.find_ancestor_inside(e.span), r.span.find_ancestor_inside(e.span))
|
||||||
|
else {
|
||||||
|
// No appropriate spans for the left and right operands, just show the warning.
|
||||||
|
return cx.emit_span_lint(
|
||||||
|
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
|
||||||
|
e.span,
|
||||||
|
UnpredictableFunctionPointerComparisons::Warn,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let ne = if cmpop == ComparisonOp::BinOp(hir::BinOpKind::Ne) { "!" } else { "" };
|
||||||
|
|
||||||
|
// `ptr::fn_addr_eq` only works with raw pointer, deref any references.
|
||||||
|
let deref_left = &*"*".repeat(l_ty_refs);
|
||||||
|
let deref_right = &*"*".repeat(r_ty_refs);
|
||||||
|
|
||||||
|
let left = e.span.shrink_to_lo().until(l_span.shrink_to_lo());
|
||||||
|
let middle = l_span.shrink_to_hi().until(r_span.shrink_to_lo());
|
||||||
|
let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi());
|
||||||
|
|
||||||
|
// We only check for a right cast as `FnDef` == `FnPtr` is not possible,
|
||||||
|
// only `FnPtr == FnDef` is possible.
|
||||||
|
let cast_right = if !r_ty.is_fn_ptr() {
|
||||||
|
let fn_sig = r_ty.fn_sig(cx.tcx);
|
||||||
|
format!(" as {fn_sig}")
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.emit_span_lint(
|
||||||
|
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
|
||||||
|
e.span,
|
||||||
|
UnpredictableFunctionPointerComparisons::Suggestion {
|
||||||
|
sugg: UnpredictableFunctionPointerComparisonsSuggestion {
|
||||||
|
ne,
|
||||||
|
deref_left,
|
||||||
|
deref_right,
|
||||||
|
left,
|
||||||
|
middle,
|
||||||
|
right,
|
||||||
|
cast_right,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx hir::Expr<'tcx>) {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
|
@ -399,7 +525,9 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
||||||
cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
|
cx.emit_span_lint(UNUSED_COMPARISONS, e.span, UnusedComparisons);
|
||||||
} else {
|
} else {
|
||||||
lint_nan(cx, e, binop, l, r);
|
lint_nan(cx, e, binop, l, r);
|
||||||
lint_wide_pointer(cx, e, ComparisonOp::BinOp(binop.node), l, r);
|
let cmpop = ComparisonOp::BinOp(binop.node);
|
||||||
|
lint_wide_pointer(cx, e, cmpop, l, r);
|
||||||
|
lint_fn_pointer(cx, e, cmpop, l, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,6 +539,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
||||||
&& let Some(cmpop) = diag_item_cmpop(diag_item) =>
|
&& let Some(cmpop) = diag_item_cmpop(diag_item) =>
|
||||||
{
|
{
|
||||||
lint_wide_pointer(cx, e, cmpop, l, r);
|
lint_wide_pointer(cx, e, cmpop, l, r);
|
||||||
|
lint_fn_pointer(cx, e, cmpop, l, r);
|
||||||
}
|
}
|
||||||
hir::ExprKind::MethodCall(_, l, [r], _)
|
hir::ExprKind::MethodCall(_, l, [r], _)
|
||||||
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
|
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
|
||||||
|
@ -418,6 +547,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits {
|
||||||
&& let Some(cmpop) = diag_item_cmpop(diag_item) =>
|
&& let Some(cmpop) = diag_item_cmpop(diag_item) =>
|
||||||
{
|
{
|
||||||
lint_wide_pointer(cx, e, cmpop, l, r);
|
lint_wide_pointer(cx, e, cmpop, l, r);
|
||||||
|
lint_fn_pointer(cx, e, cmpop, l, r);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,12 +84,17 @@ mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
|
||||||
|
|
||||||
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
|
mir_build_confused = missing patterns are not covered because `{$variable}` is interpreted as a constant pattern, not a new variable
|
||||||
|
|
||||||
mir_build_const_param_in_pattern = const parameters cannot be referenced in patterns
|
mir_build_const_defined_here = constant defined here
|
||||||
|
|
||||||
mir_build_const_pattern_depends_on_generic_parameter =
|
mir_build_const_param_in_pattern = constant parameters cannot be referenced in patterns
|
||||||
constant pattern depends on a generic parameter
|
.label = can't be used in patterns
|
||||||
|
mir_build_const_param_in_pattern_def = constant defined here
|
||||||
|
|
||||||
|
mir_build_const_pattern_depends_on_generic_parameter = constant pattern cannot depend on generic parameters
|
||||||
|
.label = `const` depends on a generic parameter
|
||||||
|
|
||||||
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
|
mir_build_could_not_eval_const_pattern = could not evaluate constant pattern
|
||||||
|
.label = could not evaluate constant
|
||||||
|
|
||||||
mir_build_deref_raw_pointer_requires_unsafe =
|
mir_build_deref_raw_pointer_requires_unsafe =
|
||||||
dereference of raw pointer is unsafe and requires unsafe block
|
dereference of raw pointer is unsafe and requires unsafe block
|
||||||
|
@ -147,7 +152,8 @@ mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
|
||||||
|
|
||||||
mir_build_interpreted_as_const = introduce a variable instead
|
mir_build_interpreted_as_const = introduce a variable instead
|
||||||
|
|
||||||
mir_build_invalid_pattern = `{$non_sm_ty}` cannot be used in patterns
|
mir_build_invalid_pattern = {$prefix} `{$non_sm_ty}` cannot be used in patterns
|
||||||
|
.label = {$prefix} can't be used in patterns
|
||||||
|
|
||||||
mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
|
mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
|
||||||
[one] pattern
|
[one] pattern
|
||||||
|
@ -244,10 +250,12 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
|
||||||
.label = mutation of layout constrained field
|
.label = mutation of layout constrained field
|
||||||
|
|
||||||
mir_build_nan_pattern = cannot use NaN in patterns
|
mir_build_nan_pattern = cannot use NaN in patterns
|
||||||
|
.label = evaluates to `NaN`, which is not allowed in patterns
|
||||||
.note = NaNs compare inequal to everything, even themselves, so this pattern would never match
|
.note = NaNs compare inequal to everything, even themselves, so this pattern would never match
|
||||||
.help = try using the `is_nan` method instead
|
.help = try using the `is_nan` method instead
|
||||||
|
|
||||||
mir_build_non_const_path = runtime values cannot be referenced in patterns
|
mir_build_non_const_path = runtime values cannot be referenced in patterns
|
||||||
|
.label = references a runtime value
|
||||||
|
|
||||||
mir_build_non_empty_never_pattern =
|
mir_build_non_empty_never_pattern =
|
||||||
mismatched types
|
mismatched types
|
||||||
|
@ -265,13 +273,15 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type
|
||||||
.suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
.suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
||||||
.help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
|
.help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
|
||||||
|
|
||||||
mir_build_non_partial_eq_match =
|
mir_build_non_partial_eq_match = constant of non-structural type `{$ty}` in a pattern
|
||||||
to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq`
|
.label = constant of non-structural type
|
||||||
|
|
||||||
mir_build_pattern_not_covered = refutable pattern in {$origin}
|
mir_build_pattern_not_covered = refutable pattern in {$origin}
|
||||||
.pattern_ty = the matched value is of type `{$pattern_ty}`
|
.pattern_ty = the matched value is of type `{$pattern_ty}`
|
||||||
|
|
||||||
mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
mir_build_pointer_pattern = function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
|
.label = can't be used in patterns
|
||||||
|
.note = see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
||||||
|
|
||||||
|
@ -283,6 +293,8 @@ mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
|
||||||
.missing_box = `#[rustc_box]` requires the `owned_box` lang item
|
.missing_box = `#[rustc_box]` requires the `owned_box` lang item
|
||||||
|
|
||||||
mir_build_static_in_pattern = statics cannot be referenced in patterns
|
mir_build_static_in_pattern = statics cannot be referenced in patterns
|
||||||
|
.label = can't be used in patterns
|
||||||
|
mir_build_static_in_pattern_def = `static` defined here
|
||||||
|
|
||||||
mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||||
|
|
||||||
|
@ -310,12 +322,12 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
|
||||||
*[other] them
|
*[other] them
|
||||||
} into the body
|
} into the body
|
||||||
|
|
||||||
mir_build_type_not_structural =
|
mir_build_type_not_structural = constant of non-structural type `{$ty}` in a pattern
|
||||||
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq)]`
|
.label = constant of non-structural type
|
||||||
|
mir_build_type_not_structural_def = `{$ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
mir_build_type_not_structural_tip =
|
||||||
mir_build_type_not_structural_tip = the traits must be derived, manual `impl`s are not sufficient
|
the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
|
||||||
mir_build_unconditional_recursion = function cannot return without recursing
|
mir_build_unconditional_recursion = function cannot return without recursing
|
||||||
.label = cannot return without recursing
|
.label = cannot return without recursing
|
||||||
|
@ -334,6 +346,7 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
|
||||||
.label = access to union field
|
.label = access to union field
|
||||||
|
|
||||||
mir_build_union_pattern = cannot use unions in constant patterns
|
mir_build_union_pattern = cannot use unions in constant patterns
|
||||||
|
.label = can't use a `union` here
|
||||||
|
|
||||||
mir_build_unreachable_making_this_unreachable = collectively making this unreachable
|
mir_build_unreachable_making_this_unreachable = collectively making this unreachable
|
||||||
|
|
||||||
|
|
|
@ -631,20 +631,27 @@ pub(crate) struct NonExhaustiveMatchAllArmsGuarded;
|
||||||
#[diag(mir_build_static_in_pattern, code = E0158)]
|
#[diag(mir_build_static_in_pattern, code = E0158)]
|
||||||
pub(crate) struct StaticInPattern {
|
pub(crate) struct StaticInPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
|
#[label(mir_build_static_in_pattern_def)]
|
||||||
|
pub(crate) static_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_const_param_in_pattern, code = E0158)]
|
#[diag(mir_build_const_param_in_pattern, code = E0158)]
|
||||||
pub(crate) struct ConstParamInPattern {
|
pub(crate) struct ConstParamInPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
|
#[label(mir_build_const_param_in_pattern_def)]
|
||||||
|
pub(crate) const_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_non_const_path, code = E0080)]
|
#[diag(mir_build_non_const_path, code = E0080)]
|
||||||
pub(crate) struct NonConstPath {
|
pub(crate) struct NonConstPath {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,6 +702,7 @@ pub(crate) struct WantedConstant {
|
||||||
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
|
#[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)]
|
||||||
pub(crate) struct ConstPatternDependsOnGenericParameter {
|
pub(crate) struct ConstPatternDependsOnGenericParameter {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,6 +710,7 @@ pub(crate) struct ConstPatternDependsOnGenericParameter {
|
||||||
#[diag(mir_build_could_not_eval_const_pattern)]
|
#[diag(mir_build_could_not_eval_const_pattern)]
|
||||||
pub(crate) struct CouldNotEvalConstPattern {
|
pub(crate) struct CouldNotEvalConstPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,33 +876,43 @@ pub(crate) enum Conflict {
|
||||||
#[diag(mir_build_union_pattern)]
|
#[diag(mir_build_union_pattern)]
|
||||||
pub(crate) struct UnionPattern {
|
pub(crate) struct UnionPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_type_not_structural)]
|
#[diag(mir_build_type_not_structural)]
|
||||||
#[note(mir_build_type_not_structural_tip)]
|
|
||||||
#[note(mir_build_type_not_structural_more_info)]
|
|
||||||
pub(crate) struct TypeNotStructural<'tcx> {
|
pub(crate) struct TypeNotStructural<'tcx> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
pub(crate) non_sm_ty: Ty<'tcx>,
|
#[label(mir_build_type_not_structural_def)]
|
||||||
|
pub(crate) ty_def_span: Span,
|
||||||
|
pub(crate) ty: Ty<'tcx>,
|
||||||
|
#[note(mir_build_type_not_structural_tip)]
|
||||||
|
pub(crate) manual_partialeq_impl_span: Option<Span>,
|
||||||
|
#[note(mir_build_type_not_structural_more_info)]
|
||||||
|
pub(crate) manual_partialeq_impl_note: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_non_partial_eq_match)]
|
#[diag(mir_build_non_partial_eq_match)]
|
||||||
|
#[note(mir_build_type_not_structural_more_info)]
|
||||||
pub(crate) struct TypeNotPartialEq<'tcx> {
|
pub(crate) struct TypeNotPartialEq<'tcx> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
pub(crate) non_peq_ty: Ty<'tcx>,
|
pub(crate) ty: Ty<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_invalid_pattern)]
|
#[diag(mir_build_invalid_pattern)]
|
||||||
pub(crate) struct InvalidPattern<'tcx> {
|
pub(crate) struct InvalidPattern<'tcx> {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
pub(crate) non_sm_ty: Ty<'tcx>,
|
pub(crate) non_sm_ty: Ty<'tcx>,
|
||||||
|
pub(crate) prefix: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -910,13 +929,16 @@ pub(crate) struct UnsizedPattern<'tcx> {
|
||||||
#[help]
|
#[help]
|
||||||
pub(crate) struct NaNPattern {
|
pub(crate) struct NaNPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(mir_build_pointer_pattern)]
|
#[diag(mir_build_pointer_pattern)]
|
||||||
|
#[note]
|
||||||
pub(crate) struct PointerPattern {
|
pub(crate) struct PointerPattern {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
|
#[label]
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
use rustc_abi::{FieldIdx, VariantIdx};
|
use rustc_abi::{FieldIdx, VariantIdx};
|
||||||
use rustc_apfloat::Float;
|
use rustc_apfloat::Float;
|
||||||
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
|
use rustc_errors::Diag;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::Obligation;
|
use rustc_infer::traits::Obligation;
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::thir::{FieldPat, Pat, PatKind};
|
use rustc_middle::thir::{FieldPat, Pat, PatKind};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeVisitor, ValTree};
|
||||||
use rustc_middle::{mir, span_bug};
|
use rustc_middle::{mir, span_bug};
|
||||||
use rustc_span::Span;
|
use rustc_span::def_id::DefId;
|
||||||
|
use rustc_span::{Span, sym};
|
||||||
use rustc_trait_selection::traits::ObligationCause;
|
use rustc_trait_selection::traits::ObligationCause;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
@ -35,7 +38,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
id: hir::HirId,
|
id: hir::HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Box<Pat<'tcx>> {
|
) -> Box<Pat<'tcx>> {
|
||||||
let mut convert = ConstToPat::new(self, id, span);
|
let mut convert = ConstToPat::new(self, id, span, c);
|
||||||
|
|
||||||
match c.kind() {
|
match c.kind() {
|
||||||
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
|
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
|
||||||
|
@ -49,21 +52,26 @@ struct ConstToPat<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
typing_env: ty::TypingEnv<'tcx>,
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
id: hir::HirId,
|
||||||
|
|
||||||
treat_byte_string_as_slice: bool,
|
treat_byte_string_as_slice: bool,
|
||||||
|
|
||||||
|
c: ty::Const<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ConstToPat<'tcx> {
|
impl<'tcx> ConstToPat<'tcx> {
|
||||||
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self {
|
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span, c: ty::Const<'tcx>) -> Self {
|
||||||
trace!(?pat_ctxt.typeck_results.hir_owner);
|
trace!(?pat_ctxt.typeck_results.hir_owner);
|
||||||
ConstToPat {
|
ConstToPat {
|
||||||
tcx: pat_ctxt.tcx,
|
tcx: pat_ctxt.tcx,
|
||||||
typing_env: pat_ctxt.typing_env,
|
typing_env: pat_ctxt.typing_env,
|
||||||
span,
|
span,
|
||||||
|
id,
|
||||||
treat_byte_string_as_slice: pat_ctxt
|
treat_byte_string_as_slice: pat_ctxt
|
||||||
.typeck_results
|
.typeck_results
|
||||||
.treat_byte_string_as_slice
|
.treat_byte_string_as_slice
|
||||||
.contains(&id.local_id),
|
.contains(&id.local_id),
|
||||||
|
c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +79,32 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
ty.is_structural_eq_shallow(self.tcx)
|
ty.is_structural_eq_shallow(self.tcx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||||
|
fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
|
||||||
|
if let ty::ConstKind::Unevaluated(uv) = self.c.kind() {
|
||||||
|
let def_kind = self.tcx.def_kind(uv.def);
|
||||||
|
if let hir::def::DefKind::AssocConst = def_kind
|
||||||
|
&& let Some(def_id) = uv.def.as_local()
|
||||||
|
{
|
||||||
|
// Include the container item in the output.
|
||||||
|
err.span_label(self.tcx.def_span(self.tcx.local_parent(def_id)), "");
|
||||||
|
}
|
||||||
|
if let hir::def::DefKind::Const | hir::def::DefKind::AssocConst = def_kind {
|
||||||
|
err.span_label(
|
||||||
|
self.tcx.def_span(uv.def),
|
||||||
|
crate::fluent_generated::mir_build_const_defined_here,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) })
|
||||||
|
}
|
||||||
|
|
||||||
fn unevaluated_to_pat(
|
fn unevaluated_to_pat(
|
||||||
&mut self,
|
&mut self,
|
||||||
uv: ty::UnevaluatedConst<'tcx>,
|
uv: ty::UnevaluatedConst<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> Box<Pat<'tcx>> {
|
) -> Box<Pat<'tcx>> {
|
||||||
trace!(self.treat_byte_string_as_slice);
|
trace!(self.treat_byte_string_as_slice);
|
||||||
let pat_from_kind = |kind| Box::new(Pat { span: self.span, ty, kind });
|
|
||||||
|
|
||||||
// It's not *technically* correct to be revealing opaque types here as borrowcheck has
|
// It's not *technically* correct to be revealing opaque types here as borrowcheck has
|
||||||
// not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
|
// not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
|
||||||
|
@ -96,32 +123,60 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
Ok(Ok(c)) => c,
|
Ok(Ok(c)) => c,
|
||||||
Err(ErrorHandled::Reported(_, _)) => {
|
Err(ErrorHandled::Reported(_, _)) => {
|
||||||
// Let's tell the use where this failing const occurs.
|
// Let's tell the use where this failing const occurs.
|
||||||
let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
|
let mut err =
|
||||||
return pat_from_kind(PatKind::Error(e));
|
self.tcx.dcx().create_err(CouldNotEvalConstPattern { span: self.span });
|
||||||
|
// We've emitted an error on the original const, it would be redundant to complain
|
||||||
|
// on its use as well.
|
||||||
|
if let ty::ConstKind::Unevaluated(uv) = self.c.kind()
|
||||||
|
&& let hir::def::DefKind::Const | hir::def::DefKind::AssocConst =
|
||||||
|
self.tcx.def_kind(uv.def)
|
||||||
|
{
|
||||||
|
err.downgrade_to_delayed_bug();
|
||||||
|
}
|
||||||
|
return self.mk_err(err, ty);
|
||||||
}
|
}
|
||||||
Err(ErrorHandled::TooGeneric(_)) => {
|
Err(ErrorHandled::TooGeneric(_)) => {
|
||||||
let e = self
|
let mut e = self
|
||||||
.tcx
|
.tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.emit_err(ConstPatternDependsOnGenericParameter { span: self.span });
|
.create_err(ConstPatternDependsOnGenericParameter { span: self.span });
|
||||||
return pat_from_kind(PatKind::Error(e));
|
for arg in uv.args {
|
||||||
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
|
&& let ty::Param(param_ty) = ty.kind()
|
||||||
|
{
|
||||||
|
let def_id = self.tcx.hir().enclosing_body_owner(self.id);
|
||||||
|
let generics = self.tcx.generics_of(def_id);
|
||||||
|
let param = generics.type_param(*param_ty, self.tcx);
|
||||||
|
let span = self.tcx.def_span(param.def_id);
|
||||||
|
e.span_label(span, "constant depends on this generic parameter");
|
||||||
|
if let Some(ident) = self.tcx.def_ident_span(def_id)
|
||||||
|
&& self.tcx.sess.source_map().is_multiline(ident.between(span))
|
||||||
|
{
|
||||||
|
// Display the `fn` name as well in the diagnostic, as the generic isn't
|
||||||
|
// in the same line and it could be confusing otherwise.
|
||||||
|
e.span_label(ident, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self.mk_err(e, ty);
|
||||||
}
|
}
|
||||||
Ok(Err(bad_ty)) => {
|
Ok(Err(bad_ty)) => {
|
||||||
// The pattern cannot be turned into a valtree.
|
// The pattern cannot be turned into a valtree.
|
||||||
let e = match bad_ty.kind() {
|
let e = match bad_ty.kind() {
|
||||||
ty::Adt(def, ..) => {
|
ty::Adt(def, ..) => {
|
||||||
assert!(def.is_union());
|
assert!(def.is_union());
|
||||||
self.tcx.dcx().emit_err(UnionPattern { span: self.span })
|
self.tcx.dcx().create_err(UnionPattern { span: self.span })
|
||||||
}
|
}
|
||||||
ty::FnPtr(..) | ty::RawPtr(..) => {
|
ty::FnPtr(..) | ty::RawPtr(..) => {
|
||||||
self.tcx.dcx().emit_err(PointerPattern { span: self.span })
|
self.tcx.dcx().create_err(PointerPattern { span: self.span })
|
||||||
}
|
}
|
||||||
_ => self
|
_ => self.tcx.dcx().create_err(InvalidPattern {
|
||||||
.tcx
|
span: self.span,
|
||||||
.dcx()
|
non_sm_ty: bad_ty,
|
||||||
.emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }),
|
prefix: bad_ty.prefix_string(self.tcx).to_string(),
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
return pat_from_kind(PatKind::Error(e));
|
return self.mk_err(e, ty);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,42 +185,16 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
|
|
||||||
if !inlined_const_as_pat.references_error() {
|
if !inlined_const_as_pat.references_error() {
|
||||||
// Always check for `PartialEq` if we had no other errors yet.
|
// Always check for `PartialEq` if we had no other errors yet.
|
||||||
if !self.type_has_partial_eq_impl(ty) {
|
if !type_has_partial_eq_impl(self.tcx, typing_env, ty).0 {
|
||||||
let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty };
|
let mut err = self.tcx.dcx().create_err(TypeNotPartialEq { span: self.span, ty });
|
||||||
let e = self.tcx.dcx().emit_err(err);
|
extend_type_not_partial_eq(self.tcx, typing_env, ty, &mut err);
|
||||||
return pat_from_kind(PatKind::Error(e));
|
return self.mk_err(err, ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inlined_const_as_pat
|
inlined_const_as_pat
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self), ret)]
|
|
||||||
fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
|
|
||||||
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
|
|
||||||
// double-check there even *is* a semantic `PartialEq` to dispatch to.
|
|
||||||
//
|
|
||||||
// (If there isn't, then we can safely issue a hard
|
|
||||||
// error, because that's never worked, due to compiler
|
|
||||||
// using `PartialEq::eq` in this scenario in the past.)
|
|
||||||
let partial_eq_trait_id =
|
|
||||||
self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
|
||||||
let partial_eq_obligation = Obligation::new(
|
|
||||||
self.tcx,
|
|
||||||
ObligationCause::dummy(),
|
|
||||||
param_env,
|
|
||||||
ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]),
|
|
||||||
);
|
|
||||||
|
|
||||||
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
|
|
||||||
// ignored. However that should be pretty much impossible since consts that do not depend on
|
|
||||||
// generics can only mention the `'static` lifetime, and how would one have a type that's
|
|
||||||
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
|
|
||||||
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
|
|
||||||
// can ensure that the type really implements `PartialEq`.
|
|
||||||
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn field_pats(
|
fn field_pats(
|
||||||
&self,
|
&self,
|
||||||
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
|
vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
|
||||||
|
@ -190,10 +219,25 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// Extremely important check for all ADTs! Make sure they opted-in to be used in
|
// Extremely important check for all ADTs! Make sure they opted-in to be used in
|
||||||
// patterns.
|
// patterns.
|
||||||
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
|
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
|
||||||
let err = TypeNotStructural { span, non_sm_ty: ty };
|
let (_impls_partial_eq, derived, structural, impl_def_id) =
|
||||||
let e = tcx.dcx().emit_err(err);
|
type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
|
||||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
let (manual_partialeq_impl_span, manual_partialeq_impl_note) =
|
||||||
PatKind::Error(e)
|
match (structural, impl_def_id) {
|
||||||
|
(true, _) => (None, false),
|
||||||
|
(_, Some(def_id)) if def_id.is_local() && !derived => {
|
||||||
|
(Some(tcx.def_span(def_id)), false)
|
||||||
|
}
|
||||||
|
_ => (None, true),
|
||||||
|
};
|
||||||
|
let ty_def_span = tcx.def_span(adt_def.did());
|
||||||
|
let err = TypeNotStructural {
|
||||||
|
span,
|
||||||
|
ty,
|
||||||
|
ty_def_span,
|
||||||
|
manual_partialeq_impl_span,
|
||||||
|
manual_partialeq_impl_note,
|
||||||
|
};
|
||||||
|
return self.mk_err(tcx.dcx().create_err(err), ty);
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, args) if adt_def.is_enum() => {
|
ty::Adt(adt_def, args) if adt_def.is_enum() => {
|
||||||
let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
|
let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
|
||||||
|
@ -207,7 +251,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
adt_def.variants()[variant_index]
|
adt_def.variants()[variant_index]
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| field.ty(self.tcx, args)),
|
.map(|field| field.ty(tcx, args)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -216,7 +260,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
|
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
|
||||||
PatKind::Leaf {
|
PatKind::Leaf {
|
||||||
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
|
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
|
||||||
def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)),
|
def.non_enum_variant().fields.iter().map(|field| field.ty(tcx, args)),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,10 +296,10 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// deref pattern.
|
// deref pattern.
|
||||||
_ => {
|
_ => {
|
||||||
if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
|
if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
|
||||||
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
|
return self.mk_err(
|
||||||
let e = tcx.dcx().emit_err(err);
|
tcx.dcx().create_err(UnsizedPattern { span, non_sm_ty: *pointee_ty }),
|
||||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
ty,
|
||||||
PatKind::Error(e)
|
);
|
||||||
} else {
|
} else {
|
||||||
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
|
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
|
||||||
// matching against references, you can only use byte string literals.
|
// matching against references, you can only use byte string literals.
|
||||||
|
@ -286,8 +330,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
if is_nan {
|
if is_nan {
|
||||||
// NaNs are not ever equal to anything so they make no sense as patterns.
|
// NaNs are not ever equal to anything so they make no sense as patterns.
|
||||||
// Also see <https://github.com/rust-lang/rfcs/pull/3535>.
|
// Also see <https://github.com/rust-lang/rfcs/pull/3535>.
|
||||||
let e = tcx.dcx().emit_err(NaNPattern { span });
|
return self.mk_err(tcx.dcx().create_err(NaNPattern { span }), ty);
|
||||||
PatKind::Error(e)
|
|
||||||
} else {
|
} else {
|
||||||
PatKind::Constant {
|
PatKind::Constant {
|
||||||
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
value: mir::Const::Ty(ty, ty::Const::new_value(tcx, cv, ty)),
|
||||||
|
@ -305,13 +348,153 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let err = InvalidPattern { span, non_sm_ty: ty };
|
let err = InvalidPattern {
|
||||||
let e = tcx.dcx().emit_err(err);
|
span,
|
||||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
non_sm_ty: ty,
|
||||||
PatKind::Error(e)
|
prefix: ty.prefix_string(tcx).to_string(),
|
||||||
|
};
|
||||||
|
return self.mk_err(tcx.dcx().create_err(err), ty);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Box::new(Pat { span, ty, kind })
|
Box::new(Pat { span, ty, kind })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given a type with type parameters, visit every ADT looking for types that need to
|
||||||
|
/// `#[derive(PartialEq)]` for it to be a structural type.
|
||||||
|
fn extend_type_not_partial_eq<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
err: &mut Diag<'_>,
|
||||||
|
) {
|
||||||
|
/// Collect all types that need to be `StructuralPartialEq`.
|
||||||
|
struct UsedParamsNeedInstantiationVisitor<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
|
/// The user has written `impl PartialEq for Ty` which means it's non-structual.
|
||||||
|
adts_with_manual_partialeq: FxHashSet<Span>,
|
||||||
|
/// The type has no `PartialEq` implementation, neither manual or derived.
|
||||||
|
adts_without_partialeq: FxHashSet<Span>,
|
||||||
|
/// The user has written `impl PartialEq for Ty` which means it's non-structual,
|
||||||
|
/// but we don't have a span to point at, so we'll just add them as a `note`.
|
||||||
|
manual: Vec<Ty<'tcx>>,
|
||||||
|
/// The type has no `PartialEq` implementation, neither manual or derived, but
|
||||||
|
/// we don't have a span to point at, so we'll just add them as a `note`.
|
||||||
|
without: Vec<Ty<'tcx>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
|
||||||
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
|
||||||
|
if let ty::Adt(def, _args) = ty.kind() {
|
||||||
|
let ty_def_id = def.did();
|
||||||
|
let ty_def_span = self.tcx.def_span(ty_def_id);
|
||||||
|
let (impls_partial_eq, derived, structural, impl_def_id) =
|
||||||
|
type_has_partial_eq_impl(self.tcx, self.typing_env, ty);
|
||||||
|
match (impls_partial_eq, derived, structural, impl_def_id) {
|
||||||
|
(_, _, true, _) => {}
|
||||||
|
(true, false, _, Some(def_id)) if def_id.is_local() => {
|
||||||
|
self.adts_with_manual_partialeq.insert(self.tcx.def_span(def_id));
|
||||||
|
}
|
||||||
|
(true, false, _, _) if ty_def_id.is_local() => {
|
||||||
|
self.adts_with_manual_partialeq.insert(ty_def_span);
|
||||||
|
}
|
||||||
|
(false, _, _, _) if ty_def_id.is_local() => {
|
||||||
|
self.adts_without_partialeq.insert(ty_def_span);
|
||||||
|
}
|
||||||
|
(true, false, _, _) => {
|
||||||
|
self.manual.push(ty);
|
||||||
|
}
|
||||||
|
(false, _, _, _) => {
|
||||||
|
self.without.push(ty);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
use rustc_middle::ty::TypeSuperVisitable;
|
||||||
|
ty.super_visit_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut v = UsedParamsNeedInstantiationVisitor {
|
||||||
|
tcx,
|
||||||
|
typing_env,
|
||||||
|
adts_with_manual_partialeq: FxHashSet::default(),
|
||||||
|
adts_without_partialeq: FxHashSet::default(),
|
||||||
|
manual: vec![],
|
||||||
|
without: vec![],
|
||||||
|
};
|
||||||
|
v.visit_ty(ty);
|
||||||
|
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
|
||||||
|
for span in v.adts_with_manual_partialeq {
|
||||||
|
err.span_note(span, "the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details");
|
||||||
|
}
|
||||||
|
#[allow(rustc::potential_query_instability)] // Span labels will be sorted by the rendering
|
||||||
|
for span in v.adts_without_partialeq {
|
||||||
|
err.span_label(
|
||||||
|
span,
|
||||||
|
"must be annotated with `#[derive(PartialEq)]` to be usable in patterns",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for ty in v.manual {
|
||||||
|
err.note(format!(
|
||||||
|
"`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
for ty in v.without {
|
||||||
|
err.note(format!(
|
||||||
|
"`{ty}` must be annotated with `#[derive(PartialEq)]` to be usable in patterns"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "trace", skip(tcx), ret)]
|
||||||
|
fn type_has_partial_eq_impl<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
) -> (
|
||||||
|
/* has impl */ bool,
|
||||||
|
/* is derived */ bool,
|
||||||
|
/* structural partial eq */ bool,
|
||||||
|
/* non-blanket impl */ Option<DefId>,
|
||||||
|
) {
|
||||||
|
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||||
|
// double-check there even *is* a semantic `PartialEq` to dispatch to.
|
||||||
|
//
|
||||||
|
// (If there isn't, then we can safely issue a hard
|
||||||
|
// error, because that's never worked, due to compiler
|
||||||
|
// using `PartialEq::eq` in this scenario in the past.)
|
||||||
|
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, None);
|
||||||
|
let structural_partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::StructuralPeq, None);
|
||||||
|
|
||||||
|
let partial_eq_obligation = Obligation::new(
|
||||||
|
tcx,
|
||||||
|
ObligationCause::dummy(),
|
||||||
|
param_env,
|
||||||
|
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut automatically_derived = false;
|
||||||
|
let mut structural_peq = false;
|
||||||
|
let mut impl_def_id = None;
|
||||||
|
for def_id in tcx.non_blanket_impls_for_ty(partial_eq_trait_id, ty) {
|
||||||
|
automatically_derived = tcx.has_attr(def_id, sym::automatically_derived);
|
||||||
|
impl_def_id = Some(def_id);
|
||||||
|
}
|
||||||
|
for _ in tcx.non_blanket_impls_for_ty(structural_partial_eq_trait_id, ty) {
|
||||||
|
structural_peq = true;
|
||||||
|
}
|
||||||
|
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
|
||||||
|
// ignored. However that should be pretty much impossible since consts that do not depend on
|
||||||
|
// generics can only mention the `'static` lifetime, and how would one have a type that's
|
||||||
|
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
|
||||||
|
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
|
||||||
|
// can ensure that the type really implements `PartialEq`.
|
||||||
|
(
|
||||||
|
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation),
|
||||||
|
automatically_derived,
|
||||||
|
structural_peq,
|
||||||
|
impl_def_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -528,11 +528,17 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
|
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
|
||||||
_ => {
|
_ => {
|
||||||
let e = match res {
|
let e = match res {
|
||||||
Res::Def(DefKind::ConstParam, _) => {
|
Res::Def(DefKind::ConstParam, def_id) => {
|
||||||
self.tcx.dcx().emit_err(ConstParamInPattern { span })
|
self.tcx.dcx().emit_err(ConstParamInPattern {
|
||||||
|
span,
|
||||||
|
const_span: self.tcx().def_span(def_id),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Static { .. }, _) => {
|
Res::Def(DefKind::Static { .. }, def_id) => {
|
||||||
self.tcx.dcx().emit_err(StaticInPattern { span })
|
self.tcx.dcx().emit_err(StaticInPattern {
|
||||||
|
span,
|
||||||
|
static_span: self.tcx().def_span(def_id),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_ => self.tcx.dcx().emit_err(NonConstPath { span }),
|
_ => self.tcx.dcx().emit_err(NonConstPath { span }),
|
||||||
};
|
};
|
||||||
|
|
|
@ -747,8 +747,8 @@ fn build_call_shim<'tcx>(
|
||||||
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
|
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(eddyb) avoid having this snippet both here and in
|
// FIXME: Avoid having to adjust the signature both here and in
|
||||||
// `Instance::fn_sig` (introduce `InstanceKind::fn_sig`?).
|
// `fn_sig_for_fn_abi`.
|
||||||
if let ty::InstanceKind::VTableShim(..) = instance {
|
if let ty::InstanceKind::VTableShim(..) = instance {
|
||||||
// Modify fn(self, ...) to fn(self: *mut Self, ...)
|
// Modify fn(self, ...) to fn(self: *mut Self, ...)
|
||||||
let mut inputs_and_output = sig.inputs_and_output.to_vec();
|
let mut inputs_and_output = sig.inputs_and_output.to_vec();
|
||||||
|
|
|
@ -343,6 +343,9 @@ parse_incorrect_semicolon =
|
||||||
.suggestion = remove this semicolon
|
.suggestion = remove this semicolon
|
||||||
.help = {$name} declarations are not followed by a semicolon
|
.help = {$name} declarations are not followed by a semicolon
|
||||||
|
|
||||||
|
parse_incorrect_type_on_self = type not allowed for shorthand `self` parameter
|
||||||
|
.suggestion = move the modifiers on `self` to the type
|
||||||
|
|
||||||
parse_incorrect_use_of_await = incorrect use of `await`
|
parse_incorrect_use_of_await = incorrect use of `await`
|
||||||
.parentheses_suggestion = `await` is not a method call, remove the parentheses
|
.parentheses_suggestion = `await` is not a method call, remove the parentheses
|
||||||
|
|
||||||
|
|
|
@ -3409,3 +3409,22 @@ pub(crate) struct PolarityAndModifiers {
|
||||||
pub polarity: &'static str,
|
pub polarity: &'static str,
|
||||||
pub modifiers_concatenated: String,
|
pub modifiers_concatenated: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(parse_incorrect_type_on_self)]
|
||||||
|
pub(crate) struct IncorrectTypeOnSelf {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub move_self_modifier: MoveSelfModifier,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
|
||||||
|
pub(crate) struct MoveSelfModifier {
|
||||||
|
#[suggestion_part(code = "")]
|
||||||
|
pub removal_span: Span,
|
||||||
|
#[suggestion_part(code = "{modifier}")]
|
||||||
|
pub insertion_span: Span,
|
||||||
|
pub modifier: String,
|
||||||
|
}
|
||||||
|
|
|
@ -2941,6 +2941,32 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
Ok((eself, eself_ident, eself_hi))
|
Ok((eself, eself_ident, eself_hi))
|
||||||
};
|
};
|
||||||
|
let expect_self_ident_not_typed =
|
||||||
|
|this: &mut Self, modifier: &SelfKind, modifier_span: Span| {
|
||||||
|
let eself_ident = expect_self_ident(this);
|
||||||
|
|
||||||
|
// Recover `: Type` after a qualified self
|
||||||
|
if this.may_recover() && this.eat_noexpect(&token::Colon) {
|
||||||
|
let snap = this.create_snapshot_for_diagnostic();
|
||||||
|
match this.parse_ty() {
|
||||||
|
Ok(ty) => {
|
||||||
|
this.dcx().emit_err(errors::IncorrectTypeOnSelf {
|
||||||
|
span: ty.span,
|
||||||
|
move_self_modifier: errors::MoveSelfModifier {
|
||||||
|
removal_span: modifier_span,
|
||||||
|
insertion_span: ty.span.shrink_to_lo(),
|
||||||
|
modifier: modifier.to_ref_suggestion(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(diag) => {
|
||||||
|
diag.cancel();
|
||||||
|
this.restore_snapshot(snap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eself_ident
|
||||||
|
};
|
||||||
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
|
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
|
||||||
let recover_self_ptr = |this: &mut Self| {
|
let recover_self_ptr = |this: &mut Self| {
|
||||||
this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
|
this.dcx().emit_err(errors::SelfArgumentPointer { span: this.token.span });
|
||||||
|
@ -2978,7 +3004,9 @@ impl<'a> Parser<'a> {
|
||||||
// `¬_self`
|
// `¬_self`
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
(eself, expect_self_ident(self), self.prev_token.span)
|
let hi = self.token.span;
|
||||||
|
let self_ident = expect_self_ident_not_typed(self, &eself, eself_lo.until(hi));
|
||||||
|
(eself, self_ident, hi)
|
||||||
}
|
}
|
||||||
// `*self`
|
// `*self`
|
||||||
token::BinOp(token::Star) if is_isolated_self(self, 1) => {
|
token::BinOp(token::Star) if is_isolated_self(self, 1) => {
|
||||||
|
|
|
@ -3838,6 +3838,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
&& self.predicate_must_hold_modulo_regions(&Obligation::misc(
|
&& self.predicate_must_hold_modulo_regions(&Obligation::misc(
|
||||||
tcx, expr.span, body_id, param_env, pred,
|
tcx, expr.span, body_id, param_env, pred,
|
||||||
))
|
))
|
||||||
|
&& expr.span.hi() != rcvr.span.hi()
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
expr.span.with_lo(rcvr.span.hi()),
|
expr.span.with_lo(rcvr.span.hi()),
|
||||||
|
@ -4115,6 +4116,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
// the expected is a projection that we need to resolve.
|
// the expected is a projection that we need to resolve.
|
||||||
// && let Some(tail_ty) = typeck_results.expr_ty_opt(expr)
|
// && let Some(tail_ty) = typeck_results.expr_ty_opt(expr)
|
||||||
&& expected_found.found.is_unit()
|
&& expected_found.found.is_unit()
|
||||||
|
// FIXME: this happens with macro calls. Need to figure out why the stmt
|
||||||
|
// `println!();` doesn't include the `;` in its `Span`. (#133845)
|
||||||
|
// We filter these out to avoid ICEs with debug assertions on caused by
|
||||||
|
// empty suggestions.
|
||||||
|
&& expr.span.hi() != stmt.span.hi()
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
expr.span.shrink_to_hi().with_hi(stmt.span.hi()),
|
expr.span.shrink_to_hi().with_hi(stmt.span.hi()),
|
||||||
|
|
|
@ -16,9 +16,7 @@ use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk};
|
use rustc_infer::infer::{DefineOpaqueTypes, HigherRankedType, InferOk};
|
||||||
use rustc_infer::traits::ObligationCauseCode;
|
use rustc_infer::traits::ObligationCauseCode;
|
||||||
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
|
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{self, GenericArgsRef, ToPolyTraitRef, Ty, TyCtxt, Upcast};
|
||||||
self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, Ty, TyCtxt, Upcast,
|
|
||||||
};
|
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
@ -638,60 +636,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// higher-ranked things.
|
// higher-ranked things.
|
||||||
// Prevent, e.g., `dyn Iterator<Item = str>`.
|
// Prevent, e.g., `dyn Iterator<Item = str>`.
|
||||||
for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
|
for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
|
||||||
let arg_bound = if defs.is_empty() {
|
|
||||||
bound.instantiate(tcx, trait_predicate.trait_ref.args)
|
|
||||||
} else {
|
|
||||||
let mut args = smallvec::SmallVec::with_capacity(defs.count());
|
|
||||||
args.extend(trait_predicate.trait_ref.args.iter());
|
|
||||||
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
|
|
||||||
smallvec::SmallVec::with_capacity(
|
|
||||||
bound.skip_binder().kind().bound_vars().len() + defs.count(),
|
|
||||||
);
|
|
||||||
bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter());
|
|
||||||
GenericArgs::fill_single(&mut args, defs, &mut |param, _| match param.kind {
|
|
||||||
GenericParamDefKind::Type { .. } => {
|
|
||||||
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
|
|
||||||
let bound_var = ty::BoundVariableKind::Ty(kind);
|
|
||||||
bound_vars.push(bound_var);
|
|
||||||
Ty::new_bound(tcx, ty::INNERMOST, ty::BoundTy {
|
|
||||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
|
||||||
kind,
|
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
GenericParamDefKind::Lifetime => {
|
|
||||||
let kind = ty::BoundRegionKind::Named(param.def_id, param.name);
|
|
||||||
let bound_var = ty::BoundVariableKind::Region(kind);
|
|
||||||
bound_vars.push(bound_var);
|
|
||||||
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion {
|
|
||||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
|
||||||
kind,
|
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
GenericParamDefKind::Const { .. } => {
|
|
||||||
let bound_var = ty::BoundVariableKind::Const;
|
|
||||||
bound_vars.push(bound_var);
|
|
||||||
ty::Const::new_bound(
|
|
||||||
tcx,
|
|
||||||
ty::INNERMOST,
|
|
||||||
ty::BoundVar::from_usize(bound_vars.len() - 1),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
|
|
||||||
let assoc_ty_args = tcx.mk_args(&args);
|
|
||||||
let bound =
|
|
||||||
bound.map_bound(|b| b.kind().skip_binder()).instantiate(tcx, assoc_ty_args);
|
|
||||||
ty::Binder::bind_with_vars(bound, bound_vars).upcast(tcx)
|
|
||||||
};
|
|
||||||
let normalized_bound = normalize_with_depth_to(
|
let normalized_bound = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
obligation.cause.clone(),
|
obligation.cause.clone(),
|
||||||
obligation.recursion_depth + 1,
|
obligation.recursion_depth + 1,
|
||||||
arg_bound,
|
bound.instantiate(tcx, trait_predicate.trait_ref.args),
|
||||||
&mut nested,
|
&mut nested,
|
||||||
);
|
);
|
||||||
nested.push(obligation.with(tcx, normalized_bound));
|
nested.push(obligation.with(tcx, normalized_bound));
|
||||||
|
|
|
@ -31,20 +31,20 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
typing_env: ty::TypingEnv<'tcx>,
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
) -> ty::PolyFnSig<'tcx> {
|
) -> ty::FnSig<'tcx> {
|
||||||
if let InstanceKind::ThreadLocalShim(..) = instance.def {
|
if let InstanceKind::ThreadLocalShim(..) = instance.def {
|
||||||
return ty::Binder::dummy(tcx.mk_fn_sig(
|
return tcx.mk_fn_sig(
|
||||||
[],
|
[],
|
||||||
tcx.thread_local_ptr_ty(instance.def_id()),
|
tcx.thread_local_ptr_ty(instance.def_id()),
|
||||||
false,
|
false,
|
||||||
hir::Safety::Safe,
|
hir::Safety::Safe,
|
||||||
rustc_abi::ExternAbi::Unadjusted,
|
rustc_abi::ExternAbi::Unadjusted,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ty = instance.ty(tcx, typing_env);
|
let ty = instance.ty(tcx, typing_env);
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::FnDef(..) => {
|
ty::FnDef(def_id, args) => {
|
||||||
// HACK(davidtwco,eddyb): This is a workaround for polymorphization considering
|
// HACK(davidtwco,eddyb): This is a workaround for polymorphization considering
|
||||||
// parameters unused if they show up in the signature, but not in the `mir::Body`
|
// parameters unused if they show up in the signature, but not in the `mir::Body`
|
||||||
// (i.e. due to being inside a projection that got normalized, see
|
// (i.e. due to being inside a projection that got normalized, see
|
||||||
|
@ -52,9 +52,8 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
// track of a polymorphization `ParamEnv` to allow normalizing later.
|
// track of a polymorphization `ParamEnv` to allow normalizing later.
|
||||||
//
|
//
|
||||||
// We normalize the `fn_sig` again after instantiating at a later point.
|
// We normalize the `fn_sig` again after instantiating at a later point.
|
||||||
let mut sig = match *ty.kind() {
|
let mut sig = tcx.instantiate_bound_regions_with_erased(
|
||||||
ty::FnDef(def_id, args) => tcx
|
tcx.fn_sig(def_id)
|
||||||
.fn_sig(def_id)
|
|
||||||
.map_bound(|fn_sig| {
|
.map_bound(|fn_sig| {
|
||||||
tcx.normalize_erasing_regions(
|
tcx.normalize_erasing_regions(
|
||||||
ty::TypingEnv::non_body_analysis(tcx, def_id),
|
ty::TypingEnv::non_body_analysis(tcx, def_id),
|
||||||
|
@ -62,62 +61,36 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.instantiate(tcx, args),
|
.instantiate(tcx, args),
|
||||||
_ => unreachable!(),
|
);
|
||||||
};
|
|
||||||
|
|
||||||
if let ty::InstanceKind::VTableShim(..) = instance.def {
|
if let ty::InstanceKind::VTableShim(..) = instance.def {
|
||||||
// Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
|
let mut inputs_and_output = sig.inputs_and_output.to_vec();
|
||||||
sig = sig.map_bound(|mut sig| {
|
inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]);
|
||||||
let mut inputs_and_output = sig.inputs_and_output.to_vec();
|
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
|
||||||
inputs_and_output[0] = Ty::new_mut_ptr(tcx, inputs_and_output[0]);
|
|
||||||
sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
|
|
||||||
sig
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sig
|
sig
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, args) => {
|
ty::Closure(def_id, args) => {
|
||||||
let sig = args.as_closure().sig();
|
let sig = tcx.instantiate_bound_regions_with_erased(args.as_closure().sig());
|
||||||
|
|
||||||
let bound_vars =
|
|
||||||
tcx.mk_bound_variable_kinds_from_iter(sig.bound_vars().iter().chain(iter::once(
|
|
||||||
ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
|
|
||||||
)));
|
|
||||||
let br = ty::BoundRegion {
|
|
||||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
|
||||||
kind: ty::BoundRegionKind::ClosureEnv,
|
|
||||||
};
|
|
||||||
let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
|
|
||||||
let env_ty = tcx.closure_env_ty(
|
let env_ty = tcx.closure_env_ty(
|
||||||
Ty::new_closure(tcx, def_id, args),
|
Ty::new_closure(tcx, def_id, args),
|
||||||
args.as_closure().kind(),
|
args.as_closure().kind(),
|
||||||
env_region,
|
tcx.lifetimes.re_erased,
|
||||||
);
|
);
|
||||||
|
|
||||||
let sig = sig.skip_binder();
|
tcx.mk_fn_sig(
|
||||||
ty::Binder::bind_with_vars(
|
iter::once(env_ty).chain(sig.inputs().iter().cloned()),
|
||||||
tcx.mk_fn_sig(
|
sig.output(),
|
||||||
iter::once(env_ty).chain(sig.inputs().iter().cloned()),
|
sig.c_variadic,
|
||||||
sig.output(),
|
sig.safety,
|
||||||
sig.c_variadic,
|
sig.abi,
|
||||||
sig.safety,
|
|
||||||
sig.abi,
|
|
||||||
),
|
|
||||||
bound_vars,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::CoroutineClosure(def_id, args) => {
|
ty::CoroutineClosure(def_id, args) => {
|
||||||
let coroutine_ty = Ty::new_coroutine_closure(tcx, def_id, args);
|
let coroutine_ty = Ty::new_coroutine_closure(tcx, def_id, args);
|
||||||
let sig = args.as_coroutine_closure().coroutine_closure_sig();
|
let sig = args.as_coroutine_closure().coroutine_closure_sig();
|
||||||
let bound_vars =
|
|
||||||
tcx.mk_bound_variable_kinds_from_iter(sig.bound_vars().iter().chain(iter::once(
|
|
||||||
ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
|
|
||||||
)));
|
|
||||||
let br = ty::BoundRegion {
|
|
||||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
|
||||||
kind: ty::BoundRegionKind::ClosureEnv,
|
|
||||||
};
|
|
||||||
let env_region = ty::Region::new_bound(tcx, ty::INNERMOST, br);
|
|
||||||
// When this `CoroutineClosure` comes from a `ConstructCoroutineInClosureShim`,
|
// When this `CoroutineClosure` comes from a `ConstructCoroutineInClosureShim`,
|
||||||
// make sure we respect the `target_kind` in that shim.
|
// make sure we respect the `target_kind` in that shim.
|
||||||
// FIXME(async_closures): This shouldn't be needed, and we should be populating
|
// FIXME(async_closures): This shouldn't be needed, and we should be populating
|
||||||
|
@ -138,42 +111,32 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
coroutine_ty
|
coroutine_ty
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tcx.closure_env_ty(coroutine_ty, coroutine_kind, env_region)
|
tcx.closure_env_ty(coroutine_ty, coroutine_kind, tcx.lifetimes.re_erased)
|
||||||
};
|
};
|
||||||
|
|
||||||
let sig = sig.skip_binder();
|
let sig = tcx.instantiate_bound_regions_with_erased(sig);
|
||||||
ty::Binder::bind_with_vars(
|
|
||||||
tcx.mk_fn_sig(
|
tcx.mk_fn_sig(
|
||||||
iter::once(env_ty).chain([sig.tupled_inputs_ty]),
|
iter::once(env_ty).chain([sig.tupled_inputs_ty]),
|
||||||
sig.to_coroutine_given_kind_and_upvars(
|
sig.to_coroutine_given_kind_and_upvars(
|
||||||
tcx,
|
tcx,
|
||||||
args.as_coroutine_closure().parent_args(),
|
args.as_coroutine_closure().parent_args(),
|
||||||
tcx.coroutine_for_closure(def_id),
|
tcx.coroutine_for_closure(def_id),
|
||||||
coroutine_kind,
|
coroutine_kind,
|
||||||
env_region,
|
tcx.lifetimes.re_erased,
|
||||||
args.as_coroutine_closure().tupled_upvars_ty(),
|
args.as_coroutine_closure().tupled_upvars_ty(),
|
||||||
args.as_coroutine_closure().coroutine_captures_by_ref_ty(),
|
args.as_coroutine_closure().coroutine_captures_by_ref_ty(),
|
||||||
),
|
|
||||||
sig.c_variadic,
|
|
||||||
sig.safety,
|
|
||||||
sig.abi,
|
|
||||||
),
|
),
|
||||||
bound_vars,
|
sig.c_variadic,
|
||||||
|
sig.safety,
|
||||||
|
sig.abi,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::Coroutine(did, args) => {
|
ty::Coroutine(did, args) => {
|
||||||
let coroutine_kind = tcx.coroutine_kind(did).unwrap();
|
let coroutine_kind = tcx.coroutine_kind(did).unwrap();
|
||||||
let sig = args.as_coroutine().sig();
|
let sig = args.as_coroutine().sig();
|
||||||
|
|
||||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(iter::once(
|
let env_ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, ty);
|
||||||
ty::BoundVariableKind::Region(ty::BoundRegionKind::ClosureEnv),
|
|
||||||
));
|
|
||||||
let br = ty::BoundRegion {
|
|
||||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
|
||||||
kind: ty::BoundRegionKind::ClosureEnv,
|
|
||||||
};
|
|
||||||
|
|
||||||
let env_ty = Ty::new_mut_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), ty);
|
|
||||||
|
|
||||||
let pin_did = tcx.require_lang_item(LangItem::Pin, None);
|
let pin_did = tcx.require_lang_item(LangItem::Pin, None);
|
||||||
let pin_adt_ref = tcx.adt_def(pin_did);
|
let pin_adt_ref = tcx.adt_def(pin_did);
|
||||||
|
@ -268,7 +231,7 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let fn_sig = if let Some(resume_ty) = resume_ty {
|
if let Some(resume_ty) = resume_ty {
|
||||||
tcx.mk_fn_sig(
|
tcx.mk_fn_sig(
|
||||||
[env_ty, resume_ty],
|
[env_ty, resume_ty],
|
||||||
ret_ty,
|
ret_ty,
|
||||||
|
@ -285,8 +248,7 @@ fn fn_sig_for_fn_abi<'tcx>(
|
||||||
hir::Safety::Safe,
|
hir::Safety::Safe,
|
||||||
rustc_abi::ExternAbi::Rust,
|
rustc_abi::ExternAbi::Rust,
|
||||||
)
|
)
|
||||||
};
|
}
|
||||||
ty::Binder::bind_with_vars(fn_sig, bound_vars)
|
|
||||||
}
|
}
|
||||||
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
|
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
|
||||||
}
|
}
|
||||||
|
@ -335,8 +297,16 @@ fn fn_abi_of_fn_ptr<'tcx>(
|
||||||
query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
query: ty::PseudoCanonicalInput<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>,
|
||||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||||
let ty::PseudoCanonicalInput { typing_env, value: (sig, extra_args) } = query;
|
let ty::PseudoCanonicalInput { typing_env, value: (sig, extra_args) } = query;
|
||||||
|
|
||||||
let cx = LayoutCx::new(tcx, typing_env);
|
let cx = LayoutCx::new(tcx, typing_env);
|
||||||
fn_abi_new_uncached(&cx, sig, extra_args, None, None, false)
|
fn_abi_new_uncached(
|
||||||
|
&cx,
|
||||||
|
tcx.instantiate_bound_regions_with_erased(sig),
|
||||||
|
extra_args,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_abi_of_instance<'tcx>(
|
fn fn_abi_of_instance<'tcx>(
|
||||||
|
@ -567,7 +537,7 @@ fn fn_abi_sanity_check<'tcx>(
|
||||||
#[tracing::instrument(level = "debug", skip(cx, caller_location, fn_def_id, force_thin_self_ptr))]
|
#[tracing::instrument(level = "debug", skip(cx, caller_location, fn_def_id, force_thin_self_ptr))]
|
||||||
fn fn_abi_new_uncached<'tcx>(
|
fn fn_abi_new_uncached<'tcx>(
|
||||||
cx: &LayoutCx<'tcx>,
|
cx: &LayoutCx<'tcx>,
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::FnSig<'tcx>,
|
||||||
extra_args: &[Ty<'tcx>],
|
extra_args: &[Ty<'tcx>],
|
||||||
caller_location: Option<Ty<'tcx>>,
|
caller_location: Option<Ty<'tcx>>,
|
||||||
fn_def_id: Option<DefId>,
|
fn_def_id: Option<DefId>,
|
||||||
|
@ -575,7 +545,7 @@ fn fn_abi_new_uncached<'tcx>(
|
||||||
force_thin_self_ptr: bool,
|
force_thin_self_ptr: bool,
|
||||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
let sig = tcx.normalize_erasing_late_bound_regions(cx.typing_env, sig);
|
let sig = tcx.normalize_erasing_regions(cx.typing_env, sig);
|
||||||
|
|
||||||
let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic);
|
let conv = conv_from_spec_abi(cx.tcx(), sig.abi, sig.c_variadic);
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ pub mod net;
|
||||||
pub mod option;
|
pub mod option;
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
pub mod panicking;
|
pub mod panicking;
|
||||||
#[unstable(feature = "core_pattern_types", issue = "123646")]
|
#[unstable(feature = "pattern_type_macro", issue = "123646")]
|
||||||
pub mod pat;
|
pub mod pat;
|
||||||
pub mod pin;
|
pub mod pin;
|
||||||
#[unstable(feature = "random", issue = "130703")]
|
#[unstable(feature = "random", issue = "130703")]
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro(pattern_type)]
|
#[rustc_builtin_macro(pattern_type)]
|
||||||
#[unstable(feature = "core_pattern_type", issue = "123646")]
|
#[unstable(feature = "pattern_type_macro", issue = "123646")]
|
||||||
macro_rules! pattern_type {
|
macro_rules! pattern_type {
|
||||||
($($arg:tt)*) => {
|
($($arg:tt)*) => {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
|
|
|
@ -304,6 +304,7 @@ fn test_const_nonnull_new() {
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)] // printf may not be available on other platforms
|
#[cfg(unix)] // printf may not be available on other platforms
|
||||||
#[allow(deprecated)] // For SipHasher
|
#[allow(deprecated)] // For SipHasher
|
||||||
|
#[cfg_attr(not(bootstrap), allow(unpredictable_function_pointer_comparisons))]
|
||||||
pub fn test_variadic_fnptr() {
|
pub fn test_variadic_fnptr() {
|
||||||
use core::ffi;
|
use core::ffi;
|
||||||
use core::hash::{Hash, SipHasher};
|
use core::hash::{Hash, SipHasher};
|
||||||
|
|
|
@ -589,7 +589,7 @@ pub mod net;
|
||||||
pub mod num;
|
pub mod num;
|
||||||
pub mod os;
|
pub mod os;
|
||||||
pub mod panic;
|
pub mod panic;
|
||||||
#[unstable(feature = "core_pattern_types", issue = "123646")]
|
#[unstable(feature = "pattern_type_macro", issue = "123646")]
|
||||||
pub mod pat;
|
pub mod pat;
|
||||||
pub mod path;
|
pub mod path;
|
||||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||||
|
|
|
@ -48,9 +48,9 @@ fn main() {
|
||||||
err => {
|
err => {
|
||||||
drop(err);
|
drop(err);
|
||||||
if let Ok(pid) = pid {
|
if let Ok(pid) = pid {
|
||||||
eprintln!("WARNING: build directory locked by process {pid}, waiting for lock");
|
println!("WARNING: build directory locked by process {pid}, waiting for lock");
|
||||||
} else {
|
} else {
|
||||||
eprintln!("WARNING: build directory locked, waiting for lock");
|
println!("WARNING: build directory locked, waiting for lock");
|
||||||
}
|
}
|
||||||
let mut lock = t!(build_lock.write());
|
let mut lock = t!(build_lock.write());
|
||||||
t!(lock.write(process::id().to_string().as_ref()));
|
t!(lock.write(process::id().to_string().as_ref()));
|
||||||
|
@ -70,13 +70,13 @@ fn main() {
|
||||||
// changelog warning, not the `x.py setup` message.
|
// changelog warning, not the `x.py setup` message.
|
||||||
let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
|
let suggest_setup = config.config.is_none() && !matches!(config.cmd, Subcommand::Setup { .. });
|
||||||
if suggest_setup {
|
if suggest_setup {
|
||||||
eprintln!("WARNING: you have not made a `config.toml`");
|
println!("WARNING: you have not made a `config.toml`");
|
||||||
eprintln!(
|
println!(
|
||||||
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
|
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
|
||||||
`cp config.example.toml config.toml`"
|
`cp config.example.toml config.toml`"
|
||||||
);
|
);
|
||||||
} else if let Some(suggestion) = &changelog_suggestion {
|
} else if let Some(suggestion) = &changelog_suggestion {
|
||||||
eprintln!("{suggestion}");
|
println!("{suggestion}");
|
||||||
}
|
}
|
||||||
|
|
||||||
let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
|
let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
|
||||||
|
@ -86,13 +86,13 @@ fn main() {
|
||||||
Build::new(config).build();
|
Build::new(config).build();
|
||||||
|
|
||||||
if suggest_setup {
|
if suggest_setup {
|
||||||
eprintln!("WARNING: you have not made a `config.toml`");
|
println!("WARNING: you have not made a `config.toml`");
|
||||||
eprintln!(
|
println!(
|
||||||
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
|
"HELP: consider running `./x.py setup` or copying `config.example.toml` by running \
|
||||||
`cp config.example.toml config.toml`"
|
`cp config.example.toml config.toml`"
|
||||||
);
|
);
|
||||||
} else if let Some(suggestion) = &changelog_suggestion {
|
} else if let Some(suggestion) = &changelog_suggestion {
|
||||||
eprintln!("{suggestion}");
|
println!("{suggestion}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give a warning if the pre-commit script is in pre-commit and not pre-push.
|
// Give a warning if the pre-commit script is in pre-commit and not pre-push.
|
||||||
|
@ -102,14 +102,14 @@ fn main() {
|
||||||
if fs::read_to_string(pre_commit).is_ok_and(|contents| {
|
if fs::read_to_string(pre_commit).is_ok_and(|contents| {
|
||||||
contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
|
contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
|
||||||
}) {
|
}) {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \
|
"WARNING: You have the pre-push script installed to .git/hooks/pre-commit. \
|
||||||
Consider moving it to .git/hooks/pre-push instead, which runs less often."
|
Consider moving it to .git/hooks/pre-push instead, which runs less often."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if suggest_setup || changelog_suggestion.is_some() {
|
if suggest_setup || changelog_suggestion.is_some() {
|
||||||
eprintln!("NOTE: this message was printed twice to make it more likely to be seen");
|
println!("NOTE: this message was printed twice to make it more likely to be seen");
|
||||||
}
|
}
|
||||||
|
|
||||||
if dump_bootstrap_shims {
|
if dump_bootstrap_shims {
|
||||||
|
|
|
@ -306,7 +306,7 @@ fn main() {
|
||||||
// should run on success, after this block.
|
// should run on success, after this block.
|
||||||
}
|
}
|
||||||
if verbose > 0 {
|
if verbose > 0 {
|
||||||
eprintln!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
|
println!("\nDid not run successfully: {status}\n{cmd:?}\n-------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut on_fail) = on_fail {
|
if let Some(mut on_fail) = on_fail {
|
||||||
|
|
|
@ -287,7 +287,7 @@ impl Step for CodegenBackend {
|
||||||
fn run(self, builder: &Builder<'_>) {
|
fn run(self, builder: &Builder<'_>) {
|
||||||
// FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
|
// FIXME: remove once https://github.com/rust-lang/rust/issues/112393 is resolved
|
||||||
if builder.build.config.vendor && self.backend == "gcc" {
|
if builder.build.config.vendor && self.backend == "gcc" {
|
||||||
eprintln!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
|
println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1611,7 +1611,7 @@ impl Step for Sysroot {
|
||||||
let sysroot = sysroot_dir(compiler.stage);
|
let sysroot = sysroot_dir(compiler.stage);
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.verbose(|| eprintln!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
|
.verbose(|| println!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
|
||||||
let _ = fs::remove_dir_all(&sysroot);
|
let _ = fs::remove_dir_all(&sysroot);
|
||||||
t!(fs::create_dir_all(&sysroot));
|
t!(fs::create_dir_all(&sysroot));
|
||||||
|
|
||||||
|
@ -1681,7 +1681,7 @@ impl Step for Sysroot {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
|
if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
|
||||||
builder.verbose_than(1, || eprintln!("ignoring {}", path.display()));
|
builder.verbose_than(1, || println!("ignoring {}", path.display()));
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
@ -2240,7 +2240,7 @@ pub fn stream_cargo(
|
||||||
cargo.arg(arg);
|
cargo.arg(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.verbose(|| eprintln!("running: {cargo:?}"));
|
builder.verbose(|| println!("running: {cargo:?}"));
|
||||||
|
|
||||||
if builder.config.dry_run() {
|
if builder.config.dry_run() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -2261,12 +2261,12 @@ pub fn stream_cargo(
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
if builder.config.json_output {
|
if builder.config.json_output {
|
||||||
// Forward JSON to stdout.
|
// Forward JSON to stdout.
|
||||||
eprintln!("{line}");
|
println!("{line}");
|
||||||
}
|
}
|
||||||
cb(msg)
|
cb(msg)
|
||||||
}
|
}
|
||||||
// If this was informational, just print it out and continue
|
// If this was informational, just print it out and continue
|
||||||
Err(_) => eprintln!("{line}"),
|
Err(_) => println!("{line}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2080,7 +2080,7 @@ fn maybe_install_llvm(
|
||||||
{
|
{
|
||||||
let mut cmd = command(llvm_config);
|
let mut cmd = command(llvm_config);
|
||||||
cmd.arg("--libfiles");
|
cmd.arg("--libfiles");
|
||||||
builder.verbose(|| eprintln!("running {cmd:?}"));
|
builder.verbose(|| println!("running {cmd:?}"));
|
||||||
let files = cmd.run_capture_stdout(builder).stdout();
|
let files = cmd.run_capture_stdout(builder).stdout();
|
||||||
let build_llvm_out = &builder.llvm_out(builder.config.build);
|
let build_llvm_out = &builder.llvm_out(builder.config.build);
|
||||||
let target_llvm_out = &builder.llvm_out(target);
|
let target_llvm_out = &builder.llvm_out(target);
|
||||||
|
|
|
@ -107,10 +107,10 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
|
||||||
if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() };
|
if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() };
|
||||||
if len <= 10 {
|
if len <= 10 {
|
||||||
for path in paths {
|
for path in paths {
|
||||||
eprintln!("fmt: {verb} {adjective}file {path}");
|
println!("fmt: {verb} {adjective}file {path}");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eprintln!("fmt: {verb} {len} {adjective}files");
|
println!("fmt: {verb} {len} {adjective}files");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
|
||||||
match get_modified_rs_files(build) {
|
match get_modified_rs_files(build) {
|
||||||
Ok(Some(files)) => {
|
Ok(Some(files)) => {
|
||||||
if files.is_empty() {
|
if files.is_empty() {
|
||||||
eprintln!("fmt info: No modified files detected for formatting.");
|
println!("fmt info: No modified files detected for formatting.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ impl Step for Profile {
|
||||||
t!(fs::remove_file(path));
|
t!(fs::remove_file(path));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Exiting.");
|
println!("Exiting.");
|
||||||
crate::exit!(1);
|
crate::exit!(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,15 +184,15 @@ pub fn setup(config: &Config, profile: Profile) {
|
||||||
Profile::Dist => &["dist", "build"],
|
Profile::Dist => &["dist", "build"],
|
||||||
};
|
};
|
||||||
|
|
||||||
eprintln!();
|
println!();
|
||||||
|
|
||||||
eprintln!("To get started, try one of the following commands:");
|
println!("To get started, try one of the following commands:");
|
||||||
for cmd in suggestions {
|
for cmd in suggestions {
|
||||||
eprintln!("- `x.py {cmd}`");
|
println!("- `x.py {cmd}`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if profile != Profile::Dist {
|
if profile != Profile::Dist {
|
||||||
eprintln!(
|
println!(
|
||||||
"For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
|
"For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
|
||||||
t!(fs::write(path, settings));
|
t!(fs::write(path, settings));
|
||||||
|
|
||||||
let include_path = profile.include_path(&config.src);
|
let include_path = profile.include_path(&config.src);
|
||||||
eprintln!("`x.py` will now use the configuration at {}", include_path.display());
|
println!("`x.py` will now use the configuration at {}", include_path.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a toolchain link for stage1 using `rustup`
|
/// Creates a toolchain link for stage1 using `rustup`
|
||||||
|
@ -256,7 +256,7 @@ impl Step for Link {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rustup_installed(builder) {
|
if !rustup_installed(builder) {
|
||||||
eprintln!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking.");
|
println!("WARNING: `rustup` is not installed; Skipping `stage1` toolchain linking.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ fn attempt_toolchain_link(builder: &Builder<'_>, stage_path: &str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if try_link_toolchain(builder, stage_path) {
|
if try_link_toolchain(builder, stage_path) {
|
||||||
eprintln!(
|
println!(
|
||||||
"Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
|
"Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -321,14 +321,14 @@ fn toolchain_is_linked(builder: &Builder<'_>) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// The toolchain has already been linked.
|
// The toolchain has already been linked.
|
||||||
eprintln!(
|
println!(
|
||||||
"`stage1` toolchain already linked; not attempting to link `stage1` toolchain"
|
"`stage1` toolchain already linked; not attempting to link `stage1` toolchain"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// In this case, we don't know if the `stage1` toolchain has been linked;
|
// In this case, we don't know if the `stage1` toolchain has been linked;
|
||||||
// but `rustup` failed, so let's not go any further.
|
// but `rustup` failed, so let's not go any further.
|
||||||
eprintln!(
|
println!(
|
||||||
"`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain"
|
"`rustup` failed to list current toolchains; not attempting to link `stage1` toolchain"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -389,9 +389,9 @@ pub fn interactive_path() -> io::Result<Profile> {
|
||||||
input.parse()
|
input.parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("Welcome to the Rust project! What do you want to do with x.py?");
|
println!("Welcome to the Rust project! What do you want to do with x.py?");
|
||||||
for ((letter, _), profile) in abbrev_all() {
|
for ((letter, _), profile) in abbrev_all() {
|
||||||
eprintln!("{}) {}: {}", letter, profile, profile.purpose());
|
println!("{}) {}: {}", letter, profile, profile.purpose());
|
||||||
}
|
}
|
||||||
let template = loop {
|
let template = loop {
|
||||||
print!(
|
print!(
|
||||||
|
@ -488,7 +488,7 @@ fn install_git_hook_maybe(builder: &Builder<'_>, config: &Config) -> io::Result<
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!(
|
println!(
|
||||||
"\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
|
"\nRust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
|
||||||
If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before
|
If you'd like, x.py can install a git hook for you that will automatically run `test tidy` before
|
||||||
pushing your code to ensure your code is up to par. If you decide later that this behavior is
|
pushing your code to ensure your code is up to par. If you decide later that this behavior is
|
||||||
|
@ -496,7 +496,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
|
||||||
);
|
);
|
||||||
|
|
||||||
if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) {
|
if prompt_user("Would you like to install the git hook?: [y/N]")? != Some(PromptResult::Yes) {
|
||||||
eprintln!("Ok, skipping installation!");
|
println!("Ok, skipping installation!");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if !hooks_dir.exists() {
|
if !hooks_dir.exists() {
|
||||||
|
@ -513,7 +513,7 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
|
||||||
);
|
);
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
Ok(_) => eprintln!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
|
Ok(_) => println!("Linked `src/etc/pre-push.sh` to `.git/hooks/pre-push`"),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -654,7 +654,7 @@ impl Step for Editor {
|
||||||
if let Some(editor_kind) = editor_kind {
|
if let Some(editor_kind) = editor_kind {
|
||||||
while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
|
while !t!(create_editor_settings_maybe(config, editor_kind.clone())) {}
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Ok, skipping editor setup!");
|
println!("Ok, skipping editor setup!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => eprintln!("Could not determine the editor: {e}"),
|
Err(e) => eprintln!("Could not determine the editor: {e}"),
|
||||||
|
@ -687,7 +687,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
|
||||||
mismatched_settings = Some(false);
|
mismatched_settings = Some(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eprintln!(
|
println!(
|
||||||
"\nx.py can automatically install the recommended `{settings_filename}` file for rustc development"
|
"\nx.py can automatically install the recommended `{settings_filename}` file for rustc development"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
|
||||||
Some(PromptResult::Yes) => true,
|
Some(PromptResult::Yes) => true,
|
||||||
Some(PromptResult::Print) => false,
|
Some(PromptResult::Print) => false,
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Ok, skipping settings!");
|
println!("Ok, skipping settings!");
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -733,9 +733,9 @@ fn create_editor_settings_maybe(config: &Config, editor: EditorKind) -> io::Resu
|
||||||
_ => "Created",
|
_ => "Created",
|
||||||
};
|
};
|
||||||
fs::write(&settings_path, editor.settings_template())?;
|
fs::write(&settings_path, editor.settings_template())?;
|
||||||
eprintln!("{verb} `{}`", settings_filename);
|
println!("{verb} `{}`", settings_filename);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("\n{}", editor.settings_template());
|
println!("\n{}", editor.settings_template());
|
||||||
}
|
}
|
||||||
Ok(should_create)
|
Ok(should_create)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) {
|
||||||
build.build();
|
build.build();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
eprintln!("HELP: consider using the `--run` flag to automatically run suggested tests");
|
println!("HELP: consider using the `--run` flag to automatically run suggested tests");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -471,11 +471,11 @@ impl Miri {
|
||||||
// We re-use the `cargo` from above.
|
// We re-use the `cargo` from above.
|
||||||
cargo.arg("--print-sysroot");
|
cargo.arg("--print-sysroot");
|
||||||
|
|
||||||
builder.verbose(|| eprintln!("running: {cargo:?}"));
|
builder.verbose(|| println!("running: {cargo:?}"));
|
||||||
let stdout = cargo.run_capture_stdout(builder).stdout();
|
let stdout = cargo.run_capture_stdout(builder).stdout();
|
||||||
// Output is "<sysroot>\n".
|
// Output is "<sysroot>\n".
|
||||||
let sysroot = stdout.trim_end();
|
let sysroot = stdout.trim_end();
|
||||||
builder.verbose(|| eprintln!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
|
builder.verbose(|| println!("`cargo miri setup --print-sysroot` said: {sysroot:?}"));
|
||||||
PathBuf::from(sysroot)
|
PathBuf::from(sysroot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2478,7 +2478,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.verbose(|| eprintln!("doc tests for: {}", markdown.display()));
|
builder.verbose(|| println!("doc tests for: {}", markdown.display()));
|
||||||
let mut cmd = builder.rustdoc_cmd(compiler);
|
let mut cmd = builder.rustdoc_cmd(compiler);
|
||||||
builder.add_rust_test_threads(&mut cmd);
|
builder.add_rust_test_threads(&mut cmd);
|
||||||
// allow for unstable options such as new editions
|
// allow for unstable options such as new editions
|
||||||
|
|
|
@ -523,7 +523,7 @@ impl Builder<'_> {
|
||||||
|
|
||||||
let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
|
let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
|
||||||
if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
|
if self.is_verbose() && !matches!(self.config.dry_run, DryRun::SelfCheck) {
|
||||||
eprintln!("using sysroot {sysroot_str}");
|
println!("using sysroot {sysroot_str}");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rustflags = Rustflags::new(target);
|
let mut rustflags = Rustflags::new(target);
|
||||||
|
|
|
@ -392,14 +392,14 @@ impl StepDescription {
|
||||||
fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
|
fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
|
||||||
if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) {
|
if builder.config.skip.iter().any(|e| pathset.has(e, builder.kind)) {
|
||||||
if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
|
if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
|
||||||
eprintln!("Skipping {pathset:?} because it is excluded");
|
println!("Skipping {pathset:?} because it is excluded");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
|
if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
|
||||||
builder.verbose(|| {
|
builder.verbose(|| {
|
||||||
eprintln!(
|
println!(
|
||||||
"{:?} not skipped for {:?} -- not in {:?}",
|
"{:?} not skipped for {:?} -- not in {:?}",
|
||||||
pathset, self.name, builder.config.skip
|
pathset, self.name, builder.config.skip
|
||||||
)
|
)
|
||||||
|
@ -1437,11 +1437,11 @@ impl<'a> Builder<'a> {
|
||||||
panic!("{}", out);
|
panic!("{}", out);
|
||||||
}
|
}
|
||||||
if let Some(out) = self.cache.get(&step) {
|
if let Some(out) = self.cache.get(&step) {
|
||||||
self.verbose_than(1, || eprintln!("{}c {:?}", " ".repeat(stack.len()), step));
|
self.verbose_than(1, || println!("{}c {:?}", " ".repeat(stack.len()), step));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
self.verbose_than(1, || eprintln!("{}> {:?}", " ".repeat(stack.len()), step));
|
self.verbose_than(1, || println!("{}> {:?}", " ".repeat(stack.len()), step));
|
||||||
stack.push(Box::new(step.clone()));
|
stack.push(Box::new(step.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,7 +1462,7 @@ impl<'a> Builder<'a> {
|
||||||
let step_string = format!("{step:?}");
|
let step_string = format!("{step:?}");
|
||||||
let brace_index = step_string.find('{').unwrap_or(0);
|
let brace_index = step_string.find('{').unwrap_or(0);
|
||||||
let type_string = type_name::<S>();
|
let type_string = type_name::<S>();
|
||||||
eprintln!(
|
println!(
|
||||||
"[TIMING] {} {} -- {}.{:03}",
|
"[TIMING] {} {} -- {}.{:03}",
|
||||||
&type_string.strip_prefix("bootstrap::").unwrap_or(type_string),
|
&type_string.strip_prefix("bootstrap::").unwrap_or(type_string),
|
||||||
&step_string[brace_index..],
|
&step_string[brace_index..],
|
||||||
|
@ -1479,9 +1479,7 @@ impl<'a> Builder<'a> {
|
||||||
let cur_step = stack.pop().expect("step stack empty");
|
let cur_step = stack.pop().expect("step stack empty");
|
||||||
assert_eq!(cur_step.downcast_ref(), Some(&step));
|
assert_eq!(cur_step.downcast_ref(), Some(&step));
|
||||||
}
|
}
|
||||||
self.verbose_than(1, || {
|
self.verbose_than(1, || println!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step));
|
||||||
eprintln!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step)
|
|
||||||
});
|
|
||||||
self.cache.put(step, out.clone());
|
self.cache.put(step, out.clone());
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
|
@ -1293,7 +1293,7 @@ impl Config {
|
||||||
.map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
|
.map(|change_id| change_id.inner.map(crate::find_recent_config_change_ids))
|
||||||
{
|
{
|
||||||
if !changes.is_empty() {
|
if !changes.is_empty() {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: There have been changes to x.py since you last updated:\n{}",
|
"WARNING: There have been changes to x.py since you last updated:\n{}",
|
||||||
crate::human_readable_changes(&changes)
|
crate::human_readable_changes(&changes)
|
||||||
);
|
);
|
||||||
|
@ -1559,7 +1559,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cargo_clippy.is_some() && rustc.is_none() {
|
if cargo_clippy.is_some() && rustc.is_none() {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict."
|
"WARNING: Using `build.cargo-clippy` without `build.rustc` usually fails due to toolchain conflict."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1841,7 +1841,7 @@ impl Config {
|
||||||
|
|
||||||
// FIXME: Remove this option at the end of 2024.
|
// FIXME: Remove this option at the end of 2024.
|
||||||
if parallel_compiler.is_some() {
|
if parallel_compiler.is_some() {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default"
|
"WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1873,7 +1873,7 @@ impl Config {
|
||||||
if available_backends.contains(&backend) {
|
if available_backends.contains(&backend) {
|
||||||
panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
|
panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
|
||||||
} else {
|
} else {
|
||||||
eprintln!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
|
println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \
|
||||||
Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
|
Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
|
||||||
In this case, it would be referred to as '{backend}'.");
|
In this case, it would be referred to as '{backend}'.");
|
||||||
}
|
}
|
||||||
|
@ -1902,7 +1902,7 @@ impl Config {
|
||||||
// tests may fail due to using a different channel than the one used by the compiler during tests.
|
// tests may fail due to using a different channel than the one used by the compiler during tests.
|
||||||
if let Some(commit) = &config.download_rustc_commit {
|
if let Some(commit) = &config.download_rustc_commit {
|
||||||
if is_user_configured_rust_channel {
|
if is_user_configured_rust_channel {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel."
|
"WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1992,10 +1992,10 @@ impl Config {
|
||||||
|
|
||||||
if config.llvm_from_ci {
|
if config.llvm_from_ci {
|
||||||
let warn = |option: &str| {
|
let warn = |option: &str| {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
|
"WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
|
||||||
);
|
);
|
||||||
eprintln!(
|
println!(
|
||||||
"HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
|
"HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2014,12 +2014,12 @@ impl Config {
|
||||||
// if they've chosen a different value.
|
// if they've chosen a different value.
|
||||||
|
|
||||||
if libzstd.is_some() {
|
if libzstd.is_some() {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
|
"WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
|
||||||
like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
|
like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
|
||||||
artifacts builder config."
|
artifacts builder config."
|
||||||
);
|
);
|
||||||
eprintln!(
|
println!(
|
||||||
"HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
|
"HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2088,7 +2088,7 @@ impl Config {
|
||||||
if available_backends.contains(&backend) {
|
if available_backends.contains(&backend) {
|
||||||
panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
|
panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'.");
|
||||||
} else {
|
} else {
|
||||||
eprintln!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
|
println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \
|
||||||
Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
|
Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
|
||||||
In this case, it would be referred to as '{backend}'.");
|
In this case, it would be referred to as '{backend}'.");
|
||||||
}
|
}
|
||||||
|
@ -2304,7 +2304,7 @@ impl Config {
|
||||||
if self.dry_run() {
|
if self.dry_run() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
self.verbose(|| eprintln!("running: {cmd:?}"));
|
self.verbose(|| println!("running: {cmd:?}"));
|
||||||
build_helper::util::try_run(cmd, self.is_verbose())
|
build_helper::util::try_run(cmd, self.is_verbose())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2479,7 +2479,7 @@ impl Config {
|
||||||
// This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error
|
// This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error
|
||||||
// to not break CI. For non-CI environments, we should return an error.
|
// to not break CI. For non-CI environments, we should return an error.
|
||||||
if CiEnv::is_ci() {
|
if CiEnv::is_ci() {
|
||||||
eprintln!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
|
println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
|
||||||
return None;
|
return None;
|
||||||
} else {
|
} else {
|
||||||
panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used.");
|
panic!("ERROR: LLVM submodule has changes, `download-rustc` can't be used.");
|
||||||
|
@ -2490,8 +2490,8 @@ impl Config {
|
||||||
let ci_config_toml = match self.get_builder_toml("ci-rustc") {
|
let ci_config_toml = match self.get_builder_toml("ci-rustc") {
|
||||||
Ok(ci_config_toml) => ci_config_toml,
|
Ok(ci_config_toml) => ci_config_toml,
|
||||||
Err(e) if e.to_string().contains("unknown field") => {
|
Err(e) if e.to_string().contains("unknown field") => {
|
||||||
eprintln!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled.");
|
println!("WARNING: CI rustc has some fields that are no longer supported in bootstrap; download-rustc will be disabled.");
|
||||||
eprintln!("HELP: Consider rebasing to a newer commit if available.");
|
println!("HELP: Consider rebasing to a newer commit if available.");
|
||||||
return None;
|
return None;
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -2516,7 +2516,7 @@ impl Config {
|
||||||
.is_some_and(|s| s == "1" || s == "true");
|
.is_some_and(|s| s == "1" || s == "true");
|
||||||
|
|
||||||
if disable_ci_rustc_if_incompatible && res.is_err() {
|
if disable_ci_rustc_if_incompatible && res.is_err() {
|
||||||
eprintln!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
|
println!("WARNING: download-rustc is disabled with `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` env.");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2701,7 +2701,7 @@ impl Config {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("Updating submodule {relative_path}");
|
println!("Updating submodule {relative_path}");
|
||||||
self.check_run(
|
self.check_run(
|
||||||
helpers::git(Some(&self.src))
|
helpers::git(Some(&self.src))
|
||||||
.run_always()
|
.run_always()
|
||||||
|
@ -2824,7 +2824,7 @@ impl Config {
|
||||||
Some(StringOrBool::Bool(true)) => false,
|
Some(StringOrBool::Bool(true)) => false,
|
||||||
Some(StringOrBool::String(s)) if s == "if-unchanged" => {
|
Some(StringOrBool::String(s)) if s == "if-unchanged" => {
|
||||||
if !self.rust_info.is_managed_git_subrepository() {
|
if !self.rust_info.is_managed_git_subrepository() {
|
||||||
eprintln!(
|
println!(
|
||||||
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
|
"ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
|
||||||
);
|
);
|
||||||
crate::exit!(1);
|
crate::exit!(1);
|
||||||
|
@ -2857,10 +2857,10 @@ impl Config {
|
||||||
if if_unchanged {
|
if if_unchanged {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
eprintln!("ERROR: could not find commit hash for downloading rustc");
|
println!("ERROR: could not find commit hash for downloading rustc");
|
||||||
eprintln!("HELP: maybe your repository history is too shallow?");
|
println!("HELP: maybe your repository history is too shallow?");
|
||||||
eprintln!("HELP: consider setting `rust.download-rustc=false` in config.toml");
|
println!("HELP: consider setting `rust.download-rustc=false` in config.toml");
|
||||||
eprintln!("HELP: or fetch enough history to include one upstream commit");
|
println!("HELP: or fetch enough history to include one upstream commit");
|
||||||
crate::exit!(1);
|
crate::exit!(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2899,7 +2899,7 @@ impl Config {
|
||||||
let if_unchanged = || {
|
let if_unchanged = || {
|
||||||
if self.rust_info.is_from_tarball() {
|
if self.rust_info.is_from_tarball() {
|
||||||
// Git is needed for running "if-unchanged" logic.
|
// Git is needed for running "if-unchanged" logic.
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
|
"WARNING: 'if-unchanged' has no effect on tarball sources; ignoring `download-ci-llvm`."
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2948,10 +2948,10 @@ impl Config {
|
||||||
// Only commits merged by bors will have CI artifacts.
|
// Only commits merged by bors will have CI artifacts.
|
||||||
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
|
let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap();
|
||||||
if commit.is_empty() {
|
if commit.is_empty() {
|
||||||
eprintln!("error: could not find commit hash for downloading components from CI");
|
println!("error: could not find commit hash for downloading components from CI");
|
||||||
eprintln!("help: maybe your repository history is too shallow?");
|
println!("help: maybe your repository history is too shallow?");
|
||||||
eprintln!("help: consider disabling `{option_name}`");
|
println!("help: consider disabling `{option_name}`");
|
||||||
eprintln!("help: or fetch enough history to include one upstream commit");
|
println!("help: or fetch enough history to include one upstream commit");
|
||||||
crate::exit!(1);
|
crate::exit!(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2963,14 +2963,14 @@ impl Config {
|
||||||
if has_changes {
|
if has_changes {
|
||||||
if if_unchanged {
|
if if_unchanged {
|
||||||
if self.is_verbose() {
|
if self.is_verbose() {
|
||||||
eprintln!(
|
println!(
|
||||||
"warning: saw changes to one of {modified_paths:?} since {commit}; \
|
"warning: saw changes to one of {modified_paths:?} since {commit}; \
|
||||||
ignoring `{option_name}`"
|
ignoring `{option_name}`"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
eprintln!(
|
println!(
|
||||||
"warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}"
|
"warning: `{option_name}` is enabled, but there are changes to one of {modified_paths:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3007,7 +3007,7 @@ pub(crate) fn check_incompatible_options_for_ci_llvm(
|
||||||
($current:expr, $expected:expr) => {
|
($current:expr, $expected:expr) => {
|
||||||
if let Some(current) = &$current {
|
if let Some(current) = &$current {
|
||||||
if Some(current) != $expected.as_ref() {
|
if Some(current) != $expected.as_ref() {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
|
"WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
|
||||||
Current value: {:?}, Expected value(s): {}{:?}",
|
Current value: {:?}, Expected value(s): {}{:?}",
|
||||||
stringify!($expected).replace("_", "-"),
|
stringify!($expected).replace("_", "-"),
|
||||||
|
@ -3112,7 +3112,7 @@ fn check_incompatible_options_for_ci_rustc(
|
||||||
($current:expr, $expected:expr, $config_section:expr) => {
|
($current:expr, $expected:expr, $config_section:expr) => {
|
||||||
if let Some(current) = &$current {
|
if let Some(current) = &$current {
|
||||||
if Some(current) != $expected.as_ref() {
|
if Some(current) != $expected.as_ref() {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: `{}` has no effect with `rust.download-rustc`. \
|
"WARNING: `{}` has no effect with `rust.download-rustc`. \
|
||||||
Current value: {:?}, Expected value(s): {}{:?}",
|
Current value: {:?}, Expected value(s): {}{:?}",
|
||||||
format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
|
format!("{}.{}", $config_section, stringify!($expected).replace("_", "-")),
|
||||||
|
|
|
@ -196,12 +196,12 @@ impl Flags {
|
||||||
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
|
if let Ok(HelpVerboseOnly { help: true, verbose: 1.., cmd: subcommand }) =
|
||||||
HelpVerboseOnly::try_parse_from(normalize_args(args))
|
HelpVerboseOnly::try_parse_from(normalize_args(args))
|
||||||
{
|
{
|
||||||
eprintln!("NOTE: updating submodules before printing available paths");
|
println!("NOTE: updating submodules before printing available paths");
|
||||||
let config = Config::parse(Self::parse(&[String::from("build")]));
|
let config = Config::parse(Self::parse(&[String::from("build")]));
|
||||||
let build = Build::new(config);
|
let build = Build::new(config);
|
||||||
let paths = Builder::get_help(&build, subcommand);
|
let paths = Builder::get_help(&build, subcommand);
|
||||||
if let Some(s) = paths {
|
if let Some(s) = paths {
|
||||||
eprintln!("{s}");
|
println!("{s}");
|
||||||
} else {
|
} else {
|
||||||
panic!("No paths available for subcommand `{}`", subcommand.as_str());
|
panic!("No paths available for subcommand `{}`", subcommand.as_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl Config {
|
||||||
if self.dry_run() && !cmd.run_always {
|
if self.dry_run() && !cmd.run_always {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
self.verbose(|| eprintln!("running: {cmd:?}"));
|
self.verbose(|| println!("running: {cmd:?}"));
|
||||||
check_run(cmd, self.is_verbose())
|
check_run(cmd, self.is_verbose())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ impl Config {
|
||||||
/// Please see <https://nixos.org/patchelf.html> for more information
|
/// Please see <https://nixos.org/patchelf.html> for more information
|
||||||
fn fix_bin_or_dylib(&self, fname: &Path) {
|
fn fix_bin_or_dylib(&self, fname: &Path) {
|
||||||
assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true));
|
assert_eq!(SHOULD_FIX_BINS_AND_DYLIBS.get(), Some(&true));
|
||||||
eprintln!("attempting to patch {}", fname.display());
|
println!("attempting to patch {}", fname.display());
|
||||||
|
|
||||||
// Only build `.nix-deps` once.
|
// Only build `.nix-deps` once.
|
||||||
static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
static NIX_DEPS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||||
|
@ -206,7 +206,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
|
fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) {
|
||||||
self.verbose(|| eprintln!("download {url}"));
|
self.verbose(|| println!("download {url}"));
|
||||||
// Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
|
// Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
|
||||||
let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
|
let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
|
||||||
// While bootstrap itself only supports http and https downloads, downstream forks might
|
// While bootstrap itself only supports http and https downloads, downstream forks might
|
||||||
|
@ -226,7 +226,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
|
fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
|
||||||
eprintln!("downloading {url}");
|
println!("downloading {url}");
|
||||||
// Try curl. If that fails and we are on windows, fallback to PowerShell.
|
// Try curl. If that fails and we are on windows, fallback to PowerShell.
|
||||||
// options should be kept in sync with
|
// options should be kept in sync with
|
||||||
// src/bootstrap/src/core/download.rs
|
// src/bootstrap/src/core/download.rs
|
||||||
|
@ -341,7 +341,7 @@ impl Config {
|
||||||
short_path = short_path.strip_prefix(pattern).unwrap_or(short_path);
|
short_path = short_path.strip_prefix(pattern).unwrap_or(short_path);
|
||||||
let dst_path = dst.join(short_path);
|
let dst_path = dst.join(short_path);
|
||||||
self.verbose(|| {
|
self.verbose(|| {
|
||||||
eprintln!("extracting {} to {}", original_path.display(), dst.display())
|
println!("extracting {} to {}", original_path.display(), dst.display())
|
||||||
});
|
});
|
||||||
if !t!(member.unpack_in(dst)) {
|
if !t!(member.unpack_in(dst)) {
|
||||||
panic!("path traversal attack ??");
|
panic!("path traversal attack ??");
|
||||||
|
@ -365,7 +365,7 @@ impl Config {
|
||||||
pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
|
pub(crate) fn verify(&self, path: &Path, expected: &str) -> bool {
|
||||||
use sha2::Digest;
|
use sha2::Digest;
|
||||||
|
|
||||||
self.verbose(|| eprintln!("verifying {}", path.display()));
|
self.verbose(|| println!("verifying {}", path.display()));
|
||||||
|
|
||||||
if self.dry_run() {
|
if self.dry_run() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -391,7 +391,7 @@ impl Config {
|
||||||
let verified = checksum == expected;
|
let verified = checksum == expected;
|
||||||
|
|
||||||
if !verified {
|
if !verified {
|
||||||
eprintln!(
|
println!(
|
||||||
"invalid checksum: \n\
|
"invalid checksum: \n\
|
||||||
found: {checksum}\n\
|
found: {checksum}\n\
|
||||||
expected: {expected}",
|
expected: {expected}",
|
||||||
|
@ -421,7 +421,7 @@ enum DownloadSource {
|
||||||
/// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions.
|
/// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions.
|
||||||
impl Config {
|
impl Config {
|
||||||
pub(crate) fn download_clippy(&self) -> PathBuf {
|
pub(crate) fn download_clippy(&self) -> PathBuf {
|
||||||
self.verbose(|| eprintln!("downloading stage0 clippy artifacts"));
|
self.verbose(|| println!("downloading stage0 clippy artifacts"));
|
||||||
|
|
||||||
let date = &self.stage0_metadata.compiler.date;
|
let date = &self.stage0_metadata.compiler.date;
|
||||||
let version = &self.stage0_metadata.compiler.version;
|
let version = &self.stage0_metadata.compiler.version;
|
||||||
|
@ -518,7 +518,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn download_ci_rustc(&self, commit: &str) {
|
pub(crate) fn download_ci_rustc(&self, commit: &str) {
|
||||||
self.verbose(|| eprintln!("using downloaded stage2 artifacts from CI (commit {commit})"));
|
self.verbose(|| println!("using downloaded stage2 artifacts from CI (commit {commit})"));
|
||||||
|
|
||||||
let version = self.artifact_version_part(commit);
|
let version = self.artifact_version_part(commit);
|
||||||
// download-rustc doesn't need its own cargo, it can just use beta's. But it does need the
|
// download-rustc doesn't need its own cargo, it can just use beta's. But it does need the
|
||||||
|
@ -539,7 +539,7 @@ impl Config {
|
||||||
|
|
||||||
#[cfg(not(feature = "bootstrap-self-test"))]
|
#[cfg(not(feature = "bootstrap-self-test"))]
|
||||||
pub(crate) fn download_beta_toolchain(&self) {
|
pub(crate) fn download_beta_toolchain(&self) {
|
||||||
self.verbose(|| eprintln!("downloading stage0 beta artifacts"));
|
self.verbose(|| println!("downloading stage0 beta artifacts"));
|
||||||
|
|
||||||
let date = &self.stage0_metadata.compiler.date;
|
let date = &self.stage0_metadata.compiler.date;
|
||||||
let version = &self.stage0_metadata.compiler.version;
|
let version = &self.stage0_metadata.compiler.version;
|
||||||
|
@ -677,7 +677,7 @@ impl Config {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
self.verbose(|| {
|
self.verbose(|| {
|
||||||
eprintln!(
|
println!(
|
||||||
"ignoring cached file {} due to failed verification",
|
"ignoring cached file {} due to failed verification",
|
||||||
tarball.display()
|
tarball.display()
|
||||||
)
|
)
|
||||||
|
@ -776,10 +776,10 @@ download-rustc = false
|
||||||
t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml));
|
t!(check_incompatible_options_for_ci_llvm(current_config_toml, ci_config_toml));
|
||||||
}
|
}
|
||||||
Err(e) if e.to_string().contains("unknown field") => {
|
Err(e) if e.to_string().contains("unknown field") => {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled."
|
"WARNING: CI LLVM has some fields that are no longer supported in bootstrap; download-ci-llvm will be disabled."
|
||||||
);
|
);
|
||||||
eprintln!("HELP: Consider rebasing to a newer commit if available.");
|
println!("HELP: Consider rebasing to a newer commit if available.");
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}");
|
eprintln!("ERROR: Failed to parse CI LLVM config.toml: {e}");
|
||||||
|
|
|
@ -237,11 +237,11 @@ than building it.
|
||||||
stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
|
stage0_supported_target_list.intersection(&missing_targets_hashset).collect();
|
||||||
|
|
||||||
if !duplicated_targets.is_empty() {
|
if !duplicated_targets.is_empty() {
|
||||||
eprintln!(
|
println!(
|
||||||
"Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
|
"Following targets supported from the stage0 compiler, please remove them from STAGE0_MISSING_TARGETS list."
|
||||||
);
|
);
|
||||||
for duplicated_target in duplicated_targets {
|
for duplicated_target in duplicated_targets {
|
||||||
eprintln!(" {duplicated_target}");
|
println!(" {duplicated_target}");
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,11 +406,11 @@ impl Build {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.trim();
|
.trim();
|
||||||
if local_release.split('.').take(2).eq(version.split('.').take(2)) {
|
if local_release.split('.').take(2).eq(version.split('.').take(2)) {
|
||||||
build.verbose(|| eprintln!("auto-detected local-rebuild {local_release}"));
|
build.verbose(|| println!("auto-detected local-rebuild {local_release}"));
|
||||||
build.local_rebuild = true;
|
build.local_rebuild = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
build.verbose(|| eprintln!("finding compilers"));
|
build.verbose(|| println!("finding compilers"));
|
||||||
utils::cc_detect::find(&build);
|
utils::cc_detect::find(&build);
|
||||||
// When running `setup`, the profile is about to change, so any requirements we have now may
|
// When running `setup`, the profile is about to change, so any requirements we have now may
|
||||||
// be different on the next invocation. Don't check for them until the next time x.py is
|
// be different on the next invocation. Don't check for them until the next time x.py is
|
||||||
|
@ -418,7 +418,7 @@ impl Build {
|
||||||
//
|
//
|
||||||
// Similarly, for `setup` we don't actually need submodules or cargo metadata.
|
// Similarly, for `setup` we don't actually need submodules or cargo metadata.
|
||||||
if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
|
if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
|
||||||
build.verbose(|| eprintln!("running sanity check"));
|
build.verbose(|| println!("running sanity check"));
|
||||||
crate::core::sanity::check(&mut build);
|
crate::core::sanity::check(&mut build);
|
||||||
|
|
||||||
// Make sure we update these before gathering metadata so we don't get an error about missing
|
// Make sure we update these before gathering metadata so we don't get an error about missing
|
||||||
|
@ -436,7 +436,7 @@ impl Build {
|
||||||
// Now, update all existing submodules.
|
// Now, update all existing submodules.
|
||||||
build.update_existing_submodules();
|
build.update_existing_submodules();
|
||||||
|
|
||||||
build.verbose(|| eprintln!("learning about cargo"));
|
build.verbose(|| println!("learning about cargo"));
|
||||||
crate::core::metadata::build(&mut build);
|
crate::core::metadata::build(&mut build);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ impl Build {
|
||||||
let stamp = dir.join(".stamp");
|
let stamp = dir.join(".stamp");
|
||||||
let mut cleared = false;
|
let mut cleared = false;
|
||||||
if mtime(&stamp) < mtime(input) {
|
if mtime(&stamp) < mtime(input) {
|
||||||
self.verbose(|| eprintln!("Dirty - {}", dir.display()));
|
self.verbose(|| println!("Dirty - {}", dir.display()));
|
||||||
let _ = fs::remove_dir_all(dir);
|
let _ = fs::remove_dir_all(dir);
|
||||||
cleared = true;
|
cleared = true;
|
||||||
} else if stamp.exists() {
|
} else if stamp.exists() {
|
||||||
|
@ -890,7 +890,7 @@ impl Build {
|
||||||
let executed_at = std::panic::Location::caller();
|
let executed_at = std::panic::Location::caller();
|
||||||
|
|
||||||
self.verbose(|| {
|
self.verbose(|| {
|
||||||
eprintln!("running: {command:?} (created at {created_at}, executed at {executed_at})")
|
println!("running: {command:?} (created at {created_at}, executed at {executed_at})")
|
||||||
});
|
});
|
||||||
|
|
||||||
let cmd = command.as_command_mut();
|
let cmd = command.as_command_mut();
|
||||||
|
@ -947,7 +947,7 @@ Executed at: {executed_at}"#,
|
||||||
|
|
||||||
let fail = |message: &str, output: CommandOutput| -> ! {
|
let fail = |message: &str, output: CommandOutput| -> ! {
|
||||||
if self.is_verbose() {
|
if self.is_verbose() {
|
||||||
eprintln!("{message}");
|
println!("{message}");
|
||||||
} else {
|
} else {
|
||||||
let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
|
let (stdout, stderr) = (output.stdout_if_present(), output.stderr_if_present());
|
||||||
// If the command captures output, the user would not see any indication that
|
// If the command captures output, the user would not see any indication that
|
||||||
|
@ -957,16 +957,16 @@ Executed at: {executed_at}"#,
|
||||||
if let Some(stdout) =
|
if let Some(stdout) =
|
||||||
output.stdout_if_present().take_if(|s| !s.trim().is_empty())
|
output.stdout_if_present().take_if(|s| !s.trim().is_empty())
|
||||||
{
|
{
|
||||||
eprintln!("STDOUT:\n{stdout}\n");
|
println!("STDOUT:\n{stdout}\n");
|
||||||
}
|
}
|
||||||
if let Some(stderr) =
|
if let Some(stderr) =
|
||||||
output.stderr_if_present().take_if(|s| !s.trim().is_empty())
|
output.stderr_if_present().take_if(|s| !s.trim().is_empty())
|
||||||
{
|
{
|
||||||
eprintln!("STDERR:\n{stderr}\n");
|
println!("STDERR:\n{stderr}\n");
|
||||||
}
|
}
|
||||||
eprintln!("Command {command:?} has failed. Rerun with -v to see more details.");
|
println!("Command {command:?} has failed. Rerun with -v to see more details.");
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Command has failed. Rerun with -v to see more details.");
|
println!("Command has failed. Rerun with -v to see more details.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit!(1);
|
exit!(1);
|
||||||
|
@ -1011,7 +1011,7 @@ Executed at: {executed_at}"#,
|
||||||
match self.config.dry_run {
|
match self.config.dry_run {
|
||||||
DryRun::SelfCheck => (),
|
DryRun::SelfCheck => (),
|
||||||
DryRun::Disabled | DryRun::UserSelected => {
|
DryRun::Disabled | DryRun::UserSelected => {
|
||||||
eprintln!("{msg}");
|
println!("{msg}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1666,7 +1666,7 @@ Executed at: {executed_at}"#,
|
||||||
if self.config.dry_run() {
|
if self.config.dry_run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.verbose_than(1, || eprintln!("Copy/Link {src:?} to {dst:?}"));
|
self.verbose_than(1, || println!("Copy/Link {src:?} to {dst:?}"));
|
||||||
if src == dst {
|
if src == dst {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1775,7 +1775,7 @@ Executed at: {executed_at}"#,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let dst = dstdir.join(src.file_name().unwrap());
|
let dst = dstdir.join(src.file_name().unwrap());
|
||||||
self.verbose_than(1, || eprintln!("Install {src:?} to {dst:?}"));
|
self.verbose_than(1, || println!("Install {src:?} to {dst:?}"));
|
||||||
t!(fs::create_dir_all(dstdir));
|
t!(fs::create_dir_all(dstdir));
|
||||||
if !src.exists() {
|
if !src.exists() {
|
||||||
panic!("ERROR: File \"{}\" not found!", src.display());
|
panic!("ERROR: File \"{}\" not found!", src.display());
|
||||||
|
|
|
@ -155,15 +155,15 @@ pub fn find_target(build: &Build, target: TargetSelection) {
|
||||||
build.cxx.borrow_mut().insert(target, compiler);
|
build.cxx.borrow_mut().insert(target, compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
build.verbose(|| eprintln!("CC_{} = {:?}", target.triple, build.cc(target)));
|
build.verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
|
||||||
build.verbose(|| eprintln!("CFLAGS_{} = {cflags:?}", target.triple));
|
build.verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
|
||||||
if let Ok(cxx) = build.cxx(target) {
|
if let Ok(cxx) = build.cxx(target) {
|
||||||
let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
|
let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx);
|
||||||
build.verbose(|| eprintln!("CXX_{} = {cxx:?}", target.triple));
|
build.verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
|
||||||
build.verbose(|| eprintln!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
|
build.verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
|
||||||
}
|
}
|
||||||
if let Some(ar) = ar {
|
if let Some(ar) = ar {
|
||||||
build.verbose(|| eprintln!("AR_{} = {ar:?}", target.triple));
|
build.verbose(|| println!("AR_{} = {ar:?}", target.triple));
|
||||||
build.ar.borrow_mut().insert(target, ar);
|
build.ar.borrow_mut().insert(target, ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ impl Drop for TimeIt {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let time = self.1.elapsed();
|
let time = self.1.elapsed();
|
||||||
if !self.0 {
|
if !self.0 {
|
||||||
eprintln!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis());
|
println!("\tfinished in {}.{:03} seconds", time.as_secs(), time.subsec_millis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,12 +267,12 @@ pub fn check_run(cmd: &mut BootstrapCommand, print_cmd_on_fail: bool) -> bool {
|
||||||
let status = match cmd.as_command_mut().status() {
|
let status = match cmd.as_command_mut().status() {
|
||||||
Ok(status) => status,
|
Ok(status) => status,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("failed to execute command: {cmd:?}\nERROR: {e}");
|
println!("failed to execute command: {cmd:?}\nERROR: {e}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if !status.success() && print_cmd_on_fail {
|
if !status.success() && print_cmd_on_fail {
|
||||||
eprintln!(
|
println!(
|
||||||
"\n\ncommand did not execute successfully: {cmd:?}\n\
|
"\n\ncommand did not execute successfully: {cmd:?}\n\
|
||||||
expected success, got: {status}\n\n"
|
expected success, got: {status}\n\n"
|
||||||
);
|
);
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl BuildMetrics {
|
||||||
if version.format_version == CURRENT_FORMAT_VERSION {
|
if version.format_version == CURRENT_FORMAT_VERSION {
|
||||||
t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations
|
t!(serde_json::from_slice::<JsonRoot>(&contents)).invocations
|
||||||
} else {
|
} else {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: overriding existing build/metrics.json, as it's not \
|
"WARNING: overriding existing build/metrics.json, as it's not \
|
||||||
compatible with build metrics format version {CURRENT_FORMAT_VERSION}."
|
compatible with build metrics format version {CURRENT_FORMAT_VERSION}."
|
||||||
);
|
);
|
||||||
|
|
|
@ -56,7 +56,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
|
||||||
let cmd = cmd.as_command_mut();
|
let cmd = cmd.as_command_mut();
|
||||||
cmd.stdout(Stdio::piped());
|
cmd.stdout(Stdio::piped());
|
||||||
|
|
||||||
builder.verbose(|| eprintln!("running: {cmd:?}"));
|
builder.verbose(|| println!("running: {cmd:?}"));
|
||||||
|
|
||||||
let mut process = cmd.spawn().unwrap();
|
let mut process = cmd.spawn().unwrap();
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut BootstrapCommand, stream: bool) ->
|
||||||
|
|
||||||
let result = process.wait_with_output().unwrap();
|
let result = process.wait_with_output().unwrap();
|
||||||
if !result.status.success() && builder.is_verbose() {
|
if !result.status.success() && builder.is_verbose() {
|
||||||
eprintln!(
|
println!(
|
||||||
"\n\ncommand did not execute successfully: {cmd:?}\n\
|
"\n\ncommand did not execute successfully: {cmd:?}\n\
|
||||||
expected success, got: {}",
|
expected success, got: {}",
|
||||||
result.status
|
result.status
|
||||||
|
@ -135,9 +135,7 @@ impl<'a> Renderer<'a> {
|
||||||
if self.up_to_date_tests > 0 {
|
if self.up_to_date_tests > 0 {
|
||||||
let n = self.up_to_date_tests;
|
let n = self.up_to_date_tests;
|
||||||
let s = if n > 1 { "s" } else { "" };
|
let s = if n > 1 { "s" } else { "" };
|
||||||
eprintln!(
|
println!("help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n");
|
||||||
"help: ignored {n} up-to-date test{s}; use `--force-rerun` to prevent this\n"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +190,7 @@ impl<'a> Renderer<'a> {
|
||||||
if let Some(exec_time) = test.exec_time {
|
if let Some(exec_time) = test.exec_time {
|
||||||
print!(" ({exec_time:.2?})");
|
print!(" ({exec_time:.2?})");
|
||||||
}
|
}
|
||||||
eprintln!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
|
fn render_test_outcome_terse(&mut self, outcome: Outcome<'_>, test: &TestOutcome) {
|
||||||
|
@ -202,7 +200,7 @@ impl<'a> Renderer<'a> {
|
||||||
let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len());
|
let executed = format!("{:>width$}", self.executed_tests - 1, width = total.len());
|
||||||
print!(" {executed}/{total}");
|
print!(" {executed}/{total}");
|
||||||
}
|
}
|
||||||
eprintln!();
|
println!();
|
||||||
self.terse_tests_in_line = 0;
|
self.terse_tests_in_line = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,31 +212,31 @@ impl<'a> Renderer<'a> {
|
||||||
fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) {
|
fn render_suite_outcome(&self, outcome: Outcome<'_>, suite: &SuiteOutcome) {
|
||||||
// The terse output doesn't end with a newline, so we need to add it ourselves.
|
// The terse output doesn't end with a newline, so we need to add it ourselves.
|
||||||
if !self.builder.config.verbose_tests {
|
if !self.builder.config.verbose_tests {
|
||||||
eprintln!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.failures.is_empty() {
|
if !self.failures.is_empty() {
|
||||||
eprintln!("\nfailures:\n");
|
println!("\nfailures:\n");
|
||||||
for failure in &self.failures {
|
for failure in &self.failures {
|
||||||
if failure.stdout.is_some() || failure.message.is_some() {
|
if failure.stdout.is_some() || failure.message.is_some() {
|
||||||
eprintln!("---- {} stdout ----", failure.name);
|
println!("---- {} stdout ----", failure.name);
|
||||||
if let Some(stdout) = &failure.stdout {
|
if let Some(stdout) = &failure.stdout {
|
||||||
eprintln!("{stdout}");
|
println!("{stdout}");
|
||||||
}
|
}
|
||||||
if let Some(message) = &failure.message {
|
if let Some(message) = &failure.message {
|
||||||
eprintln!("NOTE: {message}");
|
println!("NOTE: {message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("\nfailures:");
|
println!("\nfailures:");
|
||||||
for failure in &self.failures {
|
for failure in &self.failures {
|
||||||
eprintln!(" {}", failure.name);
|
println!(" {}", failure.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.benches.is_empty() {
|
if !self.benches.is_empty() {
|
||||||
eprintln!("\nbenchmarks:");
|
println!("\nbenchmarks:");
|
||||||
|
|
||||||
let mut rows = Vec::new();
|
let mut rows = Vec::new();
|
||||||
for bench in &self.benches {
|
for bench in &self.benches {
|
||||||
|
@ -253,13 +251,13 @@ impl<'a> Renderer<'a> {
|
||||||
let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0);
|
let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0);
|
||||||
let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0);
|
let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0);
|
||||||
for row in &rows {
|
for row in &rows {
|
||||||
eprintln!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
|
println!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print!("\ntest result: ");
|
print!("\ntest result: ");
|
||||||
self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
|
self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
|
||||||
eprintln!(
|
println!(
|
||||||
". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
|
". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
|
||||||
suite.passed,
|
suite.passed,
|
||||||
suite.failed,
|
suite.failed,
|
||||||
|
@ -276,7 +274,7 @@ impl<'a> Renderer<'a> {
|
||||||
fn render_message(&mut self, message: Message) {
|
fn render_message(&mut self, message: Message) {
|
||||||
match message {
|
match message {
|
||||||
Message::Suite(SuiteMessage::Started { test_count }) => {
|
Message::Suite(SuiteMessage::Started { test_count }) => {
|
||||||
eprintln!("\nrunning {test_count} tests");
|
println!("\nrunning {test_count} tests");
|
||||||
self.executed_tests = 0;
|
self.executed_tests = 0;
|
||||||
self.terse_tests_in_line = 0;
|
self.terse_tests_in_line = 0;
|
||||||
self.tests_count = Some(test_count);
|
self.tests_count = Some(test_count);
|
||||||
|
@ -316,7 +314,7 @@ impl<'a> Renderer<'a> {
|
||||||
self.failures.push(outcome);
|
self.failures.push(outcome);
|
||||||
}
|
}
|
||||||
Message::Test(TestMessage::Timeout { name }) => {
|
Message::Test(TestMessage::Timeout { name }) => {
|
||||||
eprintln!("test {name} has been running for a long time");
|
println!("test {name} has been running for a long time");
|
||||||
}
|
}
|
||||||
Message::Test(TestMessage::Started) => {} // Not useful
|
Message::Test(TestMessage::Started) => {} // Not useful
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,7 +344,7 @@ impl<'a> Tarball<'a> {
|
||||||
// For `x install` tarball files aren't needed, so we can speed up the process by not producing them.
|
// For `x install` tarball files aren't needed, so we can speed up the process by not producing them.
|
||||||
let compression_profile = if self.builder.kind == Kind::Install {
|
let compression_profile = if self.builder.kind == Kind::Install {
|
||||||
self.builder.verbose(|| {
|
self.builder.verbose(|| {
|
||||||
eprintln!("Forcing dist.compression-profile = 'no-op' for `x install`.")
|
println!("Forcing dist.compression-profile = 'no-op' for `x install`.")
|
||||||
});
|
});
|
||||||
// "no-op" indicates that the rust-installer won't produce compressed tarball sources.
|
// "no-op" indicates that the rust-installer won't produce compressed tarball sources.
|
||||||
"no-op"
|
"no-op"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit e16dd73690a6cc3ecdc5f5d94bbc3ce158a42e16
|
Subproject commit 614c19cb4025636eb2ba68ebb3d44e3bd3a5e6e4
|
|
@ -1 +1 @@
|
||||||
Subproject commit f48b0e842a3911c63240e955d042089e9e0894c7
|
Subproject commit 128669297c8a7fdf771042eaec18b8adfaeaf0cd
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5c86c739ec71b8bc839310ff47fa94e94635bba9
|
Subproject commit ede56d1bbe132bac476b5029cd6d7508ca9572e9
|
|
@ -1 +1 @@
|
||||||
Subproject commit 787b4166ccc67bd8f72a6e3ef6685ce9ce82909a
|
Subproject commit b21d99b770f9aceb0810c843847c52f86f45d2ed
|
|
@ -744,7 +744,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::unit_types::LET_UNIT_VALUE_INFO,
|
crate::unit_types::LET_UNIT_VALUE_INFO,
|
||||||
crate::unit_types::UNIT_ARG_INFO,
|
crate::unit_types::UNIT_ARG_INFO,
|
||||||
crate::unit_types::UNIT_CMP_INFO,
|
crate::unit_types::UNIT_CMP_INFO,
|
||||||
crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
|
|
||||||
crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
|
crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
|
||||||
crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO,
|
crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO,
|
||||||
crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
|
crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
|
||||||
|
|
|
@ -74,6 +74,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
|
||||||
#[clippy::version = "1.53.0"]
|
#[clippy::version = "1.53.0"]
|
||||||
("clippy::filter_map", "clippy::manual_filter_map"),
|
("clippy::filter_map", "clippy::manual_filter_map"),
|
||||||
#[clippy::version = ""]
|
#[clippy::version = ""]
|
||||||
|
("clippy::fn_address_comparisons", "unpredictable_function_pointer_comparisons"),
|
||||||
|
#[clippy::version = ""]
|
||||||
("clippy::identity_conversion", "clippy::useless_conversion"),
|
("clippy::identity_conversion", "clippy::useless_conversion"),
|
||||||
#[clippy::version = "pre 1.29.0"]
|
#[clippy::version = "pre 1.29.0"]
|
||||||
("clippy::if_let_redundant_pattern_matching", "clippy::redundant_pattern_matching"),
|
("clippy::if_let_redundant_pattern_matching", "clippy::redundant_pattern_matching"),
|
||||||
|
|
|
@ -363,7 +363,6 @@ mod uninhabited_references;
|
||||||
mod uninit_vec;
|
mod uninit_vec;
|
||||||
mod unit_return_expecting_ord;
|
mod unit_return_expecting_ord;
|
||||||
mod unit_types;
|
mod unit_types;
|
||||||
mod unnamed_address;
|
|
||||||
mod unnecessary_box_returns;
|
mod unnecessary_box_returns;
|
||||||
mod unnecessary_literal_bound;
|
mod unnecessary_literal_bound;
|
||||||
mod unnecessary_map_on_constructor;
|
mod unnecessary_map_on_constructor;
|
||||||
|
@ -786,7 +785,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
||||||
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
|
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
|
||||||
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(conf)));
|
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(conf)));
|
||||||
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
|
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
|
||||||
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
|
|
||||||
store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
|
store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
|
||||||
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
|
store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
|
||||||
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
|
store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
use clippy_utils::diagnostics::span_lint;
|
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
|
||||||
use rustc_middle::ty;
|
|
||||||
use rustc_session::declare_lint_pass;
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
|
||||||
/// ### What it does
|
|
||||||
/// Checks for comparisons with an address of a function item.
|
|
||||||
///
|
|
||||||
/// ### Why is this bad?
|
|
||||||
/// Function item address is not guaranteed to be unique and could vary
|
|
||||||
/// between different code generation units. Furthermore different function items could have
|
|
||||||
/// the same address after being merged together.
|
|
||||||
///
|
|
||||||
/// ### Example
|
|
||||||
/// ```no_run
|
|
||||||
/// type F = fn();
|
|
||||||
/// fn a() {}
|
|
||||||
/// let f: F = a;
|
|
||||||
/// if f == a {
|
|
||||||
/// // ...
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[clippy::version = "1.44.0"]
|
|
||||||
pub FN_ADDRESS_COMPARISONS,
|
|
||||||
correctness,
|
|
||||||
"comparison with an address of a function item"
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint_pass!(UnnamedAddress => [FN_ADDRESS_COMPARISONS]);
|
|
||||||
|
|
||||||
impl LateLintPass<'_> for UnnamedAddress {
|
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
|
||||||
fn is_comparison(binop: BinOpKind) -> bool {
|
|
||||||
matches!(
|
|
||||||
binop,
|
|
||||||
BinOpKind::Eq | BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ne | BinOpKind::Ge | BinOpKind::Gt
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_fn_def(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|
||||||
matches!(cx.typeck_results().expr_ty(expr).kind(), ty::FnDef(..))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let ExprKind::Binary(binop, left, right) = expr.kind
|
|
||||||
&& is_comparison(binop.node)
|
|
||||||
&& cx.typeck_results().expr_ty_adjusted(left).is_fn_ptr()
|
|
||||||
&& cx.typeck_results().expr_ty_adjusted(right).is_fn_ptr()
|
|
||||||
&& (is_fn_def(cx, left) || is_fn_def(cx, right))
|
|
||||||
{
|
|
||||||
span_lint(
|
|
||||||
cx,
|
|
||||||
FN_ADDRESS_COMPARISONS,
|
|
||||||
expr.span,
|
|
||||||
"comparing with a non-unique address of a function item",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
use std::fmt::Debug;
|
|
||||||
use std::ptr;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
fn a() {}
|
|
||||||
|
|
||||||
#[warn(clippy::fn_address_comparisons)]
|
|
||||||
fn main() {
|
|
||||||
type F = fn();
|
|
||||||
let f: F = a;
|
|
||||||
let g: F = f;
|
|
||||||
|
|
||||||
// These should fail:
|
|
||||||
let _ = f == a;
|
|
||||||
//~^ ERROR: comparing with a non-unique address of a function item
|
|
||||||
//~| NOTE: `-D clippy::fn-address-comparisons` implied by `-D warnings`
|
|
||||||
let _ = f != a;
|
|
||||||
//~^ ERROR: comparing with a non-unique address of a function item
|
|
||||||
|
|
||||||
// These should be fine:
|
|
||||||
let _ = f == g;
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
error: comparing with a non-unique address of a function item
|
|
||||||
--> tests/ui/fn_address_comparisons.rs:15:13
|
|
||||||
|
|
|
||||||
LL | let _ = f == a;
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: `-D clippy::fn-address-comparisons` implied by `-D warnings`
|
|
||||||
= help: to override `-D warnings` add `#[allow(clippy::fn_address_comparisons)]`
|
|
||||||
|
|
||||||
error: comparing with a non-unique address of a function item
|
|
||||||
--> tests/ui/fn_address_comparisons.rs:18:13
|
|
||||||
|
|
|
||||||
LL | let _ = f != a;
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#![allow(unknown_lints)]
|
#![allow(unknown_lints)]
|
||||||
#![allow(unused_labels)]
|
#![allow(unused_labels)]
|
||||||
#![allow(ambiguous_wide_pointer_comparisons)]
|
#![allow(ambiguous_wide_pointer_comparisons)]
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
#![allow(clippy::reversed_empty_ranges)]
|
#![allow(clippy::reversed_empty_ranges)]
|
||||||
#![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`
|
#![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`
|
||||||
#![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name`
|
#![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name`
|
||||||
|
@ -74,6 +75,7 @@
|
||||||
#![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence`
|
#![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence`
|
||||||
#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map`
|
#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map`
|
||||||
#![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map`
|
#![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map`
|
||||||
|
#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`
|
||||||
#![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion`
|
#![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion`
|
||||||
#![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`
|
#![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`
|
||||||
#![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result`
|
#![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result`
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#![allow(unknown_lints)]
|
#![allow(unknown_lints)]
|
||||||
#![allow(unused_labels)]
|
#![allow(unused_labels)]
|
||||||
#![allow(ambiguous_wide_pointer_comparisons)]
|
#![allow(ambiguous_wide_pointer_comparisons)]
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
#![allow(clippy::reversed_empty_ranges)]
|
#![allow(clippy::reversed_empty_ranges)]
|
||||||
#![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`
|
#![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`
|
||||||
#![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name`
|
#![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name`
|
||||||
|
@ -74,6 +75,7 @@
|
||||||
#![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence`
|
#![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence`
|
||||||
#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map`
|
#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map`
|
||||||
#![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map`
|
#![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map`
|
||||||
|
#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`
|
||||||
#![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion`
|
#![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion`
|
||||||
#![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`
|
#![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`
|
||||||
#![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result`
|
#![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
|
error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
|
||||||
--> tests/ui/rename.rs:63:9
|
--> tests/ui/rename.rs:64:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::almost_complete_letter_range)]
|
LL | #![warn(clippy::almost_complete_letter_range)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
|
||||||
|
@ -8,394 +8,400 @@ LL | #![warn(clippy::almost_complete_letter_range)]
|
||||||
= help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
|
= help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
|
||||||
|
|
||||||
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
|
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
|
||||||
--> tests/ui/rename.rs:64:9
|
--> tests/ui/rename.rs:65:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::blacklisted_name)]
|
LL | #![warn(clippy::blacklisted_name)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
|
||||||
|
|
||||||
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions`
|
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions`
|
||||||
--> tests/ui/rename.rs:65:9
|
--> tests/ui/rename.rs:66:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::block_in_if_condition_expr)]
|
LL | #![warn(clippy::block_in_if_condition_expr)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
|
||||||
|
|
||||||
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions`
|
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions`
|
||||||
--> tests/ui/rename.rs:66:9
|
--> tests/ui/rename.rs:67:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::block_in_if_condition_stmt)]
|
LL | #![warn(clippy::block_in_if_condition_stmt)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
|
||||||
|
|
||||||
error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions`
|
error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions`
|
||||||
--> tests/ui/rename.rs:67:9
|
--> tests/ui/rename.rs:68:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::blocks_in_if_conditions)]
|
LL | #![warn(clippy::blocks_in_if_conditions)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
|
||||||
|
|
||||||
error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
|
error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
|
||||||
--> tests/ui/rename.rs:68:9
|
--> tests/ui/rename.rs:69:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::box_vec)]
|
LL | #![warn(clippy::box_vec)]
|
||||||
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
|
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
|
||||||
|
|
||||||
error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
|
error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
|
||||||
--> tests/ui/rename.rs:69:9
|
--> tests/ui/rename.rs:70:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::const_static_lifetime)]
|
LL | #![warn(clippy::const_static_lifetime)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
|
||||||
|
|
||||||
error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
|
error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
|
||||||
--> tests/ui/rename.rs:70:9
|
--> tests/ui/rename.rs:71:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::cyclomatic_complexity)]
|
LL | #![warn(clippy::cyclomatic_complexity)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
|
||||||
|
|
||||||
error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
|
error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
|
||||||
--> tests/ui/rename.rs:71:9
|
--> tests/ui/rename.rs:72:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::derive_hash_xor_eq)]
|
LL | #![warn(clippy::derive_hash_xor_eq)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
|
||||||
|
|
||||||
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
|
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
|
||||||
--> tests/ui/rename.rs:72:9
|
--> tests/ui/rename.rs:73:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::disallowed_method)]
|
LL | #![warn(clippy::disallowed_method)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
|
||||||
|
|
||||||
error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
|
error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
|
||||||
--> tests/ui/rename.rs:73:9
|
--> tests/ui/rename.rs:74:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::disallowed_type)]
|
LL | #![warn(clippy::disallowed_type)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
|
||||||
|
|
||||||
error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
|
error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
|
||||||
--> tests/ui/rename.rs:74:9
|
--> tests/ui/rename.rs:75:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::eval_order_dependence)]
|
LL | #![warn(clippy::eval_order_dependence)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
|
||||||
|
|
||||||
error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map`
|
error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map`
|
||||||
--> tests/ui/rename.rs:75:9
|
--> tests/ui/rename.rs:76:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::find_map)]
|
LL | #![warn(clippy::find_map)]
|
||||||
| ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map`
|
| ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map`
|
||||||
|
|
||||||
error: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map`
|
error: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map`
|
||||||
--> tests/ui/rename.rs:76:9
|
--> tests/ui/rename.rs:77:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::filter_map)]
|
LL | #![warn(clippy::filter_map)]
|
||||||
| ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map`
|
| ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map`
|
||||||
|
|
||||||
|
error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons`
|
||||||
|
--> tests/ui/rename.rs:78:9
|
||||||
|
|
|
||||||
|
LL | #![warn(clippy::fn_address_comparisons)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons`
|
||||||
|
|
||||||
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
|
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
|
||||||
--> tests/ui/rename.rs:77:9
|
--> tests/ui/rename.rs:79:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::identity_conversion)]
|
LL | #![warn(clippy::identity_conversion)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
|
||||||
|
|
||||||
error: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching`
|
error: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching`
|
||||||
--> tests/ui/rename.rs:78:9
|
--> tests/ui/rename.rs:80:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::if_let_redundant_pattern_matching)]
|
LL | #![warn(clippy::if_let_redundant_pattern_matching)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching`
|
||||||
|
|
||||||
error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
|
error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
|
||||||
--> tests/ui/rename.rs:79:9
|
--> tests/ui/rename.rs:81:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::if_let_some_result)]
|
LL | #![warn(clippy::if_let_some_result)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
|
||||||
|
|
||||||
error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl`
|
error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl`
|
||||||
--> tests/ui/rename.rs:80:9
|
--> tests/ui/rename.rs:82:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)]
|
LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl`
|
||||||
|
|
||||||
error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl`
|
error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl`
|
||||||
--> tests/ui/rename.rs:81:9
|
--> tests/ui/rename.rs:83:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]
|
LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl`
|
||||||
|
|
||||||
error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
|
error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
|
||||||
--> tests/ui/rename.rs:82:9
|
--> tests/ui/rename.rs:84:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::integer_arithmetic)]
|
LL | #![warn(clippy::integer_arithmetic)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
|
||||||
|
|
||||||
error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
|
error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
|
||||||
--> tests/ui/rename.rs:83:9
|
--> tests/ui/rename.rs:85:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::logic_bug)]
|
LL | #![warn(clippy::logic_bug)]
|
||||||
| ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
|
| ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
|
||||||
|
|
||||||
error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
|
error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
|
||||||
--> tests/ui/rename.rs:84:9
|
--> tests/ui/rename.rs:86:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::new_without_default_derive)]
|
LL | #![warn(clippy::new_without_default_derive)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
|
||||||
|
|
||||||
error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
|
error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
|
||||||
--> tests/ui/rename.rs:85:9
|
--> tests/ui/rename.rs:87:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::option_and_then_some)]
|
LL | #![warn(clippy::option_and_then_some)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
|
||||||
|
|
||||||
error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
|
error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
|
||||||
--> tests/ui/rename.rs:86:9
|
--> tests/ui/rename.rs:88:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::option_expect_used)]
|
LL | #![warn(clippy::option_expect_used)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
|
||||||
|
|
||||||
error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
|
error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
|
||||||
--> tests/ui/rename.rs:87:9
|
--> tests/ui/rename.rs:89:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::option_map_unwrap_or)]
|
LL | #![warn(clippy::option_map_unwrap_or)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
|
||||||
|
|
||||||
error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
|
error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
|
||||||
--> tests/ui/rename.rs:88:9
|
--> tests/ui/rename.rs:90:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::option_map_unwrap_or_else)]
|
LL | #![warn(clippy::option_map_unwrap_or_else)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
|
||||||
|
|
||||||
error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
|
error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
|
||||||
--> tests/ui/rename.rs:89:9
|
--> tests/ui/rename.rs:91:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::option_unwrap_used)]
|
LL | #![warn(clippy::option_unwrap_used)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
|
||||||
|
|
||||||
error: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks`
|
error: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks`
|
||||||
--> tests/ui/rename.rs:90:9
|
--> tests/ui/rename.rs:92:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::overflow_check_conditional)]
|
LL | #![warn(clippy::overflow_check_conditional)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks`
|
||||||
|
|
||||||
error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
|
error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
|
||||||
--> tests/ui/rename.rs:91:9
|
--> tests/ui/rename.rs:93:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::ref_in_deref)]
|
LL | #![warn(clippy::ref_in_deref)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
|
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
|
||||||
|
|
||||||
error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
|
error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
|
||||||
--> tests/ui/rename.rs:92:9
|
--> tests/ui/rename.rs:94:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::result_expect_used)]
|
LL | #![warn(clippy::result_expect_used)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
|
||||||
|
|
||||||
error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
|
error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
|
||||||
--> tests/ui/rename.rs:93:9
|
--> tests/ui/rename.rs:95:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::result_map_unwrap_or_else)]
|
LL | #![warn(clippy::result_map_unwrap_or_else)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
|
||||||
|
|
||||||
error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
|
error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
|
||||||
--> tests/ui/rename.rs:94:9
|
--> tests/ui/rename.rs:96:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::result_unwrap_used)]
|
LL | #![warn(clippy::result_unwrap_used)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
|
||||||
|
|
||||||
error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
|
error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
|
||||||
--> tests/ui/rename.rs:95:9
|
--> tests/ui/rename.rs:97:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::single_char_push_str)]
|
LL | #![warn(clippy::single_char_push_str)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
|
||||||
|
|
||||||
error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
|
error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
|
||||||
--> tests/ui/rename.rs:96:9
|
--> tests/ui/rename.rs:98:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::stutter)]
|
LL | #![warn(clippy::stutter)]
|
||||||
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
|
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
|
||||||
|
|
||||||
error: lint `clippy::thread_local_initializer_can_be_made_const` has been renamed to `clippy::missing_const_for_thread_local`
|
error: lint `clippy::thread_local_initializer_can_be_made_const` has been renamed to `clippy::missing_const_for_thread_local`
|
||||||
--> tests/ui/rename.rs:97:9
|
--> tests/ui/rename.rs:99:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::thread_local_initializer_can_be_made_const)]
|
LL | #![warn(clippy::thread_local_initializer_can_be_made_const)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::missing_const_for_thread_local`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::missing_const_for_thread_local`
|
||||||
|
|
||||||
error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
|
error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
|
||||||
--> tests/ui/rename.rs:98:9
|
--> tests/ui/rename.rs:100:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::to_string_in_display)]
|
LL | #![warn(clippy::to_string_in_display)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
|
||||||
|
|
||||||
error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default`
|
error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default`
|
||||||
--> tests/ui/rename.rs:99:9
|
--> tests/ui/rename.rs:101:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::unwrap_or_else_default)]
|
LL | #![warn(clippy::unwrap_or_else_default)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default`
|
||||||
|
|
||||||
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
|
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
|
||||||
--> tests/ui/rename.rs:100:9
|
--> tests/ui/rename.rs:102:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::zero_width_space)]
|
LL | #![warn(clippy::zero_width_space)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
|
||||||
|
|
||||||
error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting`
|
error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting`
|
||||||
--> tests/ui/rename.rs:101:9
|
--> tests/ui/rename.rs:103:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::cast_ref_to_mut)]
|
LL | #![warn(clippy::cast_ref_to_mut)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting`
|
||||||
|
|
||||||
error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
|
error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
|
||||||
--> tests/ui/rename.rs:102:9
|
--> tests/ui/rename.rs:104:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::clone_double_ref)]
|
LL | #![warn(clippy::clone_double_ref)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
|
||||||
|
|
||||||
error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
|
error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
|
||||||
--> tests/ui/rename.rs:103:9
|
--> tests/ui/rename.rs:105:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::cmp_nan)]
|
LL | #![warn(clippy::cmp_nan)]
|
||||||
| ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
|
| ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
|
||||||
|
|
||||||
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
|
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
|
||||||
--> tests/ui/rename.rs:104:9
|
--> tests/ui/rename.rs:106:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::drop_bounds)]
|
LL | #![warn(clippy::drop_bounds)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
|
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
|
||||||
|
|
||||||
error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
|
error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
|
||||||
--> tests/ui/rename.rs:105:9
|
--> tests/ui/rename.rs:107:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::drop_copy)]
|
LL | #![warn(clippy::drop_copy)]
|
||||||
| ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
|
| ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
|
||||||
|
|
||||||
error: lint `clippy::drop_ref` has been renamed to `dropping_references`
|
error: lint `clippy::drop_ref` has been renamed to `dropping_references`
|
||||||
--> tests/ui/rename.rs:106:9
|
--> tests/ui/rename.rs:108:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::drop_ref)]
|
LL | #![warn(clippy::drop_ref)]
|
||||||
| ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
|
| ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
|
||||||
|
|
||||||
error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
|
error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
|
||||||
--> tests/ui/rename.rs:107:9
|
--> tests/ui/rename.rs:109:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::fn_null_check)]
|
LL | #![warn(clippy::fn_null_check)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`
|
| ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`
|
||||||
|
|
||||||
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
|
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
|
||||||
--> tests/ui/rename.rs:108:9
|
--> tests/ui/rename.rs:110:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::for_loop_over_option)]
|
LL | #![warn(clippy::for_loop_over_option)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
|
||||||
|
|
||||||
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
|
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
|
||||||
--> tests/ui/rename.rs:109:9
|
--> tests/ui/rename.rs:111:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::for_loop_over_result)]
|
LL | #![warn(clippy::for_loop_over_result)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
|
||||||
|
|
||||||
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
|
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
|
||||||
--> tests/ui/rename.rs:110:9
|
--> tests/ui/rename.rs:112:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::for_loops_over_fallibles)]
|
LL | #![warn(clippy::for_loops_over_fallibles)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
|
||||||
|
|
||||||
error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
|
error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
|
||||||
--> tests/ui/rename.rs:111:9
|
--> tests/ui/rename.rs:113:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::forget_copy)]
|
LL | #![warn(clippy::forget_copy)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
|
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
|
||||||
|
|
||||||
error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
|
error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
|
||||||
--> tests/ui/rename.rs:112:9
|
--> tests/ui/rename.rs:114:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::forget_ref)]
|
LL | #![warn(clippy::forget_ref)]
|
||||||
| ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
|
| ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
|
||||||
|
|
||||||
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
|
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
|
||||||
--> tests/ui/rename.rs:113:9
|
--> tests/ui/rename.rs:115:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::into_iter_on_array)]
|
LL | #![warn(clippy::into_iter_on_array)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
|
||||||
|
|
||||||
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
|
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
|
||||||
--> tests/ui/rename.rs:114:9
|
--> tests/ui/rename.rs:116:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::invalid_atomic_ordering)]
|
LL | #![warn(clippy::invalid_atomic_ordering)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
|
||||||
|
|
||||||
error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
|
error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
|
||||||
--> tests/ui/rename.rs:115:9
|
--> tests/ui/rename.rs:117:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::invalid_ref)]
|
LL | #![warn(clippy::invalid_ref)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
|
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
|
||||||
|
|
||||||
error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
|
error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
|
||||||
--> tests/ui/rename.rs:116:9
|
--> tests/ui/rename.rs:118:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::invalid_utf8_in_unchecked)]
|
LL | #![warn(clippy::invalid_utf8_in_unchecked)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
|
||||||
|
|
||||||
error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
|
error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
|
||||||
--> tests/ui/rename.rs:117:9
|
--> tests/ui/rename.rs:119:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::let_underscore_drop)]
|
LL | #![warn(clippy::let_underscore_drop)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
|
||||||
|
|
||||||
error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs`
|
error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs`
|
||||||
--> tests/ui/rename.rs:118:9
|
--> tests/ui/rename.rs:120:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::maybe_misused_cfg)]
|
LL | #![warn(clippy::maybe_misused_cfg)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
|
||||||
|
|
||||||
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
|
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
|
||||||
--> tests/ui/rename.rs:119:9
|
--> tests/ui/rename.rs:121:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::mem_discriminant_non_enum)]
|
LL | #![warn(clippy::mem_discriminant_non_enum)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
|
||||||
|
|
||||||
error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs`
|
error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs`
|
||||||
--> tests/ui/rename.rs:120:9
|
--> tests/ui/rename.rs:122:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::mismatched_target_os)]
|
LL | #![warn(clippy::mismatched_target_os)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
|
||||||
|
|
||||||
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
|
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
|
||||||
--> tests/ui/rename.rs:121:9
|
--> tests/ui/rename.rs:123:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::panic_params)]
|
LL | #![warn(clippy::panic_params)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
|
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
|
||||||
|
|
||||||
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
|
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
|
||||||
--> tests/ui/rename.rs:122:9
|
--> tests/ui/rename.rs:124:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::positional_named_format_parameters)]
|
LL | #![warn(clippy::positional_named_format_parameters)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
|
||||||
|
|
||||||
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
|
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
|
||||||
--> tests/ui/rename.rs:123:9
|
--> tests/ui/rename.rs:125:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::temporary_cstring_as_ptr)]
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
|
||||||
|
|
||||||
error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
|
error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
|
||||||
--> tests/ui/rename.rs:124:9
|
--> tests/ui/rename.rs:126:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::undropped_manually_drops)]
|
LL | #![warn(clippy::undropped_manually_drops)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
|
||||||
|
|
||||||
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
|
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
|
||||||
--> tests/ui/rename.rs:125:9
|
--> tests/ui/rename.rs:127:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::unknown_clippy_lints)]
|
LL | #![warn(clippy::unknown_clippy_lints)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
|
||||||
|
|
||||||
error: lint `clippy::unused_label` has been renamed to `unused_labels`
|
error: lint `clippy::unused_label` has been renamed to `unused_labels`
|
||||||
--> tests/ui/rename.rs:126:9
|
--> tests/ui/rename.rs:128:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::unused_label)]
|
LL | #![warn(clippy::unused_label)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
|
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
|
||||||
|
|
||||||
error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`
|
error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`
|
||||||
--> tests/ui/rename.rs:127:9
|
--> tests/ui/rename.rs:129:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::vtable_address_comparisons)]
|
LL | #![warn(clippy::vtable_address_comparisons)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`
|
||||||
|
|
||||||
error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges`
|
error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges`
|
||||||
--> tests/ui/rename.rs:128:9
|
--> tests/ui/rename.rs:130:9
|
||||||
|
|
|
|
||||||
LL | #![warn(clippy::reverse_range_loop)]
|
LL | #![warn(clippy::reverse_range_loop)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`
|
||||||
|
|
||||||
error: aborting due to 66 previous errors
|
error: aborting due to 67 previous errors
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
if !wrote_data {
|
if !wrote_data {
|
||||||
eprintln!("note: diff is identical to nightly rustdoc");
|
println!("note: diff is identical to nightly rustdoc");
|
||||||
assert!(diff_output.metadata().unwrap().len() == 0);
|
assert!(diff_output.metadata().unwrap().len() == 0);
|
||||||
return false;
|
return false;
|
||||||
} else if verbose {
|
} else if verbose {
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.remote_test_client.is_some() && !config.target.contains("android") {
|
if config.remote_test_client.is_some() && !config.target.contains("android") {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: debuginfo tests are not available when \
|
"WARNING: debuginfo tests are not available when \
|
||||||
testing with remote"
|
testing with remote"
|
||||||
);
|
);
|
||||||
|
@ -28,7 +28,7 @@ pub(crate) fn configure_gdb(config: &Config) -> Option<Arc<Config>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.target.contains("android") {
|
if config.target.contains("android") {
|
||||||
eprintln!(
|
println!(
|
||||||
"{} debug-info test uses tcp 5039 port.\
|
"{} debug-info test uses tcp 5039 port.\
|
||||||
please reserve it",
|
please reserve it",
|
||||||
config.target
|
config.target
|
||||||
|
@ -50,7 +50,7 @@ pub(crate) fn configure_lldb(config: &Config) -> Option<Arc<Config>> {
|
||||||
config.lldb_python_dir.as_ref()?;
|
config.lldb_python_dir.as_ref()?;
|
||||||
|
|
||||||
if let Some(350) = config.lldb_version {
|
if let Some(350) = config.lldb_version {
|
||||||
eprintln!(
|
println!(
|
||||||
"WARNING: The used version of LLDB (350) has a \
|
"WARNING: The used version of LLDB (350) has a \
|
||||||
known issue that breaks debuginfo tests. See \
|
known issue that breaks debuginfo tests. See \
|
||||||
issue #32520 for more information. Skipping all \
|
issue #32520 for more information. Skipping all \
|
||||||
|
|
|
@ -188,8 +188,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||||
let (argv0, args_) = args.split_first().unwrap();
|
let (argv0, args_) = args.split_first().unwrap();
|
||||||
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
|
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
|
||||||
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
|
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
|
||||||
eprintln!("{}", opts.usage(&message));
|
println!("{}", opts.usage(&message));
|
||||||
eprintln!();
|
println!();
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,8 +200,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||||
|
|
||||||
if matches.opt_present("h") || matches.opt_present("help") {
|
if matches.opt_present("h") || matches.opt_present("help") {
|
||||||
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
|
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
|
||||||
eprintln!("{}", opts.usage(&message));
|
println!("{}", opts.usage(&message));
|
||||||
eprintln!();
|
println!();
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ pub fn run_tests(config: Arc<Config>) {
|
||||||
// easy to miss which tests failed, and as such fail to reproduce
|
// easy to miss which tests failed, and as such fail to reproduce
|
||||||
// the failure locally.
|
// the failure locally.
|
||||||
|
|
||||||
eprintln!(
|
println!(
|
||||||
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
|
"Some tests failed in compiletest suite={}{} mode={} host={} target={}",
|
||||||
config.suite,
|
config.suite,
|
||||||
config
|
config
|
||||||
|
|
|
@ -774,20 +774,20 @@ impl<'test> TestCx<'test> {
|
||||||
unexpected.len(),
|
unexpected.len(),
|
||||||
not_found.len()
|
not_found.len()
|
||||||
));
|
));
|
||||||
eprintln!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
|
println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline);
|
||||||
if !unexpected.is_empty() {
|
if !unexpected.is_empty() {
|
||||||
eprintln!("{}", "--- unexpected errors (from JSON output) ---".green());
|
println!("{}", "--- unexpected errors (from JSON output) ---".green());
|
||||||
for error in &unexpected {
|
for error in &unexpected {
|
||||||
eprintln!("{}", error.render_for_expected());
|
println!("{}", error.render_for_expected());
|
||||||
}
|
}
|
||||||
eprintln!("{}", "---".green());
|
println!("{}", "---".green());
|
||||||
}
|
}
|
||||||
if !not_found.is_empty() {
|
if !not_found.is_empty() {
|
||||||
eprintln!("{}", "--- not found errors (from test file) ---".red());
|
println!("{}", "--- not found errors (from test file) ---".red());
|
||||||
for error in ¬_found {
|
for error in ¬_found {
|
||||||
eprintln!("{}", error.render_for_expected());
|
println!("{}", error.render_for_expected());
|
||||||
}
|
}
|
||||||
eprintln!("{}", "---\n".red());
|
println!("{}", "---\n".red());
|
||||||
}
|
}
|
||||||
panic!("errors differ from expected");
|
panic!("errors differ from expected");
|
||||||
}
|
}
|
||||||
|
@ -1876,18 +1876,18 @@ impl<'test> TestCx<'test> {
|
||||||
|
|
||||||
fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
|
fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
|
||||||
if self.config.verbose {
|
if self.config.verbose {
|
||||||
eprintln!("------stdout------------------------------");
|
println!("------stdout------------------------------");
|
||||||
eprintln!("{}", out);
|
println!("{}", out);
|
||||||
eprintln!("------stderr------------------------------");
|
println!("------stderr------------------------------");
|
||||||
eprintln!("{}", err);
|
println!("{}", err);
|
||||||
eprintln!("------------------------------------------");
|
println!("------------------------------------------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error(&self, err: &str) {
|
fn error(&self, err: &str) {
|
||||||
match self.revision {
|
match self.revision {
|
||||||
Some(rev) => eprintln!("\nerror in revision `{}`: {}", rev, err),
|
Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
|
||||||
None => eprintln!("\nerror: {}", err),
|
None => println!("\nerror: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,7 +1972,7 @@ impl<'test> TestCx<'test> {
|
||||||
if !self.config.has_html_tidy {
|
if !self.config.has_html_tidy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eprintln!("info: generating a diff against nightly rustdoc");
|
println!("info: generating a diff against nightly rustdoc");
|
||||||
|
|
||||||
let suffix =
|
let suffix =
|
||||||
self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
|
self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
|
||||||
|
@ -2082,7 +2082,7 @@ impl<'test> TestCx<'test> {
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(output.status.success());
|
assert!(output.status.success());
|
||||||
eprintln!("{}", String::from_utf8_lossy(&output.stdout));
|
println!("{}", String::from_utf8_lossy(&output.stdout));
|
||||||
eprintln!("{}", String::from_utf8_lossy(&output.stderr));
|
eprintln!("{}", String::from_utf8_lossy(&output.stderr));
|
||||||
} else {
|
} else {
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
@ -2482,7 +2482,7 @@ impl<'test> TestCx<'test> {
|
||||||
)"#
|
)"#
|
||||||
)
|
)
|
||||||
.replace_all(&output, |caps: &Captures<'_>| {
|
.replace_all(&output, |caps: &Captures<'_>| {
|
||||||
eprintln!("{}", &caps[0]);
|
println!("{}", &caps[0]);
|
||||||
caps[0].replace(r"\", "/")
|
caps[0].replace(r"\", "/")
|
||||||
})
|
})
|
||||||
.replace("\r\n", "\n")
|
.replace("\r\n", "\n")
|
||||||
|
@ -2581,16 +2581,16 @@ impl<'test> TestCx<'test> {
|
||||||
if let Err(err) = fs::write(&actual_path, &actual) {
|
if let Err(err) = fs::write(&actual_path, &actual) {
|
||||||
self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
|
self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
|
||||||
}
|
}
|
||||||
eprintln!("Saved the actual {stream} to {actual_path:?}");
|
println!("Saved the actual {stream} to {actual_path:?}");
|
||||||
|
|
||||||
let expected_path =
|
let expected_path =
|
||||||
expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);
|
expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);
|
||||||
|
|
||||||
if !self.config.bless {
|
if !self.config.bless {
|
||||||
if expected.is_empty() {
|
if expected.is_empty() {
|
||||||
eprintln!("normalized {}:\n{}\n", stream, actual);
|
println!("normalized {}:\n{}\n", stream, actual);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("diff of {stream}:\n");
|
println!("diff of {stream}:\n");
|
||||||
if let Some(diff_command) = self.config.diff_command.as_deref() {
|
if let Some(diff_command) = self.config.diff_command.as_deref() {
|
||||||
let mut args = diff_command.split_whitespace();
|
let mut args = diff_command.split_whitespace();
|
||||||
let name = args.next().unwrap();
|
let name = args.next().unwrap();
|
||||||
|
@ -2625,10 +2625,10 @@ impl<'test> TestCx<'test> {
|
||||||
if let Err(err) = fs::write(&expected_path, &actual) {
|
if let Err(err) = fs::write(&expected_path, &actual) {
|
||||||
self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
|
self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
|
||||||
}
|
}
|
||||||
eprintln!("Blessing the {stream} of {test_name} in {expected_path:?}");
|
println!("Blessing the {stream} of {test_name} in {expected_path:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("\nThe actual {0} differed from the expected {0}.", stream);
|
println!("\nThe actual {0} differed from the expected {0}.", stream);
|
||||||
|
|
||||||
if self.config.bless { 0 } else { 1 }
|
if self.config.bless { 0 } else { 1 }
|
||||||
}
|
}
|
||||||
|
@ -2707,7 +2707,7 @@ impl<'test> TestCx<'test> {
|
||||||
fs::create_dir_all(&incremental_dir).unwrap();
|
fs::create_dir_all(&incremental_dir).unwrap();
|
||||||
|
|
||||||
if self.config.verbose {
|
if self.config.verbose {
|
||||||
eprintln!("init_incremental_test: incremental_dir={}", incremental_dir.display());
|
println!("init_incremental_test: incremental_dir={}", incremental_dir.display());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2765,7 +2765,7 @@ impl ProcRes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!(
|
println!(
|
||||||
"status: {}\ncommand: {}\n{}\n{}\n",
|
"status: {}\ncommand: {}\n{}\n{}\n",
|
||||||
self.status,
|
self.status,
|
||||||
self.cmdline,
|
self.cmdline,
|
||||||
|
@ -2776,7 +2776,7 @@ impl ProcRes {
|
||||||
|
|
||||||
pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
|
pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
|
||||||
if let Some(e) = err {
|
if let Some(e) = err {
|
||||||
eprintln!("\nerror: {}", e);
|
println!("\nerror: {}", e);
|
||||||
}
|
}
|
||||||
self.print_info();
|
self.print_info();
|
||||||
on_failure();
|
on_failure();
|
||||||
|
|
|
@ -64,13 +64,13 @@ impl TestCx<'_> {
|
||||||
if !missing.is_empty() {
|
if !missing.is_empty() {
|
||||||
missing.sort();
|
missing.sort();
|
||||||
|
|
||||||
eprintln!("\nThese items should have been contained but were not:\n");
|
println!("\nThese items should have been contained but were not:\n");
|
||||||
|
|
||||||
for item in &missing {
|
for item in &missing {
|
||||||
eprintln!("{}", item);
|
println!("{}", item);
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("\n");
|
println!("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unexpected.is_empty() {
|
if !unexpected.is_empty() {
|
||||||
|
@ -80,24 +80,24 @@ impl TestCx<'_> {
|
||||||
sorted
|
sorted
|
||||||
};
|
};
|
||||||
|
|
||||||
eprintln!("\nThese items were contained but should not have been:\n");
|
println!("\nThese items were contained but should not have been:\n");
|
||||||
|
|
||||||
for item in sorted {
|
for item in sorted {
|
||||||
eprintln!("{}", item);
|
println!("{}", item);
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("\n");
|
println!("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !wrong_cgus.is_empty() {
|
if !wrong_cgus.is_empty() {
|
||||||
wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
|
wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
|
||||||
eprintln!("\nThe following items were assigned to wrong codegen units:\n");
|
println!("\nThe following items were assigned to wrong codegen units:\n");
|
||||||
|
|
||||||
for &(ref expected_item, ref actual_item) in &wrong_cgus {
|
for &(ref expected_item, ref actual_item) in &wrong_cgus {
|
||||||
eprintln!("{}", expected_item.name);
|
println!("{}", expected_item.name);
|
||||||
eprintln!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units));
|
println!(" expected: {}", codegen_units_to_str(&expected_item.codegen_units));
|
||||||
eprintln!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units));
|
println!(" actual: {}", codegen_units_to_str(&actual_item.codegen_units));
|
||||||
eprintln!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,7 +260,7 @@ impl TestCx<'_> {
|
||||||
cmdline,
|
cmdline,
|
||||||
};
|
};
|
||||||
if adb.kill().is_err() {
|
if adb.kill().is_err() {
|
||||||
eprintln!("Adb process is already finished.");
|
println!("Adb process is already finished.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let rust_src_root =
|
let rust_src_root =
|
||||||
|
@ -275,7 +275,7 @@ impl TestCx<'_> {
|
||||||
|
|
||||||
match self.config.gdb_version {
|
match self.config.gdb_version {
|
||||||
Some(version) => {
|
Some(version) => {
|
||||||
eprintln!("NOTE: compiletest thinks it is using GDB version {}", version);
|
println!("NOTE: compiletest thinks it is using GDB version {}", version);
|
||||||
|
|
||||||
if version > extract_gdb_version("7.4").unwrap() {
|
if version > extract_gdb_version("7.4").unwrap() {
|
||||||
// Add the directory containing the pretty printers to
|
// Add the directory containing the pretty printers to
|
||||||
|
@ -297,7 +297,7 @@ impl TestCx<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!(
|
println!(
|
||||||
"NOTE: compiletest does not know which version of \
|
"NOTE: compiletest does not know which version of \
|
||||||
GDB it is using"
|
GDB it is using"
|
||||||
);
|
);
|
||||||
|
@ -392,10 +392,10 @@ impl TestCx<'_> {
|
||||||
|
|
||||||
match self.config.lldb_version {
|
match self.config.lldb_version {
|
||||||
Some(ref version) => {
|
Some(ref version) => {
|
||||||
eprintln!("NOTE: compiletest thinks it is using LLDB version {}", version);
|
println!("NOTE: compiletest thinks it is using LLDB version {}", version);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!(
|
println!(
|
||||||
"NOTE: compiletest does not know which version of \
|
"NOTE: compiletest does not know which version of \
|
||||||
LLDB it is using"
|
LLDB it is using"
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl TestCx<'_> {
|
||||||
|
|
||||||
if !res.status.success() {
|
if !res.status.success() {
|
||||||
self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
|
self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
|
||||||
eprintln!("Rustdoc Output:");
|
println!("Rustdoc Output:");
|
||||||
proc_res.print_info();
|
proc_res.print_info();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,10 +109,10 @@ impl TestCx<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors > 0 {
|
if errors > 0 {
|
||||||
eprintln!("To update references, rerun the tests and pass the `--bless` flag");
|
println!("To update references, rerun the tests and pass the `--bless` flag");
|
||||||
let relative_path_to_file =
|
let relative_path_to_file =
|
||||||
self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
|
self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
|
||||||
eprintln!(
|
println!(
|
||||||
"To only update this specific test, also pass `--test-args {}`",
|
"To only update this specific test, also pass `--test-args {}`",
|
||||||
relative_path_to_file.display(),
|
relative_path_to_file.display(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn path_div() -> &'static str {
|
||||||
pub fn logv(config: &Config, s: String) {
|
pub fn logv(config: &Config, s: String) {
|
||||||
debug!("{}", s);
|
debug!("{}", s);
|
||||||
if config.verbose {
|
if config.verbose {
|
||||||
eprintln!("{}", s);
|
println!("{}", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
trait Answer {
|
trait Answer {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
|
|
||||||
type BuiltIn = for<'a> fn(&str);
|
type BuiltIn = for<'a> fn(&str);
|
||||||
|
|
||||||
struct Function {
|
struct Function {
|
||||||
|
|
|
@ -3936,17 +3936,8 @@ The tracking issue for this feature is: [#117693]
|
||||||
"##,
|
"##,
|
||||||
},
|
},
|
||||||
Lint {
|
Lint {
|
||||||
label: "core_pattern_type",
|
label: "pattern_type_macro",
|
||||||
description: r##"# `core_pattern_type`
|
description: r##"# `pattern_type_macro`
|
||||||
|
|
||||||
This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
"##,
|
|
||||||
},
|
|
||||||
Lint {
|
|
||||||
label: "core_pattern_types",
|
|
||||||
description: r##"# `core_pattern_types`
|
|
||||||
|
|
||||||
This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
|
This feature has no tracking issue, and is therefore likely internal to the compiler, not being intended for general use.
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ const IGNORE_UI_TEST_CHECK: &[&str] =
|
||||||
macro_rules! verbose_print {
|
macro_rules! verbose_print {
|
||||||
($verbose:expr, $($fmt:tt)*) => {
|
($verbose:expr, $($fmt:tt)*) => {
|
||||||
if $verbose {
|
if $verbose {
|
||||||
eprintln!("{}", format_args!($($fmt)*));
|
println!("{}", format_args!($($fmt)*));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut
|
||||||
// Stage 1: create list
|
// Stage 1: create list
|
||||||
let error_codes = extract_error_codes(root_path, &mut errors);
|
let error_codes = extract_error_codes(root_path, &mut errors);
|
||||||
if verbose {
|
if verbose {
|
||||||
eprintln!("Found {} error codes", error_codes.len());
|
println!("Found {} error codes", error_codes.len());
|
||||||
eprintln!("Highest error code: `{}`", error_codes.iter().max().unwrap());
|
println!("Highest error code: `{}`", error_codes.iter().max().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stage 2: check list has docs
|
// Stage 2: check list has docs
|
||||||
|
|
|
@ -158,14 +158,14 @@ pub fn check(
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for &(name, _) in gate_untested.iter() {
|
for &(name, _) in gate_untested.iter() {
|
||||||
eprintln!("Expected a gate test for the feature '{name}'.");
|
println!("Expected a gate test for the feature '{name}'.");
|
||||||
eprintln!(
|
println!(
|
||||||
"Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\
|
"Hint: create a failing test file named 'tests/ui/feature-gates/feature-gate-{}.rs',\
|
||||||
\n with its failures due to missing usage of `#![feature({})]`.",
|
\n with its failures due to missing usage of `#![feature({})]`.",
|
||||||
name.replace("_", "-"),
|
name.replace("_", "-"),
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
eprintln!(
|
println!(
|
||||||
"Hint: If you already have such a test and don't want to rename it,\
|
"Hint: If you already have such a test and don't want to rename it,\
|
||||||
\n you can also add a // gate-test-{} line to the test file.",
|
\n you can also add a // gate-test-{} line to the test file.",
|
||||||
name
|
name
|
||||||
|
@ -218,7 +218,7 @@ pub fn check(
|
||||||
|
|
||||||
lines.sort();
|
lines.sort();
|
||||||
for line in lines {
|
for line in lines {
|
||||||
eprintln!("* {line}");
|
println!("* {line}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ const ALLOWLIST: &[&str] = &[
|
||||||
"const_eval_validation_failure_note",
|
"const_eval_validation_failure_note",
|
||||||
"driver_impl_ice",
|
"driver_impl_ice",
|
||||||
"incremental_corrupt_file",
|
"incremental_corrupt_file",
|
||||||
"mir_build_pointer_pattern",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
fn check_period(filename: &str, contents: &str, bad: &mut bool) {
|
fn check_period(filename: &str, contents: &str, bad: &mut bool) {
|
||||||
|
|
|
@ -118,16 +118,16 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) {
|
||||||
// List unstable features that don't have Unstable Book sections.
|
// List unstable features that don't have Unstable Book sections.
|
||||||
// Remove the comment marker if you want the list printed.
|
// Remove the comment marker if you want the list printed.
|
||||||
/*
|
/*
|
||||||
eprintln!("Lib features without unstable book sections:");
|
println!("Lib features without unstable book sections:");
|
||||||
for feature_name in &unstable_lang_feature_names -
|
for feature_name in &unstable_lang_feature_names -
|
||||||
&unstable_book_lang_features_section_file_names {
|
&unstable_book_lang_features_section_file_names {
|
||||||
eprintln!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue);
|
println!(" * {} {:?}", feature_name, lib_features[&feature_name].tracking_issue);
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("Lang features without unstable book sections:");
|
println!("Lang features without unstable book sections:");
|
||||||
for feature_name in &unstable_lib_feature_names-
|
for feature_name in &unstable_lib_feature_names-
|
||||||
&unstable_book_lib_features_section_file_names {
|
&unstable_book_lib_features_section_file_names {
|
||||||
eprintln!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue);
|
println!(" * {} {:?}", feature_name, lang_features[&feature_name].tracking_issue);
|
||||||
}
|
}
|
||||||
// */
|
// */
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) {
|
||||||
|
|
||||||
if let Some(expected) = get_x_wrapper_version(root, cargo) {
|
if let Some(expected) = get_x_wrapper_version(root, cargo) {
|
||||||
if installed < expected {
|
if installed < expected {
|
||||||
return eprintln!(
|
return println!(
|
||||||
"Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
|
"Current version of x is {installed}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
//@ compile-flags: -Csymbol-mangling-version=v0 -Copt-level=0 --crate-type=lib
|
//@ compile-flags: -Csymbol-mangling-version=v0 -Copt-level=0 --crate-type=lib
|
||||||
|
|
||||||
#![feature(pattern_types)]
|
#![feature(pattern_types)]
|
||||||
#![feature(core_pattern_types)]
|
#![feature(pattern_type_macro)]
|
||||||
#![feature(core_pattern_type)]
|
|
||||||
|
|
||||||
use std::pat::pattern_type;
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
|
|
@ -18,17 +18,17 @@ impl Foo for Def {
|
||||||
pub fn test<A: Foo, B: Foo>(arg: EFoo) {
|
pub fn test<A: Foo, B: Foo>(arg: EFoo) {
|
||||||
match arg {
|
match arg {
|
||||||
A::X => println!("A::X"),
|
A::X => println!("A::X"),
|
||||||
//~^ error: constant pattern depends on a generic parameter
|
//~^ ERROR constant pattern cannot depend on generic parameters
|
||||||
B::X => println!("B::X"),
|
B::X => println!("B::X"),
|
||||||
//~^ error: constant pattern depends on a generic parameter
|
//~^ ERROR constant pattern cannot depend on generic parameters
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||||
//~^ ERROR constant pattern depends on a generic parameter
|
//~^ ERROR constant pattern cannot depend on generic parameters
|
||||||
let A::X = arg;
|
let A::X = arg;
|
||||||
//~^ ERROR constant pattern depends on a generic parameter
|
//~^ ERROR constant pattern cannot depend on generic parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,26 +1,57 @@
|
||||||
error[E0158]: constant pattern depends on a generic parameter
|
error[E0158]: constant pattern cannot depend on generic parameters
|
||||||
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
--> $DIR/associated-const-type-parameter-pattern.rs:20:9
|
||||||
|
|
|
|
||||||
|
LL | pub trait Foo {
|
||||||
|
| -------------
|
||||||
|
LL | const X: EFoo;
|
||||||
|
| ------------- constant defined here
|
||||||
|
...
|
||||||
|
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
|
||||||
|
| - constant depends on this generic parameter
|
||||||
|
LL | match arg {
|
||||||
LL | A::X => println!("A::X"),
|
LL | A::X => println!("A::X"),
|
||||||
| ^^^^
|
| ^^^^ `const` depends on a generic parameter
|
||||||
|
|
||||||
error[E0158]: constant pattern depends on a generic parameter
|
error[E0158]: constant pattern cannot depend on generic parameters
|
||||||
--> $DIR/associated-const-type-parameter-pattern.rs:22:9
|
--> $DIR/associated-const-type-parameter-pattern.rs:22:9
|
||||||
|
|
|
|
||||||
|
LL | pub trait Foo {
|
||||||
|
| -------------
|
||||||
|
LL | const X: EFoo;
|
||||||
|
| ------------- constant defined here
|
||||||
|
...
|
||||||
|
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo) {
|
||||||
|
| - constant depends on this generic parameter
|
||||||
|
...
|
||||||
LL | B::X => println!("B::X"),
|
LL | B::X => println!("B::X"),
|
||||||
| ^^^^
|
| ^^^^ `const` depends on a generic parameter
|
||||||
|
|
||||||
error[E0158]: constant pattern depends on a generic parameter
|
error[E0158]: constant pattern cannot depend on generic parameters
|
||||||
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
|
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
|
||||||
|
|
|
|
||||||
|
LL | pub trait Foo {
|
||||||
|
| -------------
|
||||||
|
LL | const X: EFoo;
|
||||||
|
| ------------- constant defined here
|
||||||
|
...
|
||||||
|
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||||
|
| - constant depends on this generic parameter
|
||||||
|
LL |
|
||||||
LL | let A::X = arg;
|
LL | let A::X = arg;
|
||||||
| ^^^^
|
| ^^^^ `const` depends on a generic parameter
|
||||||
|
|
||||||
error[E0158]: constant pattern depends on a generic parameter
|
error[E0158]: constant pattern cannot depend on generic parameters
|
||||||
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
|
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
|
||||||
|
|
|
|
||||||
|
LL | pub trait Foo {
|
||||||
|
| -------------
|
||||||
|
LL | const X: EFoo;
|
||||||
|
| ------------- constant defined here
|
||||||
|
...
|
||||||
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||||
| ^^^^
|
| - ^^^^ `const` depends on a generic parameter
|
||||||
|
| |
|
||||||
|
| constant depends on this generic parameter
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
fn check<const N: usize>() {
|
fn check<const N: usize>() {
|
||||||
match 1 {
|
match 1 {
|
||||||
N => {} //~ ERROR const parameters cannot be referenced in patterns
|
N => {} //~ ERROR constant parameters cannot be referenced in patterns
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
error[E0158]: const parameters cannot be referenced in patterns
|
error[E0158]: constant parameters cannot be referenced in patterns
|
||||||
--> $DIR/const-param.rs:5:9
|
--> $DIR/const-param.rs:5:9
|
||||||
|
|
|
|
||||||
|
LL | fn check<const N: usize>() {
|
||||||
|
| -------------- constant defined here
|
||||||
|
LL | match 1 {
|
||||||
LL | N => {}
|
LL | N => {}
|
||||||
| ^
|
| ^ can't be used in patterns
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
//@ run-pass
|
//@ run-pass
|
||||||
// Tests equality between supertype and subtype of a function
|
// Tests equality between supertype and subtype of a function
|
||||||
// See the issue #91636
|
// See the issue #91636
|
||||||
|
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
|
|
||||||
fn foo(_a: &str) {}
|
fn foo(_a: &str) {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
//@ run-pass
|
//@ run-pass
|
||||||
// We used to have a __rust_abi shim that resulted in duplicated symbols
|
// We used to have a __rust_abi shim that resulted in duplicated symbols
|
||||||
// whenever the item path wasn't enough to disambiguate between them.
|
// whenever the item path wasn't enough to disambiguate between them.
|
||||||
|
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = {
|
let a = {
|
||||||
extern "C" fn good() -> i32 { return 0; }
|
extern "C" fn good() -> i32 { return 0; }
|
||||||
|
|
|
@ -12,8 +12,7 @@ impl Opcode2 {
|
||||||
|
|
||||||
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
|
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
|
||||||
move |i| match msg_type {
|
move |i| match msg_type {
|
||||||
Opcode2::OP2 => unimplemented!(),
|
Opcode2::OP2 => unimplemented!(), // ok, `const` already emitted an error
|
||||||
//~^ ERROR: could not evaluate constant pattern
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,7 @@ help: you might be missing a type parameter
|
||||||
LL | pub struct Opcode2<S>(&'a S);
|
LL | pub struct Opcode2<S>(&'a S);
|
||||||
| +++
|
| +++
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
|
|
||||||
|
|
|
||||||
LL | Opcode2::OP2 => unimplemented!(),
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0261, E0412.
|
Some errors have detailed explanations: E0261, E0412.
|
||||||
For more information about an error, try `rustc --explain E0261`.
|
For more information about an error, try `rustc --explain E0261`.
|
||||||
|
|
|
@ -12,8 +12,7 @@ const NEG_NEG_128: i8 = -NEG_128; //~ ERROR constant
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match -128i8 {
|
match -128i8 {
|
||||||
NEG_NEG_128 => println!("A"),
|
NEG_NEG_128 => println!("A"), // ok, `const` error already emitted
|
||||||
//~^ ERROR could not evaluate constant pattern
|
|
||||||
_ => println!("B"),
|
_ => println!("B"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed
|
||||||
LL | const NEG_NEG_128: i8 = -NEG_128;
|
LL | const NEG_NEG_128: i8 = -NEG_128;
|
||||||
| ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
|
| ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/const-eval-overflow-2.rs:15:9
|
|
||||||
|
|
|
||||||
LL | NEG_NEG_128 => println!("A"),
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
||||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/ref_to_int_match.rs:7:14
|
|
||||||
|
|
|
||||||
LL | 10..=BAR => {},
|
|
||||||
| ^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -7,12 +7,6 @@ LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
|
||||||
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
= help: this code performed an operation that depends on the underlying bytes representing a pointer
|
||||||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/ref_to_int_match.rs:7:14
|
|
||||||
|
|
|
||||||
LL | 10..=BAR => {},
|
|
||||||
| ^^^
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -4,7 +4,7 @@ fn main() {
|
||||||
let n: Int = 40;
|
let n: Int = 40;
|
||||||
match n {
|
match n {
|
||||||
0..=10 => {},
|
0..=10 => {},
|
||||||
10..=BAR => {}, //~ ERROR could not evaluate constant pattern
|
10..=BAR => {}, // ok, `const` error already emitted
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
//@ run-pass
|
//@ run-pass
|
||||||
|
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
#![allow(unpredictable_function_pointer_comparisons)]
|
||||||
|
|
||||||
extern "C" fn foopy() {}
|
extern "C" fn foopy() {}
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,13 @@ fn main() {
|
||||||
let _ = Defaulted;
|
let _ = Defaulted;
|
||||||
match None {
|
match None {
|
||||||
consts::SOME => panic!(),
|
consts::SOME => panic!(),
|
||||||
//~^ must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `CustomEq` in a pattern
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match None {
|
match None {
|
||||||
<Defaulted as consts::AssocConst>::SOME => panic!(),
|
<Defaulted as consts::AssocConst>::SOME => panic!(),
|
||||||
//~^ must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `CustomEq` in a pattern
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,33 @@
|
||||||
error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `CustomEq` in a pattern
|
||||||
--> $DIR/cross-crate-fail.rs:11:9
|
--> $DIR/cross-crate-fail.rs:11:9
|
||||||
|
|
|
|
||||||
LL | consts::SOME => panic!(),
|
LL | consts::SOME => panic!(),
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
||||||
|
::: $DIR/auxiliary/consts.rs:1:1
|
||||||
|
|
|
||||||
|
LL | pub struct CustomEq;
|
||||||
|
| ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | pub const SOME: Option<CustomEq> = Some(CustomEq);
|
||||||
|
| -------------------------------- constant defined here
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
|
||||||
error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `CustomEq` in a pattern
|
||||||
--> $DIR/cross-crate-fail.rs:18:9
|
--> $DIR/cross-crate-fail.rs:17:9
|
||||||
|
|
|
|
||||||
LL | <Defaulted as consts::AssocConst>::SOME => panic!(),
|
LL | <Defaulted as consts::AssocConst>::SOME => panic!(),
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
||||||
|
::: $DIR/auxiliary/consts.rs:1:1
|
||||||
|
|
|
||||||
|
LL | pub struct CustomEq;
|
||||||
|
| ------------------- `CustomEq` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const SOME: Option<CustomEq> = Some(CustomEq);
|
||||||
|
| ---------------------------- constant defined here
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -1,26 +1,46 @@
|
||||||
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9
|
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:9:9
|
||||||
|
|
|
|
||||||
|
LL | const C: *const u8 = &0;
|
||||||
|
| ------------------ constant defined here
|
||||||
|
...
|
||||||
LL | C => {}
|
LL | C => {}
|
||||||
| ^
|
| ^ can't be used in patterns
|
||||||
|
|
|
||||||
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9
|
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:16:9
|
||||||
|
|
|
|
||||||
|
LL | const C_INNER: (*const u8, u8) = (C, 0);
|
||||||
|
| ------------------------------ constant defined here
|
||||||
|
...
|
||||||
LL | C_INNER => {}
|
LL | C_INNER => {}
|
||||||
| ^^^^^^^
|
| ^^^^^^^ can't be used in patterns
|
||||||
|
|
|
||||||
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9
|
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:27:9
|
||||||
|
|
|
|
||||||
|
LL | const D: *const [u8; 4] = b"abcd";
|
||||||
|
| ----------------------- constant defined here
|
||||||
|
...
|
||||||
LL | D => {}
|
LL | D => {}
|
||||||
| ^
|
| ^ can't be used in patterns
|
||||||
|
|
|
||||||
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9
|
--> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:32:9
|
||||||
|
|
|
|
||||||
|
LL | const STR: *const str = "abcd";
|
||||||
|
| --------------------- constant defined here
|
||||||
|
...
|
||||||
LL | STR => {}
|
LL | STR => {}
|
||||||
| ^^^
|
| ^^^ can't be used in patterns
|
||||||
|
|
|
||||||
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
--> $DIR/issue-44333.rs:15:9
|
--> $DIR/issue-44333.rs:15:9
|
||||||
|
|
|
|
||||||
|
LL | const FOO: Func = foo;
|
||||||
|
| --------------- constant defined here
|
||||||
|
...
|
||||||
LL | FOO => println!("foo"),
|
LL | FOO => println!("foo"),
|
||||||
| ^^^
|
| ^^^ can't be used in patterns
|
||||||
|
|
|
||||||
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
|
error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon
|
||||||
--> $DIR/issue-44333.rs:16:9
|
--> $DIR/issue-44333.rs:16:9
|
||||||
|
|
|
|
||||||
|
LL | const BAR: Func = bar;
|
||||||
|
| --------------- constant defined here
|
||||||
|
...
|
||||||
LL | BAR => println!("bar"),
|
LL | BAR => println!("bar"),
|
||||||
| ^^^
|
| ^^^ can't be used in patterns
|
||||||
|
|
|
||||||
|
= note: see https://github.com/rust-lang/rust/issues/70861 for details
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ const C: &[O<B>] = &[O::None];
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = O::None;
|
let x = O::None;
|
||||||
match &[x][..] {
|
match &[x][..] {
|
||||||
C => (), //~ERROR: the type must implement `PartialEq`
|
C => (), //~ ERROR constant of non-structural type `&[O<B>]` in a pattern
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
error: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
|
error: constant of non-structural type `&[O<B>]` in a pattern
|
||||||
--> $DIR/issue-65466.rs:14:9
|
--> $DIR/issue-65466.rs:14:9
|
||||||
|
|
|
|
||||||
|
LL | struct B;
|
||||||
|
| -------- must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
LL |
|
||||||
|
LL | const C: &[O<B>] = &[O::None];
|
||||||
|
| ---------------- constant defined here
|
||||||
|
...
|
||||||
LL | C => (),
|
LL | C => (),
|
||||||
| ^
|
| ^ constant of non-structural type
|
||||||
|
|
|
||||||
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,7 @@ const BAR_BAZ: Foo = if 42 == 42 {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
match Foo::Qux(NoEq) {
|
match Foo::Qux(NoEq) {
|
||||||
BAR_BAZ => panic!(),
|
BAR_BAZ => panic!(), //~ ERROR constant of non-structural type `Foo` in a pattern
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `Foo` in a pattern
|
||||||
--> $DIR/no-eq-branch-fail.rs:19:9
|
--> $DIR/no-eq-branch-fail.rs:19:9
|
||||||
|
|
|
|
||||||
|
LL | enum Foo {
|
||||||
|
| -------- `Foo` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const BAR_BAZ: Foo = if 42 == 42 {
|
||||||
|
| ------------------ constant defined here
|
||||||
|
...
|
||||||
LL | BAR_BAZ => panic!(),
|
LL | BAR_BAZ => panic!(),
|
||||||
| ^^^^^^^
|
| ^^^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn main() {
|
||||||
|
|
||||||
match None {
|
match None {
|
||||||
NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
||||||
//~^ ERROR must implement `PartialEq`
|
//~^ ERROR constant of non-structural type `Option<NoPartialEq>` in a pattern
|
||||||
_ => panic!("whoops"),
|
_ => panic!("whoops"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
error: to use a constant of type `Option<NoPartialEq>` in a pattern, the type must implement `PartialEq`
|
error: constant of non-structural type `Option<NoPartialEq>` in a pattern
|
||||||
--> $DIR/reject_non_partial_eq.rs:28:9
|
--> $DIR/reject_non_partial_eq.rs:28:9
|
||||||
|
|
|
|
||||||
|
LL | struct NoPartialEq(u32);
|
||||||
|
| ------------------ must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const NO_PARTIAL_EQ_NONE: Option<NoPartialEq> = None;
|
||||||
|
| --------------------------------------------- constant defined here
|
||||||
|
...
|
||||||
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"),
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
||||||
|
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,29 @@ struct NoPartialEq;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct NoDerive;
|
struct NoDerive;
|
||||||
|
//~^ NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
//~| NOTE must be annotated with `#[derive(PartialEq)]`
|
||||||
|
|
||||||
// This impl makes `NoDerive` irreflexive.
|
// This impl makes `NoDerive` irreflexive.
|
||||||
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
//~^ NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
//~| NOTE StructuralPartialEq.html for details
|
||||||
|
|
||||||
impl Eq for NoDerive { }
|
impl Eq for NoDerive { }
|
||||||
|
|
||||||
|
@ -36,65 +56,55 @@ fn main() {
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
enum Derive<X> { Some(X), None, }
|
enum Derive<X> { Some(X), None, }
|
||||||
|
|
||||||
const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
|
const ENUM: Derive<NoDerive> = Derive::Some(NoDerive); //~ NOTE constant defined here
|
||||||
match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
|
match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const FIELD: OND = TrivialEq(Some(NoDerive)).0;
|
const FIELD: OND = TrivialEq(Some(NoDerive)).0; //~ NOTE constant defined here
|
||||||
match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
|
match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const NO_DERIVE_SOME: OND = Some(NoDerive);
|
const NO_DERIVE_SOME: OND = Some(NoDerive);
|
||||||
const INDIRECT: OND = NO_DERIVE_SOME;
|
const INDIRECT: OND = NO_DERIVE_SOME; //~ NOTE constant defined here
|
||||||
match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
|
match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const TUPLE: (OND, OND) = (None, Some(NoDerive));
|
const TUPLE: (OND, OND) = (None, Some(NoDerive)); //~ NOTE constant defined here
|
||||||
match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
|
match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
|
const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); //~ NOTE constant defined here
|
||||||
match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
|
match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const ARRAY: [OND; 2] = [None, Some(NoDerive)];
|
const ARRAY: [OND; 2] = [None, Some(NoDerive)]; //~ NOTE constant defined here
|
||||||
match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
|
match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const REPEAT: [OND; 2] = [Some(NoDerive); 2];
|
const REPEAT: [OND; 2] = [Some(NoDerive); 2]; //~ NOTE constant defined here
|
||||||
match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
|
match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
trait Trait: Sized { const ASSOC: Option<Self>; }
|
trait Trait: Sized { const ASSOC: Option<Self>; } //~ NOTE constant defined here
|
||||||
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
|
impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
|
||||||
match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const BLOCK: OND = { NoDerive; Some(NoDerive) };
|
const BLOCK: OND = { NoDerive; Some(NoDerive) }; //~ NOTE constant defined here
|
||||||
match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
|
match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
const ADDR_OF: &OND = &Some(NoDerive);
|
const ADDR_OF: &OND = &Some(NoDerive); //~ NOTE constant defined here
|
||||||
match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
|
match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
|
||||||
//~^ ERROR must be annotated with `#[derive(PartialEq)]`
|
//~^ ERROR constant of non-structural type `NoDerive` in a pattern
|
||||||
//~| NOTE the traits must be derived
|
//~| NOTE constant of non-structural type
|
||||||
//~| NOTE StructuralPartialEq.html for details
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +1,173 @@
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:40:36
|
--> $DIR/reject_non_structural.rs:60:36
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const ENUM: Derive<NoDerive> = Derive::Some(NoDerive);
|
||||||
|
| ---------------------------- constant defined here
|
||||||
LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
|
LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), };
|
||||||
| ^^^^
|
| ^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:46:28
|
|
||||||
|
|
|
||||||
LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
|
|
||||||
| ^^^^^
|
|
||||||
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
|
||||||
--> $DIR/reject_non_structural.rs:53:27
|
|
||||||
|
|
|
||||||
LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
|
||||||
--> $DIR/reject_non_structural.rs:59:36
|
|
||||||
|
|
|
||||||
LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
|
|
||||||
| ^^^^^
|
|
||||||
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
|
||||||
--> $DIR/reject_non_structural.rs:65:28
|
--> $DIR/reject_non_structural.rs:65:28
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const FIELD: OND = TrivialEq(Some(NoDerive)).0;
|
||||||
|
| ---------------- constant defined here
|
||||||
|
LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), };
|
||||||
|
| ^^^^^ constant of non-structural type
|
||||||
|
|
|
||||||
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
|
--> $DIR/reject_non_structural.rs:71:27
|
||||||
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const INDIRECT: OND = NO_DERIVE_SOME;
|
||||||
|
| ------------------- constant defined here
|
||||||
|
LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), };
|
||||||
|
| ^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
||||||
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
|
--> $DIR/reject_non_structural.rs:76:36
|
||||||
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const TUPLE: (OND, OND) = (None, Some(NoDerive));
|
||||||
|
| ----------------------- constant defined here
|
||||||
|
LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), };
|
||||||
|
| ^^^^^ constant of non-structural type
|
||||||
|
|
|
||||||
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
|
--> $DIR/reject_non_structural.rs:81:28
|
||||||
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND);
|
||||||
|
| -------------------------- constant defined here
|
||||||
LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
|
LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), };
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:71:36
|
--> $DIR/reject_non_structural.rs:86:36
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const ARRAY: [OND; 2] = [None, Some(NoDerive)];
|
||||||
|
| --------------------- constant defined here
|
||||||
LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
|
LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), };
|
||||||
| ^^^^^
|
| ^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:77:33
|
--> $DIR/reject_non_structural.rs:91:33
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const REPEAT: [OND; 2] = [Some(NoDerive); 2];
|
||||||
|
| ---------------------- constant defined here
|
||||||
LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
|
LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), };
|
||||||
| ^^^^^^
|
| ^^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:84:28
|
--> $DIR/reject_non_structural.rs:97:28
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | trait Trait: Sized { const ASSOC: Option<Self>; }
|
||||||
|
| ------------------ ------------------------- constant defined here
|
||||||
|
LL | impl Trait for NoDerive { const ASSOC: Option<NoDerive> = Some(NoDerive); }
|
||||||
LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), };
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:90:28
|
--> $DIR/reject_non_structural.rs:102:28
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const BLOCK: OND = { NoDerive; Some(NoDerive) };
|
||||||
|
| ---------------- constant defined here
|
||||||
LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
|
LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), };
|
||||||
| ^^^^^
|
| ^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
|
error: constant of non-structural type `NoDerive` in a pattern
|
||||||
--> $DIR/reject_non_structural.rs:96:29
|
--> $DIR/reject_non_structural.rs:107:29
|
||||||
|
|
|
|
||||||
|
LL | struct NoDerive;
|
||||||
|
| --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
|
||||||
|
...
|
||||||
|
LL | const ADDR_OF: &OND = &Some(NoDerive);
|
||||||
|
| ------------------- constant defined here
|
||||||
LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
|
LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
|
||||||
| ^^^^^^^
|
| ^^^^^^^ constant of non-structural type
|
||||||
|
|
|
|
||||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
note: the `PartialEq` trait must be derived, manual `impl`s are not sufficient; see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
--> $DIR/reject_non_structural.rs:32:1
|
||||||
|
|
|
||||||
|
LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 10 previous errors
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn invalid() {
|
||||||
|
|
||||||
// This must be rejected here (or earlier), since it's not a valid `&bool`.
|
// This must be rejected here (or earlier), since it's not a valid `&bool`.
|
||||||
match &true {
|
match &true {
|
||||||
C => {} //~ERROR: could not evaluate constant pattern
|
C => {} // ok, `const` already emitted an error
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ fn extern_() {
|
||||||
|
|
||||||
// This must be rejected here (or earlier), since the pattern cannot be read.
|
// This must be rejected here (or earlier), since the pattern cannot be read.
|
||||||
match &0 {
|
match &0 {
|
||||||
C => {} //~ERROR: could not evaluate constant pattern
|
C => {} // ok, `const` already emitted an error
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ fn mutable() {
|
||||||
// This *must not build*, the constant we are matching against
|
// This *must not build*, the constant we are matching against
|
||||||
// could change its value!
|
// could change its value!
|
||||||
match &42 {
|
match &42 {
|
||||||
C => {} //~ERROR: could not evaluate constant pattern
|
C => {} // ok, `const` already emitted an error
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,24 +31,6 @@ LL | const C: &i32 = unsafe { &S_MUT };
|
||||||
HEX_DUMP
|
HEX_DUMP
|
||||||
}
|
}
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
error: aborting due to 3 previous errors
|
||||||
--> $DIR/const_refs_to_static_fail_invalid.rs:14:9
|
|
||||||
|
|
|
||||||
LL | C => {}
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
|
||||||
--> $DIR/const_refs_to_static_fail_invalid.rs:30:9
|
|
||||||
|
|
|
||||||
LL | C => {}
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error: could not evaluate constant pattern
|
|
||||||
--> $DIR/const_refs_to_static_fail_invalid.rs:45:9
|
|
||||||
|
|
|
||||||
LL | C => {}
|
|
||||||
| ^
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0080`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue