Auto merge of #128672 - matthiaskrgr:rollup-txf7siy, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #127655 (turn `invalid_type_param_default` into a `FutureReleaseErrorReportInDeps`) - #127907 (built-in derive: remove BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE hack and lint) - #127974 (force compiling std from source if modified) - #128309 (Implement cursors for `BTreeSet`) - #128500 (Add test for updating enum discriminant through pointer) - #128623 (Do not fire unhandled attribute assertion on multi-segment `AttributeType::Normal` attributes with builtin attribute as first segment) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
29e924841f
26 changed files with 942 additions and 343 deletions
|
@ -181,11 +181,10 @@ use std::{iter, vec};
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{
|
||||
self as ast, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, Generics,
|
||||
Mutability, PatKind, TyKind, VariantData,
|
||||
Mutability, PatKind, VariantData,
|
||||
};
|
||||
use rustc_attr as attr;
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_session::lint::builtin::BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use thin_vec::{thin_vec, ThinVec};
|
||||
|
@ -1599,52 +1598,11 @@ impl<'a> TraitDef<'a> {
|
|||
),
|
||||
);
|
||||
if is_packed {
|
||||
// In general, fields in packed structs are copied via a
|
||||
// block, e.g. `&{self.0}`. The two exceptions are `[u8]`
|
||||
// and `str` fields, which cannot be copied and also never
|
||||
// cause unaligned references. These exceptions are allowed
|
||||
// to handle the `FlexZeroSlice` type in the `zerovec`
|
||||
// crate within `icu4x-0.9.0`.
|
||||
//
|
||||
// Once use of `icu4x-0.9.0` has dropped sufficiently, this
|
||||
// exception should be removed.
|
||||
let is_simple_path = |ty: &P<ast::Ty>, sym| {
|
||||
if let TyKind::Path(None, ast::Path { segments, .. }) = &ty.kind
|
||||
&& let [seg] = segments.as_slice()
|
||||
&& seg.ident.name == sym
|
||||
&& seg.args.is_none()
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let exception = if let TyKind::Slice(ty) = &struct_field.ty.kind
|
||||
&& is_simple_path(ty, sym::u8)
|
||||
{
|
||||
Some("byte")
|
||||
} else if is_simple_path(&struct_field.ty, sym::str) {
|
||||
Some("string")
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(ty) = exception {
|
||||
cx.sess.psess.buffer_lint(
|
||||
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
sp,
|
||||
ast::CRATE_NODE_ID,
|
||||
rustc_lint_defs::BuiltinLintDiag::ByteSliceInPackedStructWithDerive {
|
||||
ty: ty.to_string(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// Wrap the expression in `{...}`, causing a copy.
|
||||
field_expr = cx.expr_block(
|
||||
cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
|
||||
);
|
||||
}
|
||||
// Fields in packed structs are wrapped in a block, e.g. `&{self.0}`,
|
||||
// causing a copy instead of a (potentially misaligned) reference.
|
||||
field_expr = cx.expr_block(
|
||||
cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
|
||||
);
|
||||
}
|
||||
cx.expr_addr_of(sp, field_expr)
|
||||
})
|
||||
|
|
|
@ -82,6 +82,9 @@ declare_features! (
|
|||
/// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
|
||||
(removed, custom_derive, "1.32.0", Some(29644),
|
||||
Some("subsumed by `#[proc_macro_derive]`")),
|
||||
/// Allows default type parameters to influence type inference.
|
||||
(removed, default_type_parameter_fallback, "CURRENT_RUSTC_VERSION", Some(27336),
|
||||
Some("never properly implemented; requires significant design work")),
|
||||
/// Allows using `#[doc(keyword = "...")]`.
|
||||
(removed, doc_keyword, "1.28.0", Some(51315),
|
||||
Some("merged into `#![feature(rustdoc_internals)]`")),
|
||||
|
|
|
@ -431,8 +431,6 @@ declare_features! (
|
|||
(unstable, custom_test_frameworks, "1.30.0", Some(50297)),
|
||||
/// Allows declarative macros 2.0 (`macro`).
|
||||
(unstable, decl_macro, "1.17.0", Some(39412)),
|
||||
/// Allows default type parameters to influence type inference.
|
||||
(unstable, default_type_parameter_fallback, "1.3.0", Some(27336)),
|
||||
/// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait
|
||||
(unstable, deprecated_safe, "1.61.0", Some(94978)),
|
||||
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
|
||||
|
|
|
@ -338,8 +338,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
if default.is_some() {
|
||||
match allow_defaults {
|
||||
Defaults::Allowed => {}
|
||||
Defaults::FutureCompatDisallowed
|
||||
if tcx.features().default_type_parameter_fallback => {}
|
||||
Defaults::FutureCompatDisallowed => {
|
||||
tcx.node_span_lint(
|
||||
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
|
||||
|
|
|
@ -543,7 +543,7 @@ fn register_builtins(store: &mut LintStore) {
|
|||
);
|
||||
store.register_removed(
|
||||
"suspicious_auto_trait_impls",
|
||||
"no longer needed, see #93367 \
|
||||
"no longer needed, see issue #93367 \
|
||||
<https://github.com/rust-lang/rust/issues/93367> for more information",
|
||||
);
|
||||
store.register_removed(
|
||||
|
@ -565,6 +565,11 @@ fn register_builtins(store: &mut LintStore) {
|
|||
"box_pointers",
|
||||
"it does not detect other kinds of allocations, and existed only for historical reasons",
|
||||
);
|
||||
store.register_removed(
|
||||
"byte_slice_in_packed_struct_with_derive",
|
||||
"converted into hard error, see issue #107457 \
|
||||
<https://github.com/rust-lang/rust/issues/107457> for more information",
|
||||
)
|
||||
}
|
||||
|
||||
fn register_internals(store: &mut LintStore) {
|
||||
|
|
|
@ -26,7 +26,6 @@ declare_lint_pass! {
|
|||
BARE_TRAIT_OBJECTS,
|
||||
BINDINGS_WITH_VARIANT_NAME,
|
||||
BREAK_WITH_LABEL_AND_LOOP,
|
||||
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
COHERENCE_LEAK_CHECK,
|
||||
CONFLICTING_REPR_HINTS,
|
||||
|
@ -1267,7 +1266,7 @@ declare_lint! {
|
|||
Deny,
|
||||
"type parameter default erroneously allowed in invalid location",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
|
||||
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
||||
reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
|
||||
};
|
||||
}
|
||||
|
@ -4315,39 +4314,6 @@ declare_lint! {
|
|||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
|
||||
/// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
|
||||
/// more built-in traits.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #[repr(packed)]
|
||||
/// #[derive(Hash)]
|
||||
/// struct FlexZeroSlice {
|
||||
/// width: u8,
|
||||
/// data: [u8],
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// This was previously accepted but is being phased out, because fields in packed structs are
|
||||
/// now required to implement `Copy` for `derive` to work. Byte slices and string slices are a
|
||||
/// temporary exception because certain crates depended on them.
|
||||
pub BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
|
||||
Warn,
|
||||
"`[u8]` or `str` used in a packed struct with `derive`",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
||||
reference: "issue #107457 <https://github.com/rust-lang/rust/issues/107457>",
|
||||
};
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments.
|
||||
///
|
||||
|
|
|
@ -116,130 +116,130 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
let attrs = self.tcx.hir().attrs(hir_id);
|
||||
for attr in attrs {
|
||||
match attr.path().as_slice() {
|
||||
[sym::diagnostic, sym::do_not_recommend] => {
|
||||
[sym::diagnostic, sym::do_not_recommend, ..] => {
|
||||
self.check_do_not_recommend(attr.span, hir_id, target)
|
||||
}
|
||||
[sym::diagnostic, sym::on_unimplemented] => {
|
||||
[sym::diagnostic, sym::on_unimplemented, ..] => {
|
||||
self.check_diagnostic_on_unimplemented(attr.span, hir_id, target)
|
||||
}
|
||||
[sym::inline] => self.check_inline(hir_id, attr, span, target),
|
||||
[sym::coverage] => self.check_coverage(attr, span, target),
|
||||
[sym::optimize] => self.check_optimize(hir_id, attr, target),
|
||||
[sym::non_exhaustive] => self.check_non_exhaustive(hir_id, attr, span, target),
|
||||
[sym::marker] => self.check_marker(hir_id, attr, span, target),
|
||||
[sym::target_feature] => {
|
||||
[sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
|
||||
[sym::coverage, ..] => self.check_coverage(attr, span, target),
|
||||
[sym::optimize, ..] => self.check_optimize(hir_id, attr, target),
|
||||
[sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
|
||||
[sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
|
||||
[sym::target_feature, ..] => {
|
||||
self.check_target_feature(hir_id, attr, span, target, attrs)
|
||||
}
|
||||
[sym::thread_local] => self.check_thread_local(attr, span, target),
|
||||
[sym::track_caller] => {
|
||||
[sym::thread_local, ..] => self.check_thread_local(attr, span, target),
|
||||
[sym::track_caller, ..] => {
|
||||
self.check_track_caller(hir_id, attr.span, attrs, span, target)
|
||||
}
|
||||
[sym::doc] => self.check_doc_attrs(
|
||||
[sym::doc, ..] => self.check_doc_attrs(
|
||||
attr,
|
||||
hir_id,
|
||||
target,
|
||||
&mut specified_inline,
|
||||
&mut doc_aliases,
|
||||
),
|
||||
[sym::no_link] => self.check_no_link(hir_id, attr, span, target),
|
||||
[sym::export_name] => self.check_export_name(hir_id, attr, span, target),
|
||||
[sym::rustc_layout_scalar_valid_range_start]
|
||||
| [sym::rustc_layout_scalar_valid_range_end] => {
|
||||
[sym::no_link, ..] => self.check_no_link(hir_id, attr, span, target),
|
||||
[sym::export_name, ..] => self.check_export_name(hir_id, attr, span, target),
|
||||
[sym::rustc_layout_scalar_valid_range_start, ..]
|
||||
| [sym::rustc_layout_scalar_valid_range_end, ..] => {
|
||||
self.check_rustc_layout_scalar_valid_range(attr, span, target)
|
||||
}
|
||||
[sym::allow_internal_unstable] => {
|
||||
[sym::allow_internal_unstable, ..] => {
|
||||
self.check_allow_internal_unstable(hir_id, attr, span, target, attrs)
|
||||
}
|
||||
[sym::debugger_visualizer] => self.check_debugger_visualizer(attr, target),
|
||||
[sym::rustc_allow_const_fn_unstable] => {
|
||||
[sym::debugger_visualizer, ..] => self.check_debugger_visualizer(attr, target),
|
||||
[sym::rustc_allow_const_fn_unstable, ..] => {
|
||||
self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::rustc_std_internal_symbol] => {
|
||||
[sym::rustc_std_internal_symbol, ..] => {
|
||||
self.check_rustc_std_internal_symbol(attr, span, target)
|
||||
}
|
||||
[sym::naked] => self.check_naked(hir_id, attr, span, target, attrs),
|
||||
[sym::rustc_never_returns_null_ptr] => {
|
||||
[sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs),
|
||||
[sym::rustc_never_returns_null_ptr, ..] => {
|
||||
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::rustc_legacy_const_generics] => {
|
||||
[sym::rustc_legacy_const_generics, ..] => {
|
||||
self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)
|
||||
}
|
||||
[sym::rustc_lint_query_instability] => {
|
||||
[sym::rustc_lint_query_instability, ..] => {
|
||||
self.check_rustc_lint_query_instability(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::rustc_lint_diagnostics] => {
|
||||
[sym::rustc_lint_diagnostics, ..] => {
|
||||
self.check_rustc_lint_diagnostics(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::rustc_lint_opt_ty] => self.check_rustc_lint_opt_ty(attr, span, target),
|
||||
[sym::rustc_lint_opt_deny_field_access] => {
|
||||
[sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target),
|
||||
[sym::rustc_lint_opt_deny_field_access, ..] => {
|
||||
self.check_rustc_lint_opt_deny_field_access(attr, span, target)
|
||||
}
|
||||
[sym::rustc_clean]
|
||||
| [sym::rustc_dirty]
|
||||
| [sym::rustc_if_this_changed]
|
||||
| [sym::rustc_then_this_would_need] => self.check_rustc_dirty_clean(attr),
|
||||
[sym::rustc_coinductive]
|
||||
| [sym::rustc_must_implement_one_of]
|
||||
| [sym::rustc_deny_explicit_impl]
|
||||
| [sym::const_trait] => self.check_must_be_applied_to_trait(attr, span, target),
|
||||
[sym::cmse_nonsecure_entry] => {
|
||||
[sym::rustc_clean, ..]
|
||||
| [sym::rustc_dirty, ..]
|
||||
| [sym::rustc_if_this_changed, ..]
|
||||
| [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr),
|
||||
[sym::rustc_coinductive, ..]
|
||||
| [sym::rustc_must_implement_one_of, ..]
|
||||
| [sym::rustc_deny_explicit_impl, ..]
|
||||
| [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target),
|
||||
[sym::cmse_nonsecure_entry, ..] => {
|
||||
self.check_cmse_nonsecure_entry(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::collapse_debuginfo] => self.check_collapse_debuginfo(attr, span, target),
|
||||
[sym::must_not_suspend] => self.check_must_not_suspend(attr, span, target),
|
||||
[sym::must_use] => self.check_must_use(hir_id, attr, target),
|
||||
[sym::rustc_pass_by_value] => self.check_pass_by_value(attr, span, target),
|
||||
[sym::rustc_allow_incoherent_impl] => {
|
||||
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
|
||||
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
|
||||
[sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
|
||||
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
|
||||
[sym::rustc_allow_incoherent_impl, ..] => {
|
||||
self.check_allow_incoherent_impl(attr, span, target)
|
||||
}
|
||||
[sym::rustc_has_incoherent_inherent_impls] => {
|
||||
[sym::rustc_has_incoherent_inherent_impls, ..] => {
|
||||
self.check_has_incoherent_inherent_impls(attr, span, target)
|
||||
}
|
||||
[sym::ffi_pure] => self.check_ffi_pure(attr.span, attrs, target),
|
||||
[sym::ffi_const] => self.check_ffi_const(attr.span, target),
|
||||
[sym::rustc_const_unstable]
|
||||
| [sym::rustc_const_stable]
|
||||
| [sym::unstable]
|
||||
| [sym::stable]
|
||||
| [sym::rustc_allowed_through_unstable_modules]
|
||||
| [sym::rustc_promotable] => self.check_stability_promotable(attr, target),
|
||||
[sym::link_ordinal] => self.check_link_ordinal(attr, span, target),
|
||||
[sym::rustc_confusables] => self.check_confusables(attr, target),
|
||||
[sym::rustc_safe_intrinsic] => {
|
||||
[sym::ffi_pure, ..] => self.check_ffi_pure(attr.span, attrs, target),
|
||||
[sym::ffi_const, ..] => self.check_ffi_const(attr.span, target),
|
||||
[sym::rustc_const_unstable, ..]
|
||||
| [sym::rustc_const_stable, ..]
|
||||
| [sym::unstable, ..]
|
||||
| [sym::stable, ..]
|
||||
| [sym::rustc_allowed_through_unstable_modules, ..]
|
||||
| [sym::rustc_promotable, ..] => self.check_stability_promotable(attr, target),
|
||||
[sym::link_ordinal, ..] => self.check_link_ordinal(attr, span, target),
|
||||
[sym::rustc_confusables, ..] => self.check_confusables(attr, target),
|
||||
[sym::rustc_safe_intrinsic, ..] => {
|
||||
self.check_rustc_safe_intrinsic(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::cold] => self.check_cold(hir_id, attr, span, target),
|
||||
[sym::link] => self.check_link(hir_id, attr, span, target),
|
||||
[sym::link_name] => self.check_link_name(hir_id, attr, span, target),
|
||||
[sym::link_section] => self.check_link_section(hir_id, attr, span, target),
|
||||
[sym::no_mangle] => self.check_no_mangle(hir_id, attr, span, target),
|
||||
[sym::deprecated] => self.check_deprecated(hir_id, attr, span, target),
|
||||
[sym::macro_use] | [sym::macro_escape] => {
|
||||
[sym::cold, ..] => self.check_cold(hir_id, attr, span, target),
|
||||
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
|
||||
[sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
|
||||
[sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target),
|
||||
[sym::no_mangle, ..] => self.check_no_mangle(hir_id, attr, span, target),
|
||||
[sym::deprecated, ..] => self.check_deprecated(hir_id, attr, span, target),
|
||||
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
|
||||
self.check_macro_use(hir_id, attr, target)
|
||||
}
|
||||
[sym::path] => self.check_generic_attr(hir_id, attr, target, Target::Mod),
|
||||
[sym::macro_export] => self.check_macro_export(hir_id, attr, target),
|
||||
[sym::ignore] | [sym::should_panic] => {
|
||||
[sym::path, ..] => self.check_generic_attr(hir_id, attr, target, Target::Mod),
|
||||
[sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
|
||||
[sym::ignore, ..] | [sym::should_panic, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Fn)
|
||||
}
|
||||
[sym::automatically_derived] => {
|
||||
[sym::automatically_derived, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Impl)
|
||||
}
|
||||
[sym::no_implicit_prelude] => {
|
||||
[sym::no_implicit_prelude, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Mod)
|
||||
}
|
||||
[sym::rustc_object_lifetime_default] => self.check_object_lifetime_default(hir_id),
|
||||
[sym::proc_macro] => {
|
||||
[sym::rustc_object_lifetime_default, ..] => self.check_object_lifetime_default(hir_id),
|
||||
[sym::proc_macro, ..] => {
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike)
|
||||
}
|
||||
[sym::proc_macro_attribute] => {
|
||||
[sym::proc_macro_attribute, ..] => {
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute);
|
||||
}
|
||||
[sym::proc_macro_derive] => {
|
||||
[sym::proc_macro_derive, ..] => {
|
||||
self.check_generic_attr(hir_id, attr, target, Target::Fn);
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
|
||||
}
|
||||
[sym::coroutine] => {
|
||||
[sym::coroutine, ..] => {
|
||||
self.check_coroutine(attr, target);
|
||||
}
|
||||
[
|
||||
|
@ -273,14 +273,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
| sym::default_lib_allocator
|
||||
| sym::start
|
||||
| sym::custom_mir,
|
||||
..
|
||||
] => {}
|
||||
[name, ..] => {
|
||||
match BUILTIN_ATTRIBUTE_MAP.get(name) {
|
||||
// checked below
|
||||
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
|
||||
Some(_) => {
|
||||
// FIXME: differentiate between unstable and internal attributes just like we do with features instead
|
||||
// of just accepting `rustc_` attributes by name. That should allow trimming the above list, too.
|
||||
// FIXME: differentiate between unstable and internal attributes just
|
||||
// like we do with features instead of just accepting `rustc_`
|
||||
// attributes by name. That should allow trimming the above list, too.
|
||||
if !name.as_str().starts_with("rustc_") {
|
||||
span_bug!(
|
||||
attr.span,
|
||||
|
|
|
@ -472,7 +472,8 @@
|
|||
# This is mostly useful for tools; if you have changes to `compiler/` or `library/` they will be ignored.
|
||||
#
|
||||
# Set this to "if-unchanged" to only download if the compiler and standard library have not been modified.
|
||||
# Set this to `true` to download unconditionally (useful if e.g. you are only changing doc-comments).
|
||||
# Set this to `true` to download unconditionally. This is useful if you are working on tools, doc-comments,
|
||||
# or library (you will be able to build the standard library without needing to build the compiler).
|
||||
#download-rustc = false
|
||||
|
||||
# Number of codegen units to use for each compiler invocation. A value of 0
|
||||
|
|
|
@ -5,7 +5,7 @@ use core::fmt::{self, Debug};
|
|||
use core::hash::{Hash, Hasher};
|
||||
use core::iter::{FusedIterator, Peekable};
|
||||
use core::mem::ManuallyDrop;
|
||||
use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
|
||||
use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub};
|
||||
|
||||
use super::map::{BTreeMap, Keys};
|
||||
use super::merge_iter::MergeIterInner;
|
||||
|
@ -1182,6 +1182,178 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
|
|||
pub const fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Returns a [`Cursor`] pointing at the gap before the smallest element
|
||||
/// greater than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap before the smallest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let cursor = set.lower_bound(Bound::Included(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&1));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&2));
|
||||
///
|
||||
/// let cursor = set.lower_bound(Bound::Excluded(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let cursor = set.lower_bound(Bound::Unbounded);
|
||||
/// assert_eq!(cursor.peek_prev(), None);
|
||||
/// assert_eq!(cursor.peek_next(), Some(&1));
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn lower_bound<Q: ?Sized>(&self, bound: Bound<&Q>) -> Cursor<'_, T>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
Cursor { inner: self.map.lower_bound(bound) }
|
||||
}
|
||||
|
||||
/// Returns a [`CursorMut`] pointing at the gap before the smallest element
|
||||
/// greater than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap before the smallest element greater than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap before the smallest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let mut set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let mut cursor = set.lower_bound_mut(Bound::Included(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&1));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&2));
|
||||
///
|
||||
/// let mut cursor = set.lower_bound_mut(Bound::Excluded(&2));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let mut cursor = set.lower_bound_mut(Bound::Unbounded);
|
||||
/// assert_eq!(cursor.peek_prev(), None);
|
||||
/// assert_eq!(cursor.peek_next(), Some(&1));
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn lower_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
CursorMut { inner: self.map.lower_bound_mut(bound) }
|
||||
}
|
||||
|
||||
/// Returns a [`Cursor`] pointing at the gap after the greatest element
|
||||
/// smaller than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap after the greatest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let cursor = set.upper_bound(Bound::Included(&3));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&3));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&4));
|
||||
///
|
||||
/// let cursor = set.upper_bound(Bound::Excluded(&3));
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let cursor = set.upper_bound(Bound::Unbounded);
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&4));
|
||||
/// assert_eq!(cursor.peek_next(), None);
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn upper_bound<Q: ?Sized>(&self, bound: Bound<&Q>) -> Cursor<'_, T>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
Cursor { inner: self.map.upper_bound(bound) }
|
||||
}
|
||||
|
||||
/// Returns a [`CursorMut`] pointing at the gap after the greatest element
|
||||
/// smaller than the given bound.
|
||||
///
|
||||
/// Passing `Bound::Included(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than or equal to `x`.
|
||||
///
|
||||
/// Passing `Bound::Excluded(x)` will return a cursor pointing to the
|
||||
/// gap after the greatest element smaller than `x`.
|
||||
///
|
||||
/// Passing `Bound::Unbounded` will return a cursor pointing to the
|
||||
/// gap after the greatest element in the set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_cursors)]
|
||||
///
|
||||
/// use std::collections::BTreeSet;
|
||||
/// use std::ops::Bound;
|
||||
///
|
||||
/// let mut set = BTreeSet::from([1, 2, 3, 4]);
|
||||
///
|
||||
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Included(&3)) };
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&3));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&4));
|
||||
///
|
||||
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Excluded(&3)) };
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&2));
|
||||
/// assert_eq!(cursor.peek_next(), Some(&3));
|
||||
///
|
||||
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Unbounded) };
|
||||
/// assert_eq!(cursor.peek_prev(), Some(&4));
|
||||
/// assert_eq!(cursor.peek_next(), None);
|
||||
/// ```
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
|
||||
where
|
||||
T: Borrow<Q> + Ord,
|
||||
Q: Ord,
|
||||
{
|
||||
CursorMut { inner: self.map.upper_bound_mut(bound) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1816,5 +1988,414 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
|
|||
#[stable(feature = "fused", since = "1.26.0")]
|
||||
impl<T: Ord> FusedIterator for Union<'_, T> {}
|
||||
|
||||
/// A cursor over a `BTreeSet`.
|
||||
///
|
||||
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth.
|
||||
///
|
||||
/// Cursors always point to a gap between two elements in the set, and can
|
||||
/// operate on the two immediately adjacent elements.
|
||||
///
|
||||
/// A `Cursor` is created with the [`BTreeSet::lower_bound`] and [`BTreeSet::upper_bound`] methods.
|
||||
#[derive(Clone)]
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub struct Cursor<'a, K: 'a> {
|
||||
inner: super::map::Cursor<'a, K, SetValZST>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
impl<K: Debug> Debug for Cursor<'_, K> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("Cursor")
|
||||
}
|
||||
}
|
||||
|
||||
/// A cursor over a `BTreeSet` with editing operations.
|
||||
///
|
||||
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can
|
||||
/// safely mutate the set during iteration. This is because the lifetime of its yielded
|
||||
/// references is tied to its own lifetime, instead of just the underlying map. This means
|
||||
/// cursors cannot yield multiple elements at once.
|
||||
///
|
||||
/// Cursors always point to a gap between two elements in the set, and can
|
||||
/// operate on the two immediately adjacent elements.
|
||||
///
|
||||
/// A `CursorMut` is created with the [`BTreeSet::lower_bound_mut`] and [`BTreeSet::upper_bound_mut`]
|
||||
/// methods.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub struct CursorMut<'a, K: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A = Global>
|
||||
{
|
||||
inner: super::map::CursorMut<'a, K, SetValZST, A>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
impl<K: Debug, A> Debug for CursorMut<'_, K, A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("CursorMut")
|
||||
}
|
||||
}
|
||||
|
||||
/// A cursor over a `BTreeSet` with editing operations, and which allows
|
||||
/// mutating elements.
|
||||
///
|
||||
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can
|
||||
/// safely mutate the set during iteration. This is because the lifetime of its yielded
|
||||
/// references is tied to its own lifetime, instead of just the underlying set. This means
|
||||
/// cursors cannot yield multiple elements at once.
|
||||
///
|
||||
/// Cursors always point to a gap between two elements in the set, and can
|
||||
/// operate on the two immediately adjacent elements.
|
||||
///
|
||||
/// A `CursorMutKey` is created from a [`CursorMut`] with the
|
||||
/// [`CursorMut::with_mutable_key`] method.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Since this cursor allows mutating elements, you must ensure that the
|
||||
/// `BTreeSet` invariants are maintained. Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub struct CursorMutKey<
|
||||
'a,
|
||||
K: 'a,
|
||||
#[unstable(feature = "allocator_api", issue = "32838")] A = Global,
|
||||
> {
|
||||
inner: super::map::CursorMutKey<'a, K, SetValZST, A>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
impl<K: Debug, A> Debug for CursorMutKey<'_, K, A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("CursorMutKey")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K> Cursor<'a, K> {
|
||||
/// Advances the cursor to the next gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the end of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn next(&mut self) -> Option<&'a K> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Advances the cursor to the previous gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the start of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn prev(&mut self) -> Option<&'a K> {
|
||||
self.inner.prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to next element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the end of the set then `None` is returned
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_next(&self) -> Option<&'a K> {
|
||||
self.inner.peek_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the previous element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the start of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_prev(&self) -> Option<&'a K> {
|
||||
self.inner.peek_prev().map(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, A> CursorMut<'a, T, A> {
|
||||
/// Advances the cursor to the next gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the end of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn next(&mut self) -> Option<&T> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Advances the cursor to the previous gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the start of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn prev(&mut self) -> Option<&T> {
|
||||
self.inner.prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the next element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the end of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_next(&mut self) -> Option<&T> {
|
||||
self.inner.peek_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the previous element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the start of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_prev(&mut self) -> Option<&T> {
|
||||
self.inner.peek_prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a read-only cursor pointing to the same location as the
|
||||
/// `CursorMut`.
|
||||
///
|
||||
/// The lifetime of the returned `Cursor` is bound to that of the
|
||||
/// `CursorMut`, which means it cannot outlive the `CursorMut` and that the
|
||||
/// `CursorMut` is frozen for the lifetime of the `Cursor`.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn as_cursor(&self) -> Cursor<'_, T> {
|
||||
Cursor { inner: self.inner.as_cursor() }
|
||||
}
|
||||
|
||||
/// Converts the cursor into a [`CursorMutKey`], which allows mutating
|
||||
/// elements in the tree.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Since this cursor allows mutating elements, you must ensure that the
|
||||
/// `BTreeSet` invariants are maintained. Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn with_mutable_key(self) -> CursorMutKey<'a, T, A> {
|
||||
CursorMutKey { inner: unsafe { self.inner.with_mutable_key() } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, A> CursorMutKey<'a, T, A> {
|
||||
/// Advances the cursor to the next gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the end of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn next(&mut self) -> Option<&mut T> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Advances the cursor to the previous gap, returning the element that it
|
||||
/// moved over.
|
||||
///
|
||||
/// If the cursor is already at the start of the set then `None` is returned
|
||||
/// and the cursor is not moved.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn prev(&mut self) -> Option<&mut T> {
|
||||
self.inner.prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the next element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the end of the set then `None` is returned
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_next(&mut self) -> Option<&mut T> {
|
||||
self.inner.peek_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a reference to the previous element without moving the cursor.
|
||||
///
|
||||
/// If the cursor is at the start of the set then `None` is returned.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn peek_prev(&mut self) -> Option<&mut T> {
|
||||
self.inner.peek_prev().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Returns a read-only cursor pointing to the same location as the
|
||||
/// `CursorMutKey`.
|
||||
///
|
||||
/// The lifetime of the returned `Cursor` is bound to that of the
|
||||
/// `CursorMutKey`, which means it cannot outlive the `CursorMutKey` and that the
|
||||
/// `CursorMutKey` is frozen for the lifetime of the `Cursor`.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn as_cursor(&self) -> Cursor<'_, T> {
|
||||
Cursor { inner: self.inner.as_cursor() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_after_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_after_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_before_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_before_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_after(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_before(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Removes the next element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (before the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_next(&mut self) -> Option<T> {
|
||||
self.inner.remove_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_prev(&mut self) -> Option<T> {
|
||||
self.inner.remove_prev().map(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The key of the newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_after_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_after_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that the `BTreeSet` invariants are maintained.
|
||||
/// Specifically:
|
||||
///
|
||||
/// * The newly inserted element must be unique in the tree.
|
||||
/// * All elements in the tree must remain in sorted order.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub unsafe fn insert_before_unchecked(&mut self, value: T) {
|
||||
unsafe { self.inner.insert_before_unchecked(value, SetValZST) }
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap before the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_after(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Inserts a new element into the set in the gap that the
|
||||
/// cursor is currently pointing to.
|
||||
///
|
||||
/// After the insertion the cursor will be pointing at the gap after the
|
||||
/// newly inserted element.
|
||||
///
|
||||
/// If the inserted element is not greater than the element before the
|
||||
/// cursor (if any), or if it not less than the element after the cursor (if
|
||||
/// any), then an [`UnorderedKeyError`] is returned since this would
|
||||
/// invalidate the [`Ord`] invariant between the elements of the set.
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
|
||||
self.inner.insert_before(value, SetValZST)
|
||||
}
|
||||
|
||||
/// Removes the next element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (before the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_next(&mut self) -> Option<T> {
|
||||
self.inner.remove_next().map(|(k, _)| k)
|
||||
}
|
||||
|
||||
/// Removes the precending element from the `BTreeSet`.
|
||||
///
|
||||
/// The element that was removed is returned. The cursor position is
|
||||
/// unchanged (after the removed element).
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub fn remove_prev(&mut self) -> Option<T> {
|
||||
self.inner.remove_prev().map(|(k, _)| k)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "btree_cursors", issue = "107540")]
|
||||
pub use super::map::UnorderedKeyError;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -26,7 +26,8 @@ use crate::core::builder::{
|
|||
use crate::core::config::{DebuginfoLevel, LlvmLibunwind, RustcLto, TargetSelection};
|
||||
use crate::utils::exec::command;
|
||||
use crate::utils::helpers::{
|
||||
exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date,
|
||||
self, exe, get_clang_cl_resource_dir, get_closest_merge_base_commit, is_debug_info, is_dylib,
|
||||
symlink_dir, t, up_to_date,
|
||||
};
|
||||
use crate::{CLang, Compiler, DependencyType, GitRepo, Mode, LLVM_TOOLS};
|
||||
|
||||
|
@ -114,21 +115,43 @@ impl Step for Std {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
// When downloading stage1, the standard library has already been copied to the sysroot, so
|
||||
// there's no need to rebuild it.
|
||||
let builder = run.builder;
|
||||
run.crate_or_deps("sysroot")
|
||||
.path("library")
|
||||
.lazy_default_condition(Box::new(|| !builder.download_rustc()))
|
||||
run.crate_or_deps("sysroot").path("library")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let crates = std_crates_for_run_make(&run);
|
||||
let builder = run.builder;
|
||||
|
||||
// Force compilation of the standard library from source if the `library` is modified. This allows
|
||||
// library team to compile the standard library without needing to compile the compiler with
|
||||
// the `rust.download-rustc=true` option.
|
||||
let force_recompile =
|
||||
if builder.rust_info().is_managed_git_subrepository() && builder.download_rustc() {
|
||||
let closest_merge_commit = get_closest_merge_base_commit(
|
||||
Some(&builder.src),
|
||||
&builder.config.git_config(),
|
||||
&builder.config.stage0_metadata.config.git_merge_commit_email,
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Check if `library` has changes (returns false otherwise)
|
||||
!t!(helpers::git(Some(&builder.src))
|
||||
.args(["diff-index", "--quiet", &closest_merge_commit])
|
||||
.arg("--")
|
||||
.arg(builder.src.join("library"))
|
||||
.as_command_mut()
|
||||
.status())
|
||||
.success()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
run.builder.ensure(Std {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
||||
target: run.target,
|
||||
crates,
|
||||
force_recompile: false,
|
||||
force_recompile,
|
||||
extra_rust_args: &[],
|
||||
is_for_mir_opt_tests: false,
|
||||
});
|
||||
|
|
19
tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
Normal file
19
tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
//@ compile-flags: -O
|
||||
//@ min-llvm-version: 19
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub enum State {
|
||||
A([u8; 753]),
|
||||
B([u8; 753]),
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @update
|
||||
#[no_mangle]
|
||||
pub unsafe fn update(s: *mut State) {
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: store i8
|
||||
// CHECK-NEXT: ret
|
||||
let State::A(v) = s.read() else { std::hint::unreachable_unchecked() };
|
||||
s.write(State::B(v));
|
||||
}
|
58
tests/ui/attributes/check-builtin-attr-ice.rs
Normal file
58
tests/ui/attributes/check-builtin-attr-ice.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
//! Regression test for #128622.
|
||||
//!
|
||||
//! PR #128581 introduced an assertion that all builtin attributes are actually checked via
|
||||
//! `CheckAttrVisitor` and aren't accidentally usable on completely unrelated HIR nodes.
|
||||
//! Unfortunately, the check had correctness problems.
|
||||
//!
|
||||
//! The match on attribute path segments looked like
|
||||
//!
|
||||
//! ```rs,ignore
|
||||
//! [sym::should_panic] => /* check is implemented */
|
||||
//! match BUILTIN_ATTRIBUTE_MAP.get(name) {
|
||||
//! // checked below
|
||||
//! Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
|
||||
//! Some(_) => {
|
||||
//! if !name.as_str().starts_with("rustc_") {
|
||||
//! span_bug!(
|
||||
//! attr.span,
|
||||
//! "builtin attribute {name:?} not handled by `CheckAttrVisitor`"
|
||||
//! )
|
||||
//! }
|
||||
//! }
|
||||
//! None => (),
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! However, it failed to account for edge cases such as an attribute whose:
|
||||
//!
|
||||
//! 1. path segments *starts* with a builtin attribute such as `should_panic`
|
||||
//! 2. which does not start with `rustc_`, and
|
||||
//! 3. is also an `AttributeType::Normal` attribute upon registration with the builtin attribute map
|
||||
//!
|
||||
//! These conditions when all satisfied cause the span bug to be issued for e.g.
|
||||
//! `#[should_panic::skip]` because the `[sym::should_panic]` arm is not matched (since it's
|
||||
//! `[sym::should_panic, sym::skip]`).
|
||||
//!
|
||||
//! This test checks that the span bug is not fired for such cases.
|
||||
//!
|
||||
//! issue: rust-lang/rust#128622
|
||||
|
||||
// Notably, `should_panic` is a `AttributeType::Normal` attribute that is checked separately.
|
||||
|
||||
struct Foo {
|
||||
#[should_panic::skip]
|
||||
//~^ ERROR failed to resolve
|
||||
pub field: u8,
|
||||
|
||||
#[should_panic::a::b::c]
|
||||
//~^ ERROR failed to resolve
|
||||
pub field2: u8,
|
||||
}
|
||||
|
||||
fn foo() {}
|
||||
|
||||
fn main() {
|
||||
#[deny::skip]
|
||||
//~^ ERROR failed to resolve
|
||||
foo();
|
||||
}
|
21
tests/ui/attributes/check-builtin-attr-ice.stderr
Normal file
21
tests/ui/attributes/check-builtin-attr-ice.stderr
Normal file
|
@ -0,0 +1,21 @@
|
|||
error[E0433]: failed to resolve: use of undeclared crate or module `should_panic`
|
||||
--> $DIR/check-builtin-attr-ice.rs:43:7
|
||||
|
|
||||
LL | #[should_panic::skip]
|
||||
| ^^^^^^^^^^^^ use of undeclared crate or module `should_panic`
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared crate or module `should_panic`
|
||||
--> $DIR/check-builtin-attr-ice.rs:47:7
|
||||
|
|
||||
LL | #[should_panic::a::b::c]
|
||||
| ^^^^^^^^^^^^ use of undeclared crate or module `should_panic`
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared crate or module `deny`
|
||||
--> $DIR/check-builtin-attr-ice.rs:55:7
|
||||
|
|
||||
LL | #[deny::skip]
|
||||
| ^^^^ use of undeclared crate or module `deny`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
|
@ -22,25 +22,22 @@ struct Y(usize);
|
|||
struct X(Y);
|
||||
//~^ ERROR cannot move out of `self` which is behind a shared reference
|
||||
|
||||
// This is currently allowed, but will be phased out at some point. From
|
||||
// `zerovec` within icu4x-0.9.0.
|
||||
#[derive(Debug)]
|
||||
#[repr(packed)]
|
||||
struct FlexZeroSlice {
|
||||
width: u8,
|
||||
data: [u8],
|
||||
//~^ WARNING byte slice in a packed struct that derives a built-in trait
|
||||
//~^^ this was previously accepted
|
||||
//~^ ERROR cannot move
|
||||
//~| ERROR cannot move
|
||||
}
|
||||
|
||||
// Again, currently allowed, but will be phased out.
|
||||
#[derive(Debug)]
|
||||
#[repr(packed)]
|
||||
struct WithStr {
|
||||
width: u8,
|
||||
data: str,
|
||||
//~^ WARNING string slice in a packed struct that derives a built-in trait
|
||||
//~^^ this was previously accepted
|
||||
//~^ ERROR cannot move
|
||||
//~| ERROR cannot move
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,32 +1,3 @@
|
|||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:31:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: [u8],
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: string slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:41:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: str,
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0507]: cannot move out of `self` which is behind a shared reference
|
||||
--> $DIR/deriving-with-repr-packed.rs:22:10
|
||||
|
|
||||
|
@ -47,38 +18,43 @@ LL | struct X(Y);
|
|||
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 1 previous error; 2 warnings emitted
|
||||
error[E0161]: cannot move a value of type `[u8]`
|
||||
--> $DIR/deriving-with-repr-packed.rs:29:5
|
||||
|
|
||||
LL | data: [u8],
|
||||
| ^^^^^^^^^^ the size of `[u8]` cannot be statically determined
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:31:5
|
||||
error[E0507]: cannot move out of `self.data` which is behind a shared reference
|
||||
--> $DIR/deriving-with-repr-packed.rs:29:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: [u8],
|
||||
| ^^^^^^^^^^
|
||||
| ^^^^^^^^^^ move occurs because `self.data` has type `[u8]`, which does not implement the `Copy` trait
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
warning: string slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-with-repr-packed.rs:41:5
|
||||
error[E0161]: cannot move a value of type `str`
|
||||
--> $DIR/deriving-with-repr-packed.rs:38:5
|
||||
|
|
||||
LL | data: str,
|
||||
| ^^^^^^^^^ the size of `str` cannot be statically determined
|
||||
|
||||
error[E0507]: cannot move out of `self.data` which is behind a shared reference
|
||||
--> $DIR/deriving-with-repr-packed.rs:38:5
|
||||
|
|
||||
LL | #[derive(Debug)]
|
||||
| ----- in this derive macro expansion
|
||||
...
|
||||
LL | data: str,
|
||||
| ^^^^^^^^^
|
||||
| ^^^^^^^^^ move occurs because `self.data` has type `str`, which does not implement the `Copy` trait
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0161, E0507.
|
||||
For more information about an error, try `rustc --explain E0161`.
|
||||
|
|
|
@ -73,16 +73,6 @@ impl Copy for PackedManualCopy {}
|
|||
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct Unsized([u32]);
|
||||
|
||||
// A packed struct with an unsized `[u8]` field. This is currently allowed, but
|
||||
// causes a warning and will be phased out at some point.
|
||||
#[derive(Debug, Hash)]
|
||||
#[repr(packed)]
|
||||
struct PackedUnsizedU8([u8]);
|
||||
//~^ WARNING byte slice in a packed struct that derives a built-in trait
|
||||
//~^^ WARNING byte slice in a packed struct that derives a built-in trait
|
||||
//~^^^ this was previously accepted
|
||||
//~^^^^ this was previously accepted
|
||||
|
||||
trait Trait {
|
||||
type A;
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ----- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ---- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: this warning originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ----- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
warning: byte slice in a packed struct that derives a built-in trait
|
||||
--> $DIR/deriving-all-codegen.rs:80:24
|
||||
|
|
||||
LL | #[derive(Debug, Hash)]
|
||||
| ---- in this derive macro expansion
|
||||
LL | #[repr(packed)]
|
||||
LL | struct PackedUnsizedU8([u8]);
|
||||
| ^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
|
||||
= help: consider implementing the trait by hand, or remove the `packed` attribute
|
||||
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
|
||||
= note: this warning originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
@ -516,26 +516,6 @@ impl ::core::cmp::Ord for Unsized {
|
|||
}
|
||||
}
|
||||
|
||||
// A packed struct with an unsized `[u8]` field. This is currently allowed, but
|
||||
// causes a warning and will be phased out at some point.
|
||||
#[repr(packed)]
|
||||
struct PackedUnsizedU8([u8]);
|
||||
#[automatically_derived]
|
||||
impl ::core::fmt::Debug for PackedUnsizedU8 {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||
::core::fmt::Formatter::debug_tuple_field1_finish(f,
|
||||
"PackedUnsizedU8", &&self.0)
|
||||
}
|
||||
}
|
||||
#[automatically_derived]
|
||||
impl ::core::hash::Hash for PackedUnsizedU8 {
|
||||
#[inline]
|
||||
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
|
||||
::core::hash::Hash::hash(&self.0, state)
|
||||
}
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
type A;
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/feature-gate-default_type_parameter_fallback.rs:3:8
|
||||
|
|
||||
LL | fn avg<T=i32>(_: T) {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/feature-gate-default_type_parameter_fallback.rs:8:6
|
||||
|
|
||||
LL | impl<T=i32> S<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -433,3 +433,25 @@ error: aborting due to 50 previous errors
|
|||
|
||||
Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0599, E0658, E0666.
|
||||
For more information about an error, try `rustc --explain E0053`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/where-allowed.rs:239:7
|
||||
|
|
||||
LL | impl <T = impl Debug> T {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/where-allowed.rs:246:36
|
||||
|
|
||||
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![feature(default_type_parameter_fallback)]
|
||||
|
||||
fn avg<T=T::Item>(_: T) {}
|
||||
//~^ ERROR generic parameters with a default cannot use forward declared identifiers
|
||||
//~| ERROR defaults for type parameters
|
||||
//~| WARN previously accepted
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,9 +1,30 @@
|
|||
error[E0128]: generic parameters with a default cannot use forward declared identifiers
|
||||
--> $DIR/issue-26812.rs:3:10
|
||||
--> $DIR/issue-26812.rs:1:10
|
||||
|
|
||||
LL | fn avg<T=T::Item>(_: T) {}
|
||||
| ^^^^^^^ defaulted generic parameters cannot be forward declared
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/issue-26812.rs:1:8
|
||||
|
|
||||
LL | fn avg<T=T::Item>(_: T) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0128`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/issue-26812.rs:1:8
|
||||
|
|
||||
LL | fn avg<T=T::Item>(_: T) {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
|
|
@ -72,3 +72,14 @@ error: aborting due to 8 previous errors
|
|||
|
||||
Some errors have detailed explanations: E0106, E0214, E0308, E0770.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/unusual-rib-combinations.rs:15:6
|
||||
|
|
||||
LL | fn c<T = u8()>() {}
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
|
|
|
@ -12,3 +12,13 @@ LL | foo::<T, U>();
|
|||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
warning: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/unbounded-type-param-in-fn-with-assoc-type.rs:3:11
|
||||
|
|
||||
LL | fn foo<T, U = u64>() -> (T, U) {
|
||||
| ^^^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
|
|
43
tests/ui/type/default_type_parameter_in_fn_or_impl.stderr
Normal file
43
tests/ui/type/default_type_parameter_in_fn_or_impl.stderr
Normal file
|
@ -0,0 +1,43 @@
|
|||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:3:8
|
||||
|
|
||||
LL | fn avg<T=i32>(_: T) {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:8:6
|
||||
|
|
||||
LL | impl<T=i32> S<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:3:8
|
||||
|
|
||||
LL | fn avg<T=i32>(_: T) {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
||||
Future breakage diagnostic:
|
||||
error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
|
||||
--> $DIR/default_type_parameter_in_fn_or_impl.rs:8:6
|
||||
|
|
||||
LL | impl<T=i32> S<T> {}
|
||||
| ^^^^^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
|
||||
= note: `#[deny(invalid_type_param_default)]` on by default
|
||||
|
Loading…
Add table
Reference in a new issue