authorbors <bors@rust-lang.org> 2026-04-25 21:08:31 UTC
committerbors <bors@rust-lang.org> 2026-04-25 21:08:31 UTC
log68ffae46b581747074413e4242ab0c6ecc4db4a9
tree56361fbb39d71f33f74513358b91f9a5182292e2
parent9838411cb723b60dc62b1625751075c4d933b992
parent3b59d9d58e679ff0499619f3e50b4d56d21df699

Auto merge of #155796 - JonathanBrouwer:rollup-uKXw9ZB, r=JonathanBrouwer

Rollup of 9 pull requests Successful merges: - rust-lang/rust#146181 (Add intrinsic for launch-sized workgroup memory on GPUs) - rust-lang/rust#154803 (Fix ICE from cfg_attr_trace ) - rust-lang/rust#155065 (Error on invalid macho section specifier) - rust-lang/rust#155485 (Add an edge-case test for `--remap-path-prefix` for `rustc` & `rustdoc`) - rust-lang/rust#155659 (cleanup, restructure and merge `tests/ui/deriving` into `tests/ui/derives`) - rust-lang/rust#155676 ( Reject implementing const Drop for types that are not const `Destruct` already) - rust-lang/rust#155696 (Add a higher-level API for parsing attributes) - rust-lang/rust#155769 (triagebot.toml: Ping Enselic when tests/debuginfo/basic-stepping.rs changes) - rust-lang/rust#155783 (Do not suggest internal cfg trace attributes)

257 files changed, 6318 insertions(+), 5952 deletions(-)

compiler/rustc_abi/src/lib.rs+3
......@@ -1753,6 +1753,9 @@ pub struct AddressSpace(pub u32);
17531753impl AddressSpace {
17541754 /// LLVM's `0` address space.
17551755 pub const ZERO: Self = AddressSpace(0);
1756 /// The address space for workgroup memory on nvptx and amdgpu.
1757 /// See e.g. the `gpu_launch_sized_workgroup_mem` intrinsic for details.
1758 pub const GPU_WORKGROUP: Self = AddressSpace(3);
17561759}
17571760
17581761/// How many scalable vectors are in a `BackendRepr::ScalableVector`?
compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs+1-1
......@@ -81,7 +81,7 @@ fn parse_unstable<S: Stage>(
8181) -> impl IntoIterator<Item = Symbol> {
8282 let mut res = Vec::new();
8383
84 let Some(list) = args.list() else {
84 let Some(list) = args.as_list() else {
8585 cx.emit_err(session_diagnostics::ExpectsFeatureList {
8686 span: cx.attr_span,
8787 name: symbol.to_ident_string(),
compiler/rustc_attr_parsing/src/attributes/cfg.rs+4-8
......@@ -44,13 +44,9 @@ pub fn parse_cfg<S: Stage>(
4444 cx: &mut AcceptContext<'_, '_, S>,
4545 args: &ArgParser,
4646) -> Option<CfgEntry> {
47 let ArgParser::List(list) = args else {
48 let attr_span = cx.attr_span;
49 cx.adcx().expected_list(attr_span, args);
50 return None;
51 };
47 let list = cx.expect_list(args, cx.attr_span)?;
5248
53 let Some(single) = list.single() else {
49 let Some(single) = list.as_single() else {
5450 let target = cx.target;
5551 let mut adcx = cx.adcx();
5652 if list.is_empty() {
......@@ -93,7 +89,7 @@ pub fn parse_cfg_entry<S: Stage>(
9389 MetaItemOrLitParser::MetaItemParser(meta) => match meta.args() {
9490 ArgParser::List(list) => match meta.path().word_sym() {
9591 Some(sym::not) => {
96 let Some(single) = list.single() else {
92 let Some(single) = list.as_single() else {
9793 return Err(cx.adcx().expected_single_argument(list.span, list.len()));
9894 };
9995 CfgEntry::Not(Box::new(parse_cfg_entry(cx, single)?), list.span)
......@@ -136,7 +132,7 @@ fn parse_cfg_entry_version<S: Stage>(
136132 meta_span: Span,
137133) -> Result<CfgEntry, ErrorGuaranteed> {
138134 try_gate_cfg(sym::version, meta_span, cx.sess(), cx.features_option());
139 let Some(version) = list.single() else {
135 let Some(version) = list.as_single() else {
140136 return Err(
141137 cx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral { span: list.span })
142138 );
compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs+6-17
......@@ -24,7 +24,7 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
2424 const TEMPLATE: AttributeTemplate = template!(List: &["size", "speed", "none"]);
2525
2626 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
27 let single = cx.single_element_list(args, cx.attr_span)?;
27 let single = cx.expect_single_element_list(args, cx.attr_span)?;
2828
2929 let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) {
3030 Some(sym::size) => OptimizeAttr::Size,
......@@ -75,7 +75,7 @@ impl<S: Stage> SingleAttributeParser<S> for CoverageParser {
7575 const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::off, sym::on]);
7676
7777 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
78 let arg = cx.single_element_list(args, cx.attr_span)?;
78 let arg = cx.expect_single_element_list(args, cx.attr_span)?;
7979
8080 let mut fail_incorrect_argument =
8181 |span| cx.adcx().expected_specific_argument(span, &[sym::on, sym::off]);
......@@ -371,8 +371,7 @@ impl<S: Stage> AttributeParser<S> for UsedParser {
371371 let used_by = match args {
372372 ArgParser::NoArgs => UsedBy::Default,
373373 ArgParser::List(list) => {
374 let Some(l) = list.single() else {
375 cx.adcx().expected_single_argument(list.span, list.len());
374 let Some(l) = cx.expect_single(list) else {
376375 return;
377376 };
378377
......@@ -463,9 +462,7 @@ fn parse_tf_attribute<S: Stage>(
463462 args: &ArgParser,
464463) -> impl IntoIterator<Item = (Symbol, Span)> {
465464 let mut features = Vec::new();
466 let ArgParser::List(list) = args else {
467 let attr_span = cx.attr_span;
468 cx.adcx().expected_list(attr_span, args);
465 let Some(list) = cx.expect_list(args, cx.attr_span) else {
469466 return features;
470467 };
471468 if list.is_empty() {
......@@ -588,11 +585,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
588585 ]);
589586
590587 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
591 let Some(list) = args.list() else {
592 let attr_span = cx.attr_span;
593 cx.adcx().expected_list(attr_span, args);
594 return None;
595 };
588 let list = cx.expect_list(args, cx.attr_span)?;
596589
597590 let mut on_set = SanitizerSet::empty();
598591 let mut off_set = SanitizerSet::empty();
......@@ -719,11 +712,7 @@ impl<S: Stage> SingleAttributeParser<S> for PatchableFunctionEntryParser {
719712 const TEMPLATE: AttributeTemplate = template!(List: &["prefix_nops = m, entry_nops = n"]);
720713
721714 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
722 let Some(meta_item_list) = args.list() else {
723 let attr_span = cx.attr_span;
724 cx.adcx().expected_list(attr_span, args);
725 return None;
726 };
715 let meta_item_list = cx.expect_list(args, cx.attr_span)?;
727716
728717 let mut prefix = None;
729718 let mut entry = None;
compiler/rustc_attr_parsing/src/attributes/confusables.rs+1-5
......@@ -12,11 +12,7 @@ impl<S: Stage> AttributeParser<S> for ConfusablesParser {
1212 &[sym::rustc_confusables],
1313 template!(List: &[r#""name1", "name2", ..."#]),
1414 |this, cx, args| {
15 let Some(list) = args.list() else {
16 let attr_span = cx.attr_span;
17 cx.adcx().expected_list(attr_span, args);
18 return;
19 };
15 let Some(list) = cx.expect_list(args, cx.attr_span) else { return };
2016
2117 if list.is_empty() {
2218 cx.emit_err(EmptyConfusables { span: cx.attr_span });
compiler/rustc_attr_parsing/src/attributes/crate_level.rs+2-6
......@@ -314,9 +314,7 @@ impl<S: Stage> CombineAttributeParser<S> for FeatureParser {
314314 cx: &mut AcceptContext<'_, '_, S>,
315315 args: &ArgParser,
316316 ) -> impl IntoIterator<Item = Self::Item> {
317 let ArgParser::List(list) = args else {
318 let attr_span = cx.attr_span;
319 cx.adcx().expected_list(attr_span, args);
317 let Some(list) = cx.expect_list(args, cx.attr_span) else {
320318 return Vec::new();
321319 };
322320
......@@ -362,9 +360,7 @@ impl<S: Stage> CombineAttributeParser<S> for RegisterToolParser {
362360 cx: &mut AcceptContext<'_, '_, S>,
363361 args: &ArgParser,
364362 ) -> impl IntoIterator<Item = Self::Item> {
365 let ArgParser::List(list) = args else {
366 let attr_span = cx.attr_span;
367 cx.adcx().expected_list(attr_span, args);
363 let Some(list) = cx.expect_list(args, cx.attr_span) else {
368364 return Vec::new();
369365 };
370366
compiler/rustc_attr_parsing/src/attributes/debugger.rs+1-1
......@@ -20,7 +20,7 @@ impl<S: Stage> CombineAttributeParser<S> for DebuggerViualizerParser {
2020 cx: &mut AcceptContext<'_, '_, S>,
2121 args: &ArgParser,
2222 ) -> impl IntoIterator<Item = Self::Item> {
23 let single = cx.single_element_list(args, cx.attr_span)?;
23 let single = cx.expect_single_element_list(args, cx.attr_span)?;
2424 let Some(mi) = single.meta_item() else {
2525 cx.adcx().expected_name_value(single.span(), None);
2626 return None;
compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs+2-2
......@@ -344,7 +344,7 @@ fn parse_directive_items<'p, S: Stage>(
344344 }
345345 (Mode::RustcOnUnimplemented, sym::on) => {
346346 if is_root {
347 let items = or_malformed!(item.args().list()?);
347 let items = or_malformed!(item.args().as_list()?);
348348 let mut iter = items.mixed();
349349 let condition: &MetaItemOrLitParser = match iter.next() {
350350 Some(c) => c,
......@@ -554,7 +554,7 @@ fn parse_predicate(input: &MetaItemOrLitParser) -> Result<Predicate, InvalidOnCl
554554 sym::any => Ok(Predicate::Any(parse_predicate_sequence(mis)?)),
555555 sym::all => Ok(Predicate::All(parse_predicate_sequence(mis)?)),
556556 sym::not => {
557 if let Some(single) = mis.single() {
557 if let Some(single) = mis.as_single() {
558558 Ok(Predicate::Not(Box::new(parse_predicate(single)?)))
559559 } else {
560560 Err(InvalidOnClause::ExpectedOnePredInNot { span: mis.span })
compiler/rustc_attr_parsing/src/attributes/doc.rs+2-2
......@@ -199,7 +199,7 @@ impl DocParser {
199199 self.attribute.no_crate_inject = Some(path.span())
200200 }
201201 Some(sym::attr) => {
202 let Some(list) = args.list() else {
202 let Some(list) = args.as_list() else {
203203 // FIXME: remove this method once merged and uncomment the line below instead.
204204 // cx.expected_list(cx.attr_span, args);
205205 let span = cx.attr_span;
......@@ -587,7 +587,7 @@ impl DocParser {
587587 }),
588588 Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args),
589589 Some(sym::test) => {
590 let Some(list) = args.list() else {
590 let Some(list) = args.as_list() else {
591591 cx.emit_dyn_lint(
592592 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
593593 |dcx, level| DocTestTakesList.into_diag(dcx, level),
compiler/rustc_attr_parsing/src/attributes/inline.rs+2-8
......@@ -37,10 +37,7 @@ impl<S: Stage> SingleAttributeParser<S> for InlineParser {
3737 match args {
3838 ArgParser::NoArgs => Some(AttributeKind::Inline(InlineAttr::Hint, cx.attr_span)),
3939 ArgParser::List(list) => {
40 let Some(l) = list.single() else {
41 cx.adcx().expected_single_argument(list.span, list.len());
42 return None;
43 };
40 let l = cx.expect_single(list)?;
4441
4542 match l.meta_item().and_then(|i| i.path().word_sym()) {
4643 Some(sym::always) => {
......@@ -78,10 +75,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
7875 let reason = match args {
7976 ArgParser::NoArgs => None,
8077 ArgParser::List(list) => {
81 let Some(l) = list.single() else {
82 cx.adcx().expected_single_argument(list.span, list.len());
83 return None;
84 };
78 let l = cx.expect_single(list)?;
8579
8680 let Some(reason) = l.lit().and_then(|i| i.kind.str()) else {
8781 cx.adcx().expected_string_literal(l.span(), l.lit());
compiler/rustc_attr_parsing/src/attributes/instruction_set.rs+1-1
......@@ -19,7 +19,7 @@ impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser {
1919 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
2020 const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
2121 const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32];
22 let maybe_meta_item = cx.single_element_list(args, cx.attr_span)?;
22 let maybe_meta_item = cx.expect_single_element_list(args, cx.attr_span)?;
2323
2424 let Some(meta_item) = maybe_meta_item.meta_item() else {
2525 cx.adcx().expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS);
compiler/rustc_attr_parsing/src/attributes/link_attrs.rs+39-3
......@@ -16,8 +16,9 @@ use crate::attributes::cfg::parse_cfg_entry;
1616use crate::session_diagnostics::{
1717 AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic,
1818 ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier,
19 LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers,
20 NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic,
19 InvalidMachoSection, InvalidMachoSectionReason, LinkFrameworkApple, LinkOrdinalOutOfRange,
20 LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows,
21 WholeArchiveNeedsStatic,
2122};
2223
2324pub(crate) struct LinkNameParser;
......@@ -390,7 +391,7 @@ impl LinkParser {
390391 cx.adcx().duplicate_key(item.span(), sym::cfg);
391392 return true;
392393 }
393 let Some(link_cfg) = cx.single_element_list(item.args(), item.span()) else {
394 let Some(link_cfg) = cx.expect_single_element_list(item.args(), item.span()) else {
394395 return true;
395396 };
396397 if !features.link_cfg() {
......@@ -462,6 +463,29 @@ impl LinkParser {
462463
463464pub(crate) struct LinkSectionParser;
464465
466fn check_link_section_macho(name: Symbol) -> Result<(), InvalidMachoSectionReason> {
467 let mut parts = name.as_str().split(',').map(|s| s.trim());
468
469 // The segment can be empty.
470 let _segment = parts.next();
471
472 // But the section is required.
473 let section = match parts.next() {
474 None | Some("") => return Err(InvalidMachoSectionReason::MissingSection),
475 Some(section) => section,
476 };
477
478 if section.len() > 16 {
479 return Err(InvalidMachoSectionReason::SectionTooLong { section: section.to_string() });
480 }
481
482 // LLVM also checks the other components of the section specifier, but that logic is hard to
483 // keep in sync. We skip it here for now, assuming that if you got that far you'll be able
484 // to interpret the LLVM errors.
485
486 Ok(())
487}
488
465489impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
466490 const PATH: &[Symbol] = &[sym::link_section];
467491 const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
......@@ -495,6 +519,18 @@ impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
495519 return None;
496520 }
497521
522 // We (currently) only validate macho section specifiers.
523 match cx.sess.target.binary_format {
524 BinaryFormat::MachO => match check_link_section_macho(name) {
525 Ok(()) => {}
526 Err(reason) => {
527 cx.emit_err(InvalidMachoSection { name_span: nv.value_span, reason });
528 return None;
529 }
530 },
531 BinaryFormat::Coff | BinaryFormat::Elf | BinaryFormat::Wasm | BinaryFormat::Xcoff => {}
532 }
533
498534 Some(LinkSection { name, span: cx.attr_span })
499535 }
500536}
compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs+2-2
......@@ -142,7 +142,7 @@ impl<S: Stage> SingleAttributeParser<S> for MacroExportParser {
142142 let local_inner_macros = match args {
143143 ArgParser::NoArgs => false,
144144 ArgParser::List(list) => {
145 let Some(l) = list.single() else {
145 let Some(l) = list.as_single() else {
146146 cx.adcx().warn_ill_formed_attribute_input(INVALID_MACRO_EXPORT_ARGUMENTS);
147147 return None;
148148 };
......@@ -174,7 +174,7 @@ impl<S: Stage> SingleAttributeParser<S> for CollapseDebugInfoParser {
174174 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
175175
176176 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
177 let single = cx.single_element_list(args, cx.attr_span)?;
177 let single = cx.expect_single_element_list(args, cx.attr_span)?;
178178 let Some(mi) = single.meta_item() else {
179179 cx.adcx().expected_not_literal(single.span());
180180 return None;
compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs+2-5
......@@ -57,7 +57,7 @@ fn parse_derive_like<S: Stage>(
5757 args: &ArgParser,
5858 trait_name_mandatory: bool,
5959) -> Option<(Option<Symbol>, ThinVec<Symbol>)> {
60 let Some(list) = args.list() else {
60 let Some(list) = args.as_list() else {
6161 // For #[rustc_builtin_macro], it is permitted to leave out the trait name
6262 if args.no_args().is_ok() && !trait_name_mandatory {
6363 return Some((None, ThinVec::new()));
......@@ -101,10 +101,7 @@ fn parse_derive_like<S: Stage>(
101101 cx.adcx().expected_specific_argument(attrs.span(), &[sym::attributes]);
102102 return None;
103103 }
104 let Some(attr_list) = attr_list.args().list() else {
105 cx.adcx().expected_list(attrs.span(), attr_list.args());
106 return None;
107 };
104 let attr_list = cx.expect_list(attr_list.args(), attrs.span())?;
108105
109106 // Parse item in `attributes(...)` argument
110107 for attr in attr_list.mixed() {
compiler/rustc_attr_parsing/src/attributes/prototype.rs+1-5
......@@ -22,11 +22,7 @@ impl<S: Stage> SingleAttributeParser<S> for CustomMirParser {
2222 const TEMPLATE: AttributeTemplate = template!(List: &[r#"dialect = "...", phase = "...""#]);
2323
2424 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
25 let Some(list) = args.list() else {
26 let attr_span = cx.attr_span;
27 cx.adcx().expected_list(attr_span, args);
28 return None;
29 };
25 let list = cx.expect_list(args, cx.attr_span)?;
3026
3127 let mut dialect = None;
3228 let mut phase = None;
compiler/rustc_attr_parsing/src/attributes/repr.rs+3-6
......@@ -32,9 +32,7 @@ impl<S: Stage> CombineAttributeParser<S> for ReprParser {
3232 ) -> impl IntoIterator<Item = Self::Item> {
3333 let mut reprs = Vec::new();
3434
35 let Some(list) = args.list() else {
36 let attr_span = cx.attr_span;
37 cx.adcx().expected_list(attr_span, args);
35 let Some(list) = cx.expect_list(args, cx.attr_span) else {
3836 return reprs;
3937 };
4038
......@@ -197,7 +195,7 @@ fn parse_repr_align<S: Stage>(
197195) -> Option<ReprAttr> {
198196 use AlignKind::*;
199197
200 let Some(align) = list.single() else {
198 let Some(align) = list.as_single() else {
201199 match align_kind {
202200 Packed => {
203201 cx.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
......@@ -296,8 +294,7 @@ impl RustcAlignParser {
296294 cx.adcx().expected_list(attr_span, args);
297295 }
298296 ArgParser::List(list) => {
299 let Some(align) = list.single() else {
300 cx.adcx().expected_single_argument(list.span, list.len());
297 let Some(align) = cx.expect_single(list) else {
301298 return;
302299 };
303300
compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs+1-3
......@@ -96,9 +96,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcDumpLayoutParser {
9696 cx: &mut AcceptContext<'_, '_, S>,
9797 args: &ArgParser,
9898 ) -> impl IntoIterator<Item = Self::Item> {
99 let ArgParser::List(items) = args else {
100 let attr_span = cx.attr_span;
101 cx.adcx().expected_list(attr_span, args);
99 let Some(items) = cx.expect_list(args, cx.attr_span) else {
102100 return vec![];
103101 };
104102
compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs+11-36
......@@ -30,11 +30,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcMustImplementOneOfParser {
3030 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
3131 const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]);
3232 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
33 let Some(list) = args.list() else {
34 let span = cx.attr_span;
35 cx.adcx().expected_list(span, args);
36 return None;
37 };
33 let list = cx.expect_list(args, cx.attr_span)?;
3834
3935 let mut fn_names = ThinVec::new();
4036
......@@ -130,11 +126,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLegacyConstGenericsParser {
130126 const TEMPLATE: AttributeTemplate = template!(List: &["N"]);
131127
132128 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
133 let ArgParser::List(meta_items) = args else {
134 let attr_span = cx.attr_span;
135 cx.adcx().expected_list(attr_span, args);
136 return None;
137 };
129 let meta_items = cx.expect_list(args, cx.attr_span)?;
138130
139131 let mut parsed_indexes = ThinVec::new();
140132 let mut errored = false;
......@@ -185,7 +177,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLintOptDenyFieldAccessParser {
185177 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]);
186178 const TEMPLATE: AttributeTemplate = template!(Word);
187179 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
188 let arg = cx.single_element_list(args, cx.attr_span)?;
180 let arg = cx.expect_single_element_list(args, cx.attr_span)?;
189181
190182 let MetaItemOrLitParser::Lit(MetaItemLit { kind: LitKind::Str(lint_message, _), .. }) = arg
191183 else {
......@@ -210,11 +202,7 @@ fn parse_cgu_fields<S: Stage>(
210202 args: &ArgParser,
211203 accepts_kind: bool,
212204) -> Option<(Symbol, Symbol, Option<CguKind>)> {
213 let Some(args) = args.list() else {
214 let attr_span = cx.attr_span;
215 cx.adcx().expected_list(attr_span, args);
216 return None;
217 };
205 let args = cx.expect_list(args, cx.attr_span)?;
218206
219207 let mut cfg = None::<(Symbol, Span)>;
220208 let mut module = None::<(Symbol, Span)>;
......@@ -359,7 +347,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDeprecatedSafe2024Parser {
359347 const TEMPLATE: AttributeTemplate = template!(List: &[r#"audit_that = "...""#]);
360348
361349 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
362 let single = cx.single_element_list(args, cx.attr_span)?;
350 let single = cx.expect_single_element_list(args, cx.attr_span)?;
363351
364352 let Some(arg) = single.meta_item() else {
365353 cx.adcx().expected_name_value(single.span(), None);
......@@ -418,11 +406,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcNeverTypeOptionsParser {
418406 ]);
419407
420408 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
421 let Some(list) = args.list() else {
422 let attr_span = cx.attr_span;
423 cx.adcx().expected_list(attr_span, args);
424 return None;
425 };
409 let list = cx.expect_list(args, cx.attr_span)?;
426410
427411 let mut fallback = None::<Ident>;
428412 let mut diverging_block_default = None::<Ident>;
......@@ -703,9 +687,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
703687 cx: &mut AcceptContext<'_, '_, S>,
704688 args: &ArgParser,
705689 ) -> impl IntoIterator<Item = Self::Item> {
706 let Some(list) = args.list() else {
707 let attr_span = cx.attr_span;
708 cx.adcx().expected_list(attr_span, args);
690 let Some(list) = cx.expect_list(args, cx.attr_span) else {
709691 return ThinVec::new();
710692 };
711693
......@@ -825,11 +807,8 @@ impl<S: Stage> CombineAttributeParser<S> for RustcCleanParser {
825807 if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
826808 cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
827809 }
828 let Some(list) = args.list() else {
829 let attr_span = cx.attr_span;
830 cx.adcx().expected_list(attr_span, args);
831 return None;
832 };
810 let list = cx.expect_list(args, cx.attr_span)?;
811
833812 let mut except = None;
834813 let mut loaded_from_disk = None;
835814 let mut cfg = None;
......@@ -926,11 +905,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcIfThisChangedParser {
926905 match args {
927906 ArgParser::NoArgs => Some(AttributeKind::RustcIfThisChanged(cx.attr_span, None)),
928907 ArgParser::List(list) => {
929 let Some(item) = list.single() else {
930 let attr_span = cx.attr_span;
931 cx.adcx().expected_single_argument(attr_span, list.len());
932 return None;
933 };
908 let item = cx.expect_single(list)?;
934909 let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
935910 cx.adcx().expected_identifier(item.span());
936911 return None;
......@@ -988,7 +963,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcThenThisWouldNeedParser {
988963 if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
989964 cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
990965 }
991 let item = cx.single_element_list(args, cx.attr_span)?;
966 let item = cx.expect_single_element_list(args, cx.attr_span)?;
992967 let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
993968 cx.adcx().expected_identifier(item.span());
994969 return None;
compiler/rustc_attr_parsing/src/attributes/stability.rs+3-15
......@@ -311,11 +311,7 @@ pub(crate) fn parse_stability<S: Stage>(
311311 let mut feature = None;
312312 let mut since = None;
313313
314 let ArgParser::List(list) = args else {
315 let attr_span = cx.attr_span;
316 cx.adcx().expected_list(attr_span, args);
317 return None;
318 };
314 let list = cx.expect_list(args, cx.attr_span)?;
319315
320316 for param in list.mixed() {
321317 let param_span = param.span();
......@@ -383,11 +379,7 @@ pub(crate) fn parse_unstability<S: Stage>(
383379 let mut implied_by = None;
384380 let mut old_name = None;
385381
386 let ArgParser::List(list) = args else {
387 let attr_span = cx.attr_span;
388 cx.adcx().expected_list(attr_span, args);
389 return None;
390 };
382 let list = cx.expect_list(args, cx.attr_span)?;
391383
392384 for param in list.mixed() {
393385 let Some(param) = param.meta_item() else {
......@@ -503,11 +495,7 @@ impl<S: Stage> CombineAttributeParser<S> for UnstableRemovedParser {
503495 return None;
504496 }
505497
506 let ArgParser::List(list) = args else {
507 let attr_span = cx.attr_span;
508 cx.adcx().expected_list(attr_span, args);
509 return None;
510 };
498 let list = cx.expect_list(args, cx.attr_span)?;
511499
512500 for param in list.mixed() {
513501 let Some(param) = param.meta_item() else {
compiler/rustc_attr_parsing/src/attributes/test_attrs.rs+9-15
......@@ -28,10 +28,11 @@ impl<S: Stage> SingleAttributeParser<S> for IgnoreParser {
2828 Some(str_value)
2929 }
3030 ArgParser::List(list) => {
31 let help = list.single().and_then(|item| item.meta_item()).and_then(|item| {
32 item.args().no_args().ok()?;
33 Some(item.path().to_string())
34 });
31 let help =
32 list.as_single().and_then(|item| item.meta_item()).and_then(|item| {
33 item.args().no_args().ok()?;
34 Some(item.path().to_string())
35 });
3536 cx.adcx().warn_ill_formed_attribute_input_with_help(
3637 ILL_FORMED_ATTRIBUTE_INPUT,
3738 help,
......@@ -71,10 +72,7 @@ impl<S: Stage> SingleAttributeParser<S> for ShouldPanicParser {
7172 Some(str_value)
7273 }
7374 ArgParser::List(list) => {
74 let Some(single) = list.single() else {
75 cx.adcx().expected_single_argument(list.span, list.len());
76 return None;
77 };
75 let single = cx.expect_single(list)?;
7876 let Some(single) = single.meta_item() else {
7977 cx.adcx().expected_name_value(single.span(), Some(sym::expected));
8078 return None;
......@@ -140,17 +138,13 @@ impl<S: Stage> SingleAttributeParser<S> for RustcAbiParser {
140138 ]);
141139
142140 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
143 let Some(args) = args.list() else {
141 let Some(args) = args.as_list() else {
144142 let attr_span = cx.attr_span;
145143 cx.adcx().expected_specific_argument_and_list(attr_span, &[sym::assert_eq, sym::debug]);
146144 return None;
147145 };
148146
149 let Some(arg) = args.single() else {
150 let attr_span = cx.attr_span;
151 cx.adcx().expected_single_argument(attr_span, args.len());
152 return None;
153 };
147 let arg = cx.expect_single(args)?;
154148
155149 let mut fail_incorrect_argument =
156150 |span| cx.adcx().expected_specific_argument(span, &[sym::assert_eq, sym::debug]);
......@@ -203,7 +197,7 @@ impl<S: Stage> SingleAttributeParser<S> for TestRunnerParser {
203197 const TEMPLATE: AttributeTemplate = template!(List: &["path"]);
204198
205199 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
206 let single = cx.single_element_list(args, cx.attr_span)?;
200 let single = cx.expect_single_element_list(args, cx.attr_span)?;
207201
208202 let Some(meta) = single.meta_item() else {
209203 cx.adcx().expected_not_literal(single.span());
compiler/rustc_attr_parsing/src/attributes/traits.rs+1-5
......@@ -17,11 +17,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcSkipDuringMethodDispatchParser
1717 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
1818 let mut array = false;
1919 let mut boxed_slice = false;
20 let Some(args) = args.list() else {
21 let attr_span = cx.attr_span;
22 cx.adcx().expected_list(attr_span, args);
23 return None;
24 };
20 let args = cx.expect_list(args, cx.attr_span)?;
2521 if args.is_empty() {
2622 cx.adcx().expected_at_least_one_argument(args.span);
2723 return None;
compiler/rustc_attr_parsing/src/attributes/util.rs+1-1
......@@ -41,7 +41,7 @@ pub(crate) fn parse_single_integer<S: Stage>(
4141 cx: &mut AcceptContext<'_, '_, S>,
4242 args: &ArgParser,
4343) -> Option<u128> {
44 let single = cx.single_element_list(args, cx.attr_span)?;
44 let single = cx.expect_single_element_list(args, cx.attr_span)?;
4545 let Some(lit) = single.lit() else {
4646 cx.adcx().expected_integer_literal(single.span());
4747 return None;
compiler/rustc_attr_parsing/src/context.rs+49-3
......@@ -61,7 +61,7 @@ use crate::attributes::test_attrs::*;
6161use crate::attributes::traits::*;
6262use crate::attributes::transparency::*;
6363use crate::attributes::{AttributeParser as _, AttributeSafety, Combine, Single, WithoutArgs};
64use crate::parser::{ArgParser, MetaItemOrLitParser, RefPathParser};
64use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, RefPathParser};
6565use crate::session_diagnostics::{
6666 AttributeParseError, AttributeParseErrorReason, AttributeParseErrorSuggestions,
6767 ParsedDescription,
......@@ -554,7 +554,7 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
554554 ///
555555 /// The provided span is used as a fallback for diagnostic generation in case `arg` does not
556556 /// contain any. It should be the span of the node that contains `arg`.
557 pub(crate) fn single_element_list<'arg>(
557 pub(crate) fn expect_single_element_list<'arg>(
558558 &mut self,
559559 arg: &'arg ArgParser,
560560 span: Span,
......@@ -564,13 +564,59 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
564564 return None;
565565 };
566566
567 let Some(single) = l.single() else {
567 let Some(single) = l.as_single() else {
568568 self.adcx().expected_single_argument(l.span, l.len());
569569 return None;
570570 };
571571
572572 Some(single)
573573 }
574
575 /// Asserts that an [`ArgParser`] is a list and returns it, or emits an error and returns
576 /// `None`.
577 ///
578 /// Some examples:
579 ///
580 /// - `#[allow(clippy::complexity)]`: `(clippy::complexity)` is a list
581 /// - `#[rustfmt::skip::macros(target_macro_name)]`: `(target_macro_name)` is a list
582 ///
583 /// This is a higher-level (and harder to misuse) wrapper over [`ArgParser::as_list`]. That
584 /// allows using `?` when the attribute parsing function allows it. You may still want to use
585 /// [`ArgParser::as_list`] for the following reasons:
586 ///
587 /// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
588 /// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.
589 pub(crate) fn expect_list<'arg>(
590 &mut self,
591 args: &'arg ArgParser,
592 span: Span,
593 ) -> Option<&'arg MetaItemListParser> {
594 let list = args.as_list();
595 if list.is_none() {
596 self.adcx().expected_list(span, args);
597 }
598 list
599 }
600
601 /// Asserts that a [`MetaItemListParser`] contains a single element and returns it, or emits an
602 /// error and returns `None`.
603 ///
604 /// This is a higher-level (and harder to misuse) wrapper over [`MetaItemListParser::as_single`].
605 /// That allows using `?` to early return. You may still want to use
606 /// [`MetaItemListParser::as_single`] for the following reasons:
607 ///
608 /// - You want to emit your own diagnostics (for instance, with [`SharedContext::emit_err`]).
609 /// - The attribute can be parsed in multiple ways and it does not make sense to emit an error.
610 pub(crate) fn expect_single<'arg>(
611 &mut self,
612 list: &'arg MetaItemListParser,
613 ) -> Option<&'arg MetaItemOrLitParser> {
614 let single = list.as_single();
615 if single.is_none() {
616 self.adcx().expected_single_argument(list.span, list.len());
617 }
618 single
619 }
574620}
575621
576622impl<'f, 'sess, S: Stage> Deref for AcceptContext<'f, 'sess, S> {
compiler/rustc_attr_parsing/src/parser.rs+4-3
......@@ -176,7 +176,7 @@ impl ArgParser {
176176 ///
177177 /// - `#[allow(clippy::complexity)]`: `(clippy::complexity)` is a list
178178 /// - `#[rustfmt::skip::macros(target_macro_name)]`: `(target_macro_name)` is a list
179 pub fn list(&self) -> Option<&MetaItemListParser> {
179 pub fn as_list(&self) -> Option<&MetaItemListParser> {
180180 match self {
181181 Self::List(l) => Some(l),
182182 Self::NameValue(_) | Self::NoArgs => None,
......@@ -255,6 +255,7 @@ impl MetaItemOrLitParser {
255255 }
256256}
257257
258// FIXME(scrabsha): once #155696 is merged, update this and mention the higher-level APIs.
258259/// Utility that deconstructs a MetaItem into usable parts.
259260///
260261/// MetaItems are syntactically extremely flexible, but specific attributes want to parse
......@@ -263,7 +264,7 @@ impl MetaItemOrLitParser {
263264/// MetaItems consist of some path, and some args. The args could be empty. In other words:
264265///
265266/// - `name` -> args are empty
266/// - `name(...)` -> args are a [`list`](ArgParser::list), which is the bit between the parentheses
267/// - `name(...)` -> args are a [`list`](ArgParser::as_list), which is the bit between the parentheses
267268/// - `name = value`-> arg is [`name_value`](ArgParser::name_value), where the argument is the
268269/// `= value` part
269270///
......@@ -694,7 +695,7 @@ impl MetaItemListParser {
694695 /// Returns Some if the list contains only a single element.
695696 ///
696697 /// Inside the Some is the parser to parse this single element.
697 pub fn single(&self) -> Option<&MetaItemOrLitParser> {
698 pub fn as_single(&self) -> Option<&MetaItemOrLitParser> {
698699 let mut iter = self.mixed();
699700 iter.next().filter(|_| iter.next().is_none())
700701 }
compiler/rustc_attr_parsing/src/session_diagnostics.rs+19
......@@ -1137,3 +1137,22 @@ pub(crate) struct UnstableAttrForAlreadyStableFeature {
11371137 #[label("the stability attribute annotates this item")]
11381138 pub item_span: Span,
11391139}
1140
1141#[derive(Diagnostic)]
1142#[diag("invalid Mach-O section specifier")]
1143pub(crate) struct InvalidMachoSection {
1144 #[primary_span]
1145 #[label("not a valid Mach-O section specifier")]
1146 pub name_span: Span,
1147 #[subdiagnostic]
1148 pub reason: InvalidMachoSectionReason,
1149}
1150
1151#[derive(Subdiagnostic)]
1152pub(crate) enum InvalidMachoSectionReason {
1153 #[note("a Mach-O section specifier requires a segment and a section, separated by a comma")]
1154 #[help("an example of a valid Mach-O section specifier is `__TEXT,__cstring`")]
1155 MissingSection,
1156 #[note("section name `{$section}` is longer than 16 bytes")]
1157 SectionTooLong { section: String },
1158}
compiler/rustc_codegen_llvm/src/declare.rs+23
......@@ -14,6 +14,7 @@
1414use std::borrow::Borrow;
1515
1616use itertools::Itertools;
17use rustc_abi::AddressSpace;
1718use rustc_codegen_ssa::traits::{MiscCodegenMethods, TypeMembershipCodegenMethods};
1819use rustc_data_structures::fx::FxIndexSet;
1920use rustc_middle::ty::{Instance, Ty};
......@@ -104,6 +105,28 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
104105 )
105106 }
106107 }
108
109 /// Declare a global value in a specific address space.
110 ///
111 /// If there’s a value with the same name already declared, the function will
112 /// return its Value instead.
113 pub(crate) fn declare_global_in_addrspace(
114 &self,
115 name: &str,
116 ty: &'ll Type,
117 addr_space: AddressSpace,
118 ) -> &'ll Value {
119 debug!("declare_global(name={name:?}, addrspace={addr_space:?})");
120 unsafe {
121 llvm::LLVMRustGetOrInsertGlobalInAddrspace(
122 (**self).borrow().llmod,
123 name.as_c_char_ptr(),
124 name.len(),
125 ty,
126 addr_space.0,
127 )
128 }
129 }
107130}
108131
109132impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
compiler/rustc_codegen_llvm/src/intrinsic.rs+45-4
......@@ -3,8 +3,8 @@ use std::ffi::c_uint;
33use std::{assert_matches, iter, ptr};
44
55use rustc_abi::{
6 Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, Size,
7 WrappingRange,
6 AddressSpace, Align, BackendRepr, Float, HasDataLayout, Integer, NumScalableVectors, Primitive,
7 Size, WrappingRange,
88};
99use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
1010use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
......@@ -178,6 +178,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
178178 span: Span,
179179 ) -> Result<(), ty::Instance<'tcx>> {
180180 let tcx = self.tcx;
181 let llvm_version = crate::llvm_util::get_version();
181182
182183 let name = tcx.item_name(instance.def_id());
183184 let fn_args = instance.args;
......@@ -194,7 +195,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
194195 | sym::maximum_number_nsz_f64
195196 | sym::maximum_number_nsz_f128
196197 // Need at least LLVM 22 for `min/maximumnum` to not crash LLVM.
197 if crate::llvm_util::get_version() >= (22, 0, 0) =>
198 if llvm_version >= (22, 0, 0) =>
198199 {
199200 let intrinsic_name = if name.as_str().starts_with("min") {
200201 "llvm.minimumnum"
......@@ -420,7 +421,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
420421 }
421422
422423 // FIXME move into the branch below when LLVM 22 is the lowest version we support.
423 sym::carryless_mul if crate::llvm_util::get_version() >= (22, 0, 0) => {
424 sym::carryless_mul if llvm_version >= (22, 0, 0) => {
424425 let ty = args[0].layout.ty;
425426 if !ty.is_integral() {
426427 tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
......@@ -620,6 +621,46 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
620621 return Ok(());
621622 }
622623
624 sym::gpu_launch_sized_workgroup_mem => {
625 // Generate an anonymous global per call, with these properties:
626 // 1. The global is in the address space for workgroup memory
627 // 2. It is an `external` global
628 // 3. It is correctly aligned for the pointee `T`
629 // All instances of extern addrspace(gpu_workgroup) globals are merged in the LLVM backend.
630 // The name is irrelevant.
631 // See https://docs.nvidia.com/cuda/cuda-c-programming-guide/#shared
632 let name = if llvm_version < (23, 0, 0) && tcx.sess.target.arch == Arch::Nvptx64 {
633 // The auto-assigned name for extern shared globals in the nvptx backend does
634 // not compile in ptxas. Workaround this issue by assigning a name.
635 // Fixed in LLVM 23.
636 "gpu_launch_sized_workgroup_mem"
637 } else {
638 ""
639 };
640 let global = self.declare_global_in_addrspace(
641 name,
642 self.type_array(self.type_i8(), 0),
643 AddressSpace::GPU_WORKGROUP,
644 );
645 let ty::RawPtr(inner_ty, _) = result.layout.ty.kind() else { unreachable!() };
646 // The alignment of the global is used to specify the *minimum* alignment that
647 // must be obeyed by the GPU runtime.
648 // When multiple of these global variables are used by a kernel, the maximum alignment is taken.
649 // See https://github.com/llvm/llvm-project/blob/a271d07488a85ce677674bbe8101b10efff58c95/llvm/lib/Target/AMDGPU/AMDGPULowerModuleLDSPass.cpp#L821
650 let alignment = self.align_of(*inner_ty).bytes() as u32;
651 unsafe {
652 // FIXME Workaround the above issue by taking maximum alignment if the global existed
653 if tcx.sess.target.arch == Arch::Nvptx64 {
654 if alignment > llvm::LLVMGetAlignment(global) {
655 llvm::LLVMSetAlignment(global, alignment);
656 }
657 } else {
658 llvm::LLVMSetAlignment(global, alignment);
659 }
660 }
661 self.cx().const_pointercast(global, self.type_ptr())
662 }
663
623664 sym::amdgpu_dispatch_ptr => {
624665 let val = self.call_intrinsic("llvm.amdgcn.dispatch.ptr", &[], &[]);
625666 // Relying on `LLVMBuildPointerCast` to produce an addrspacecast
compiler/rustc_codegen_llvm/src/llvm/ffi.rs+7
......@@ -2003,6 +2003,13 @@ unsafe extern "C" {
20032003 NameLen: size_t,
20042004 T: &'a Type,
20052005 ) -> &'a Value;
2006 pub(crate) fn LLVMRustGetOrInsertGlobalInAddrspace<'a>(
2007 M: &'a Module,
2008 Name: *const c_char,
2009 NameLen: size_t,
2010 T: &'a Type,
2011 AddressSpace: c_uint,
2012 ) -> &'a Value;
20062013 pub(crate) fn LLVMRustGetNamedValue(
20072014 M: &Module,
20082015 Name: *const c_char,
compiler/rustc_codegen_ssa/src/mir/intrinsic.rs+1
......@@ -111,6 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
111111 sym::abort
112112 | sym::unreachable
113113 | sym::cold_path
114 | sym::gpu_launch_sized_workgroup_mem
114115 | sym::breakpoint
115116 | sym::amdgpu_dispatch_ptr
116117 | sym::assert_zero_valid
compiler/rustc_hir/src/attrs/data_structures.rs+1-1
......@@ -1098,8 +1098,8 @@ pub enum AttributeKind {
10981098
10991099 /// Represents [`#[link_section]`](https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute)
11001100 LinkSection {
1101 name: Symbol,
11021101 span: Span,
1102 name: Symbol,
11031103 },
11041104
11051105 /// Represents `#[linkage]`.
compiler/rustc_hir/src/hir.rs+9
......@@ -1304,6 +1304,15 @@ impl Attribute {
13041304 Attribute::Unparsed(_) => false,
13051305 }
13061306 }
1307
1308 pub fn is_prefix_attr_for_suggestions(&self) -> bool {
1309 match self {
1310 Attribute::Unparsed(attr) => attr.span.desugaring_kind().is_none(),
1311 // Other parsed attributes that can appear on expressions originate from source and
1312 // should make suggestions treat the expression like a prefixed form.
1313 Attribute::Parsed(_) => true,
1314 }
1315 }
13071316}
13081317
13091318impl AttributeExt for Attribute {
compiler/rustc_hir_analysis/src/check/always_applicable.rs+61-1
......@@ -11,7 +11,7 @@ use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
1111use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
1212use rustc_middle::span_bug;
1313use rustc_middle::ty::util::CheckRegions;
14use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode};
14use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
1515use rustc_trait_selection::regions::InferCtxtRegionExt;
1616use rustc_trait_selection::traits::{self, ObligationCtxt};
1717
......@@ -65,6 +65,8 @@ pub(crate) fn check_drop_impl(
6565 adt_to_impl_args,
6666 )?;
6767
68 ensure_all_fields_are_const_destruct(tcx, drop_impl_did, adt_def.did())?;
69
6870 ensure_impl_predicates_are_implied_by_item_defn(
6971 tcx,
7072 drop_impl_did,
......@@ -173,6 +175,64 @@ fn ensure_impl_params_and_item_params_correspond<'tcx>(
173175 Err(err.emit())
174176}
175177
178fn ensure_all_fields_are_const_destruct<'tcx>(
179 tcx: TyCtxt<'tcx>,
180 impl_def_id: LocalDefId,
181 adt_def_id: DefId,
182) -> Result<(), ErrorGuaranteed> {
183 if !tcx.is_conditionally_const(impl_def_id) {
184 return Ok(());
185 }
186 let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
187 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
188
189 let impl_span = tcx.def_span(impl_def_id.to_def_id());
190 let env =
191 ty::EarlyBinder::bind(tcx.param_env(impl_def_id)).instantiate_identity().skip_norm_wip();
192 let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id);
193 let destruct_trait = tcx.lang_items().destruct_trait().unwrap();
194 for field in tcx.adt_def(adt_def_id).all_fields() {
195 let field_ty = field.ty(tcx, args);
196 let cause = traits::ObligationCause::new(
197 tcx.def_span(field.did),
198 impl_def_id,
199 ObligationCauseCode::Misc,
200 );
201 ocx.register_obligation(traits::Obligation::new(
202 tcx,
203 cause,
204 env,
205 ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
206 trait_ref: ty::TraitRef::new(tcx, destruct_trait, [field_ty]),
207 constness: ty::BoundConstness::Maybe,
208 }),
209 ));
210 }
211 ocx.evaluate_obligations_error_on_ambiguity()
212 .into_iter()
213 .map(|error| {
214 let ty::ClauseKind::HostEffect(eff) =
215 error.root_obligation.predicate.expect_clause().kind().no_bound_vars().unwrap()
216 else {
217 unreachable!()
218 };
219 let field_ty = eff.trait_ref.self_ty();
220 let diag = struct_span_code_err!(
221 tcx.dcx(),
222 error.root_obligation.cause.span,
223 E0367,
224 "`{field_ty}` does not implement `[const] Destruct`",
225 )
226 .with_span_note(impl_span, "required for this `Drop` impl");
227 if field_ty.has_param() {
228 // FIXME: suggest adding `[const] Destruct` by teaching
229 // `suggest_restricting_param_bound` about const traits.
230 }
231 Err(diag.emit())
232 })
233 .collect()
234}
235
176236/// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
177237/// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
178238/// implied by the ADT being well formed.
compiler/rustc_hir_analysis/src/check/intrinsic.rs+2
......@@ -130,6 +130,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
130130 | sym::forget
131131 | sym::frem_algebraic
132132 | sym::fsub_algebraic
133 | sym::gpu_launch_sized_workgroup_mem
133134 | sym::is_val_statically_known
134135 | sym::log2f16
135136 | sym::log2f32
......@@ -297,6 +298,7 @@ pub(crate) fn check_intrinsic_type(
297298 sym::field_offset => (1, 0, vec![], tcx.types.usize),
298299 sym::rustc_peek => (1, 0, vec![param(0)], param(0)),
299300 sym::caller_location => (0, 0, vec![], tcx.caller_location_ty()),
301 sym::gpu_launch_sized_workgroup_mem => (1, 0, vec![], Ty::new_mut_ptr(tcx, param(0))),
300302 sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
301303 (1, 0, vec![], tcx.types.unit)
302304 }
compiler/rustc_hir_typeck/src/expr.rs+1-19
......@@ -57,25 +57,7 @@ use crate::{
5757impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5858 pub(crate) fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence {
5959 let has_attr = |id: HirId| -> bool {
60 for attr in self.tcx.hir_attrs(id) {
61 // For the purpose of rendering suggestions, disregard attributes
62 // that originate from desugaring of any kind. For example, `x?`
63 // desugars to `#[allow(unreachable_code)] match ...`. Failing to
64 // ignore the prefix attribute in the desugaring would cause this
65 // suggestion:
66 //
67 // let y: u32 = x?.try_into().unwrap();
68 // ++++++++++++++++++++
69 //
70 // to be rendered as:
71 //
72 // let y: u32 = (x?).try_into().unwrap();
73 // + +++++++++++++++++++++
74 if attr.span().desugaring_kind().is_none() {
75 return true;
76 }
77 }
78 false
60 self.tcx.hir_attrs(id).iter().any(hir::Attribute::is_prefix_attr_for_suggestions)
7961 };
8062
8163 // Special case: range expressions are desugared to struct literals in HIR,
compiler/rustc_lint/src/context.rs+1-6
......@@ -845,12 +845,7 @@ impl<'tcx> LateContext<'tcx> {
845845 /// be used for pretty-printing HIR by rustc_hir_pretty.
846846 pub fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence {
847847 let has_attr = |id: hir::HirId| -> bool {
848 for attr in self.tcx.hir_attrs(id) {
849 if attr.span().desugaring_kind().is_none() {
850 return true;
851 }
852 }
853 false
848 self.tcx.hir_attrs(id).iter().any(hir::Attribute::is_prefix_attr_for_suggestions)
854849 };
855850 expr.precedence(&has_attr)
856851 }
compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp+21-5
......@@ -299,10 +299,12 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
299299 .getCallee());
300300}
301301
302extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
303 const char *Name,
304 size_t NameLen,
305 LLVMTypeRef Ty) {
302// Get the global variable with the given name if it exists or create a new
303// external global.
304extern "C" LLVMValueRef
305LLVMRustGetOrInsertGlobalInAddrspace(LLVMModuleRef M, const char *Name,
306 size_t NameLen, LLVMTypeRef Ty,
307 unsigned int AddressSpace) {
306308 Module *Mod = unwrap(M);
307309 auto NameRef = StringRef(Name, NameLen);
308310
......@@ -313,10 +315,24 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
313315 GlobalVariable *GV = Mod->getGlobalVariable(NameRef, true);
314316 if (!GV)
315317 GV = new GlobalVariable(*Mod, unwrap(Ty), false,
316 GlobalValue::ExternalLinkage, nullptr, NameRef);
318 GlobalValue::ExternalLinkage, nullptr, NameRef,
319 nullptr, GlobalValue::NotThreadLocal, AddressSpace);
317320 return wrap(GV);
318321}
319322
323// Get the global variable with the given name if it exists or create a new
324// external global.
325extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
326 const char *Name,
327 size_t NameLen,
328 LLVMTypeRef Ty) {
329 Module *Mod = unwrap(M);
330 unsigned int AddressSpace =
331 Mod->getDataLayout().getDefaultGlobalsAddressSpace();
332 return LLVMRustGetOrInsertGlobalInAddrspace(M, Name, NameLen, Ty,
333 AddressSpace);
334}
335
320336// Must match the layout of `rustc_codegen_llvm::llvm::ffi::AttributeKind`.
321337enum class LLVMRustAttributeKind {
322338 AlwaysInline = 0,
compiler/rustc_resolve/src/diagnostics.rs+5
......@@ -1281,6 +1281,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
12811281 suggestions.extend(
12821282 BUILTIN_ATTRIBUTES
12831283 .iter()
1284 // These trace attributes are compiler-generated and have
1285 // deliberately invalid names.
1286 .filter(|attr| {
1287 !matches!(attr.name, sym::cfg_trace | sym::cfg_attr_trace)
1288 })
12841289 .map(|attr| TypoSuggestion::typo_from_name(attr.name, res)),
12851290 );
12861291 }
compiler/rustc_span/src/symbol.rs+1
......@@ -1033,6 +1033,7 @@ symbols! {
10331033 global_asm,
10341034 global_registration,
10351035 globs,
1036 gpu_launch_sized_workgroup_mem,
10361037 gt,
10371038 guard,
10381039 guard_patterns,
library/core/src/intrinsics/gpu.rs+45
......@@ -5,6 +5,51 @@
55
66#![unstable(feature = "gpu_intrinsics", issue = "none")]
77
8/// Returns the pointer to workgroup memory allocated at launch-time on GPUs.
9///
10/// Workgroup memory is a memory region that is shared between all threads in
11/// the same workgroup. It is faster to access than other memory but pointers do not
12/// work outside the workgroup where they were obtained.
13/// Workgroup memory can be allocated statically or after compilation, when
14/// launching a gpu-kernel. `gpu_launch_sized_workgroup_mem` returns the pointer to
15/// the memory that is allocated at launch-time.
16/// The size of this memory can differ between launches of a gpu-kernel, depending on
17/// what is specified at launch-time.
18/// However, the alignment is fixed by the kernel itself, at compile-time.
19///
20/// The returned pointer is the start of the workgroup memory region that is
21/// allocated at launch-time.
22/// All calls to `gpu_launch_sized_workgroup_mem` in a workgroup, independent of the
23/// generic type, return the same address, so alias the same memory.
24/// The returned pointer is aligned by at least the alignment of `T`.
25///
26/// If `gpu_launch_sized_workgroup_mem` is invoked multiple times with different
27/// types that have different alignment, then you may only rely on the resulting
28/// pointer having the alignment of `T` after a call to `gpu_launch_sized_workgroup_mem::<T>`
29/// has occurred in the current program execution.
30///
31/// # Safety
32///
33/// The pointer is safe to dereference from the start (the returned pointer) up to the
34/// size of workgroup memory that was specified when launching the current gpu-kernel.
35/// This allocated size is not related in any way to `T`.
36///
37/// The user must take care of synchronizing access to workgroup memory between
38/// threads in a workgroup. The usual data race requirements apply.
39///
40/// # Other APIs
41///
42/// CUDA and HIP call this dynamic shared memory, shared between threads in a block.
43/// OpenCL and SYCL call this local memory, shared between threads in a work-group.
44/// GLSL calls this shared memory, shared between invocations in a work group.
45/// DirectX calls this groupshared memory, shared between threads in a thread-group.
46#[must_use = "returns a pointer that does nothing unless used"]
47#[rustc_intrinsic]
48#[rustc_nounwind]
49#[unstable(feature = "gpu_launch_sized_workgroup_mem", issue = "135513")]
50#[cfg(any(target_arch = "amdgpu", target_arch = "nvptx64"))]
51pub fn gpu_launch_sized_workgroup_mem<T>() -> *mut T;
52
853/// Returns a pointer to the HSA kernel dispatch packet.
954///
1055/// A `gpu-kernel` on amdgpu is always launched through a kernel dispatch packet.
src/tools/tidy/src/style.rs+4
......@@ -222,6 +222,10 @@ fn should_ignore(line: &str) -> bool {
222222 || static_regex!(
223223 "\\s*//@ \\!?(count|files|has|has-dir|hasraw|matches|matchesraw|snapshot)\\s.*"
224224 ).is_match(line)
225 // Matching for FileCheck checks
226 || static_regex!(
227 "\\s*// [a-zA-Z0-9-_]*:\\s.*"
228 ).is_match(line)
225229}
226230
227231/// Returns `true` if `line` is allowed to be longer than the normal limit.
tests/codegen-llvm/gpu-launch-sized-workgroup-memory.rs created+41
......@@ -0,0 +1,41 @@
1// Checks that the GPU intrinsic to get launch-sized workgroup memory works
2// and correctly aligns the `external addrspace(...) global`s over multiple calls.
3
4//@ revisions: amdgpu nvptx-pre-llvm-23 nvptx-post-llvm-23
5//@ compile-flags: --crate-type=rlib -Copt-level=1
6//
7//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
8//@ [amdgpu] needs-llvm-components: amdgpu
9
10//@ [nvptx-pre-llvm-23] compile-flags: --target nvptx64-nvidia-cuda
11//@ [nvptx-pre-llvm-23] needs-llvm-components: nvptx
12//@ [nvptx-pre-llvm-23] max-llvm-major-version: 22
13//@ [nvptx-post-llvm-23] compile-flags: --target nvptx64-nvidia-cuda
14//@ [nvptx-post-llvm-23] needs-llvm-components: nvptx
15//@ [nvptx-post-llvm-23] min-llvm-version: 23
16//@ add-minicore
17#![feature(intrinsics, no_core, rustc_attrs)]
18#![no_core]
19
20extern crate minicore;
21
22#[rustc_intrinsic]
23#[rustc_nounwind]
24fn gpu_launch_sized_workgroup_mem<T>() -> *mut T;
25
26// amdgpu-DAG: @[[SMALL:[^ ]+]] = external addrspace(3) global [0 x i8], align 4
27// amdgpu-DAG: @[[BIG:[^ ]+]] = external addrspace(3) global [0 x i8], align 8
28// amdgpu: ret { ptr, ptr } { ptr addrspacecast (ptr addrspace(3) @[[SMALL]] to ptr), ptr addrspacecast (ptr addrspace(3) @[[BIG]] to ptr) }
29
30// nvptx-pre-llvm-23: @[[BIG:[^ ]+]] = external addrspace(3) global [0 x i8], align 8
31// nvptx-pre-llvm-23: ret { ptr, ptr } { ptr addrspacecast (ptr addrspace(3) @[[BIG]] to ptr), ptr addrspacecast (ptr addrspace(3) @[[BIG]] to ptr) }
32
33// nvptx-post-llvm-23-DAG: @[[SMALL:[^ ]+]] = external addrspace(3) global [0 x i8], align 4
34// nvptx-post-llvm-23-DAG: @[[BIG:[^ ]+]] = external addrspace(3) global [0 x i8], align 8
35// nvptx-post-llvm-23: ret { ptr, ptr } { ptr addrspacecast (ptr addrspace(3) @[[SMALL]] to ptr), ptr addrspacecast (ptr addrspace(3) @[[BIG]] to ptr) }
36#[unsafe(no_mangle)]
37pub fn fun() -> (*mut i32, *mut f64) {
38 let small = gpu_launch_sized_workgroup_mem::<i32>();
39 let big = gpu_launch_sized_workgroup_mem::<f64>(); // Increase alignment to 8
40 (small, big)
41}
tests/codegen-llvm/link_section.rs+9-9
......@@ -3,14 +3,14 @@
33
44#![crate_type = "lib"]
55
6// CHECK: @VAR1 = {{(dso_local )?}}constant [4 x i8] c"\01\00\00\00", section ".test_one"
6// CHECK: @VAR1 = {{(dso_local )?}}constant [4 x i8] c"\01\00\00\00", section "__TEST,one"
77#[no_mangle]
8#[link_section = ".test_one"]
8#[link_section = "__TEST,one"]
99#[cfg(target_endian = "little")]
1010pub static VAR1: u32 = 1;
1111
1212#[no_mangle]
13#[link_section = ".test_one"]
13#[link_section = "__TEST,one"]
1414#[cfg(target_endian = "big")]
1515pub static VAR1: u32 = 0x01000000;
1616
......@@ -19,17 +19,17 @@ pub enum E {
1919 B(f32),
2020}
2121
22// CHECK: @VAR2 = {{(dso_local )?}}constant {{.*}}, section ".test_two"
22// CHECK: @VAR2 = {{(dso_local )?}}constant {{.*}}, section "__TEST,two"
2323#[no_mangle]
24#[link_section = ".test_two"]
24#[link_section = "__TEST,two"]
2525pub static VAR2: E = E::A(666);
2626
27// CHECK: @VAR3 = {{(dso_local )?}}constant {{.*}}, section ".test_three"
27// CHECK: @VAR3 = {{(dso_local )?}}constant {{.*}}, section "__TEST,three"
2828#[no_mangle]
29#[link_section = ".test_three"]
29#[link_section = "__TEST,three"]
3030pub static VAR3: E = E::B(1.);
3131
32// CHECK: define {{(dso_local )?}}void @fn1() {{.*}} section ".test_four" {
32// CHECK: define {{(dso_local )?}}void @fn1() {{.*}} section "__TEST,four" {
3333#[no_mangle]
34#[link_section = ".test_four"]
34#[link_section = "__TEST,four"]
3535pub fn fn1() {}
tests/codegen-llvm/naked-fn/naked-functions.rs+6-3
......@@ -22,7 +22,7 @@
2222//@[thumb] needs-llvm-components: arm
2323
2424#![crate_type = "lib"]
25#![feature(no_core, lang_items, rustc_attrs)]
25#![feature(no_core, lang_items, rustc_attrs, cfg_target_object_format)]
2626#![no_core]
2727
2828extern crate minicore;
......@@ -170,14 +170,17 @@ pub extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
170170}
171171
172172// linux,linux_no_function_sections: .pushsection .text.some_different_name,\22ax\22, @progbits
173// macos: .pushsection .text.some_different_name,regular,pure_instructions
173// macos: .pushsection __TEXT,different,regular,pure_instructions
174174// win_x86_msvc,win_x86_gnu,win_i686_gnu: .section .text.some_different_name,\22xr\22
175175// win_x86_gnu_function_sections: .section .text.some_different_name,\22xr\22
176176// thumb: .pushsection .text.some_different_name,\22ax\22, %progbits
177177// CHECK-LABEL: test_link_section:
178178#[no_mangle]
179179#[unsafe(naked)]
180#[link_section = ".text.some_different_name"]
180#[link_section = cfg_select!(
181 target_object_format = "mach-o" => "__TEXT,different",
182 _ => ".text.some_different_name"
183)]
181184pub extern "C" fn test_link_section() {
182185 cfg_select! {
183186 all(target_arch = "arm", target_feature = "thumb-mode") => {
tests/run-make/remap-path-prefix-edge-cases/rmake.rs created+51
......@@ -0,0 +1,51 @@
1//! This test checks multiple edge-case of `--remap-path-prefix`.
2//!
3//! It tests:
4//! - `=` sign in FROM path
5//! - multiple path remappings
6//! - multiple conflicting path remappings
7
8//@ ignore-windows (does not support directories with = sign)
9
10use std::path::Path;
11
12use run_make_support::{
13 CompletedProcess, assert_contains, assert_not_contains, cwd, rfs, run_in_tmpdir, rustc, rustdoc,
14};
15
16fn main() {
17 run_in_tmpdir(|| {
18 let out_dir = cwd();
19
20 // Create a directory with an `=` sign
21 let eq_dir = out_dir.join("path=with=equal");
22 rfs::create_dir_all(&eq_dir);
23
24 let src_path = eq_dir.join("lib.rs");
25 rfs::write(&src_path, "pub fn broken_func() { ");
26
27 // Use multiple remap args and conflicting remappings
28 let remap_args = [
29 format!("--remap-path-prefix={}={}", eq_dir.display(), "REMAPPED_DIR"),
30 format!("--remap-path-prefix={}={}", eq_dir.display(), "REMAPPED_DIR2"),
31 ];
32
33 fn run_test(cmd: impl FnOnce() -> CompletedProcess) {
34 let output = cmd();
35 let stderr = output.stderr_utf8();
36
37 // Checks the diagnostic output
38 assert_contains(&stderr, "REMAPPED_DIR2/lib.rs");
39 assert_not_contains(&stderr, "REMAPPED_DIR/");
40 assert_not_contains(&stderr, "path=with=equal");
41 };
42
43 // Test with rustc
44 run_test(|| rustc().input(&src_path).args(&remap_args).run_fail());
45
46 // Test with rustdoc
47 run_test(|| {
48 rustdoc().input(&src_path).arg("-Zunstable-options").args(&remap_args).run_fail()
49 });
50 });
51}
tests/rustdoc-html/attributes-2021-edition.rs+2-2
......@@ -9,6 +9,6 @@ pub extern "C" fn f() {}
99#[export_name = "bar"]
1010pub extern "C" fn g() {}
1111
12//@ has foo/fn.example.html '//pre[@class="rust item-decl"]' '#[unsafe(link_section = ".text")]'
13#[link_section = ".text"]
12//@ has foo/fn.example.html '//pre[@class="rust item-decl"]' '#[unsafe(link_section = "__TEXT,__text")]'
13#[link_section = "__TEXT,__text"]
1414pub extern "C" fn example() {}
tests/rustdoc-html/attributes.rs+1
......@@ -1,4 +1,5 @@
11//@ edition: 2024
2//@ only-linux
23#![crate_name = "foo"]
34
45//@ has foo/fn.f.html '//*[@class="code-attribute"]' '#[unsafe(no_mangle)]'
tests/rustdoc-html/inline_cross/attributes.rs+1-1
......@@ -9,7 +9,7 @@
99pub use attributes::no_mangle;
1010
1111//@ has 'user/fn.link_section.html' '//pre[@class="rust item-decl"]' \
12// '#[unsafe(link_section = ".here")]'
12// '#[unsafe(link_section = "__TEXT,__here")]'
1313pub use attributes::link_section;
1414
1515//@ has 'user/fn.export_name.html' '//pre[@class="rust item-decl"]' \
tests/rustdoc-html/inline_cross/auxiliary/attributes.rs+1-1
......@@ -1,7 +1,7 @@
11#[unsafe(no_mangle)]
22pub fn no_mangle() {}
33
4#[unsafe(link_section = ".here")]
4#[unsafe(link_section = "__TEXT,__here")]
55pub fn link_section() {}
66
77#[unsafe(export_name = "exonym")]
tests/rustdoc-json/attrs/link_section_2021.rs+2-2
......@@ -2,6 +2,6 @@
22#![no_std]
33
44//@ count "$.index[?(@.name=='example')].attrs[*]" 1
5//@ is "$.index[?(@.name=='example')].attrs[*].link_section" '".text"'
6#[link_section = ".text"]
5//@ is "$.index[?(@.name=='example')].attrs[*].link_section" '"__TEXT,__text"'
6#[link_section = "__TEXT,__text"]
77pub extern "C" fn example() {}
tests/rustdoc-json/attrs/link_section_2024.rs+2-2
......@@ -5,6 +5,6 @@
55// However, the unsafe qualification is not shown by rustdoc.
66
77//@ count "$.index[?(@.name=='example')].attrs[*]" 1
8//@ is "$.index[?(@.name=='example')].attrs[*].link_section" '".text"'
9#[unsafe(link_section = ".text")]
8//@ is "$.index[?(@.name=='example')].attrs[*].link_section" '"__TEXT,__text"'
9#[unsafe(link_section = "__TEXT,__text")]
1010pub extern "C" fn example() {}
tests/ui/README.md-4
......@@ -412,10 +412,6 @@ Tests for quality of diagnostics involving suppression of cascading errors in so
412412
413413Tests for built-in derive macros (`Debug`, `Clone`, etc.) when used in conjunction with built-in `#[derive(..)]` attributes.
414414
415## `tests/ui/deriving/`: Derive Macro
416
417**FIXME**: Coalesce with `tests/ui/derives`.
418
419415## `tests/ui/dest-prop/` Destination Propagation
420416
421417**FIXME**: Contains a single test for the `DestProp` mir-opt, should probably be rehomed.
tests/ui/asm/naked-functions.rs+5-2
......@@ -3,7 +3,7 @@
33//@ ignore-spirv
44//@ reference: attributes.codegen.naked.body
55
6#![feature(asm_unwind, linkage, rustc_attrs)]
6#![feature(asm_unwind, linkage, rustc_attrs, cfg_target_object_format)]
77#![crate_type = "lib"]
88
99use std::arch::{asm, naked_asm};
......@@ -200,7 +200,10 @@ pub extern "C" fn compatible_must_use_attributes() -> u64 {
200200}
201201
202202#[export_name = "exported_function_name"]
203#[link_section = ".custom_section"]
203#[link_section = cfg_select!(
204 target_object_format = "mach-o" => "__TEXT,__custom",
205 _ => ".custom",
206)]
204207#[unsafe(naked)]
205208pub extern "C" fn compatible_ffi_attributes_1() {
206209 naked_asm!("", options(raw));
tests/ui/attributes/attr-on-mac-call.rs+1-1
......@@ -27,7 +27,7 @@ fn main() {
2727 #[link_name = "x"]
2828 //~^ WARN attribute cannot be used on macro calls
2929 //~| WARN previously accepted
30 #[link_section = "x"]
30 #[link_section = "__TEXT,__text"]
3131 //~^ WARN attribute cannot be used on macro calls
3232 //~| WARN previously accepted
3333 #[link_ordinal(42)]
tests/ui/attributes/attr-on-mac-call.stderr+2-2
......@@ -78,8 +78,8 @@ LL | #[link_name = "x"]
7878warning: `#[link_section]` attribute cannot be used on macro calls
7979 --> $DIR/attr-on-mac-call.rs:30:5
8080 |
81LL | #[link_section = "x"]
82 | ^^^^^^^^^^^^^^^^^^^^^
81LL | #[link_section = "__TEXT,__text"]
82 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8383 |
8484 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8585 = help: `#[link_section]` can be applied to functions and statics
tests/ui/attributes/codegen_attr_on_required_trait_method.rs+1-1
......@@ -7,7 +7,7 @@ trait Test {
77 //~^ ERROR cannot be used on required trait methods [unused_attributes]
88 //~| WARN previously accepted
99 fn method1(&self);
10 #[link_section = ".text"]
10 #[link_section = "__TEXT,__text"]
1111 //~^ ERROR cannot be used on required trait methods [unused_attributes]
1212 //~| WARN previously accepted
1313 fn method2(&self);
tests/ui/attributes/codegen_attr_on_required_trait_method.stderr+2-2
......@@ -15,8 +15,8 @@ LL | #![deny(unused_attributes)]
1515error: `#[link_section]` attribute cannot be used on required trait methods
1616 --> $DIR/codegen_attr_on_required_trait_method.rs:10:5
1717 |
18LL | #[link_section = ".text"]
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^
18LL | #[link_section = "__TEXT,__text"]
19 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2020 |
2121 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2222 = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
tests/ui/conditional-compilation/cfg-attr-parsed-span-issue-154801.rs created+11
......@@ -0,0 +1,11 @@
1fn main() {
2 let _x = 30;
3 #[cfg_attr(, (cc))] //~ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `,`
4 _x //~ ERROR mismatched types
5}
6
7fn inline_case() {
8 let _x = 30;
9 #[inline] //~ ERROR `#[inline]` attribute cannot be used on expressions
10 _x //~ ERROR mismatched types
11}
tests/ui/conditional-compilation/cfg-attr-parsed-span-issue-154801.stderr created+42
......@@ -0,0 +1,42 @@
1error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `,`
2 --> $DIR/cfg-attr-parsed-span-issue-154801.rs:3:16
3 |
4LL | #[cfg_attr(, (cc))]
5 | ^
6 |
7 = note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
8help: must be of the form
9 |
10LL - #[cfg_attr(, (cc))]
11LL + #[cfg_attr(predicate, attr1, attr2, ...)]
12 |
13
14error: `#[inline]` attribute cannot be used on expressions
15 --> $DIR/cfg-attr-parsed-span-issue-154801.rs:9:5
16 |
17LL | #[inline]
18 | ^^^^^^^^^
19 |
20 = help: `#[inline]` can only be applied to functions
21
22error[E0308]: mismatched types
23 --> $DIR/cfg-attr-parsed-span-issue-154801.rs:4:5
24 |
25LL | fn main() {
26 | - expected `()` because of default return type
27...
28LL | _x
29 | ^^ expected `()`, found integer
30
31error[E0308]: mismatched types
32 --> $DIR/cfg-attr-parsed-span-issue-154801.rs:10:5
33 |
34LL | fn inline_case() {
35 | - help: try adding a return type: `-> i32`
36...
37LL | _x
38 | ^^ expected `()`, found integer
39
40error: aborting due to 4 previous errors
41
42For more information about this error, try `rustc --explain E0308`.
tests/ui/consts/drop-impl-nonconst-drop-field.rs created+32
......@@ -0,0 +1,32 @@
1#![feature(const_trait_impl)]
2#![feature(const_destruct)]
3
4use std::marker::Destruct;
5
6struct NotConstDrop;
7
8impl Drop for NotConstDrop {
9 fn drop(&mut self) {}
10}
11
12struct ConstDrop(NotConstDrop);
13//~^ ERROR: `NotConstDrop` does not implement `[const] Destruct`
14
15impl const Drop for ConstDrop {
16 fn drop(&mut self) {}
17}
18
19struct ConstDrop2<T>(T);
20//~^ ERROR: `T` does not implement `[const] Destruct`
21
22impl<T> const Drop for ConstDrop2<T> {
23 fn drop(&mut self) {}
24}
25
26struct ConstDrop3<T>(T);
27
28impl<T: [const] Destruct> const Drop for ConstDrop3<T> {
29 fn drop(&mut self) {}
30}
31
32fn main() {}
tests/ui/consts/drop-impl-nonconst-drop-field.stderr created+27
......@@ -0,0 +1,27 @@
1error[E0367]: `NotConstDrop` does not implement `[const] Destruct`
2 --> $DIR/drop-impl-nonconst-drop-field.rs:12:18
3 |
4LL | struct ConstDrop(NotConstDrop);
5 | ^^^^^^^^^^^^
6 |
7note: required for this `Drop` impl
8 --> $DIR/drop-impl-nonconst-drop-field.rs:15:1
9 |
10LL | impl const Drop for ConstDrop {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
13error[E0367]: `T` does not implement `[const] Destruct`
14 --> $DIR/drop-impl-nonconst-drop-field.rs:19:22
15 |
16LL | struct ConstDrop2<T>(T);
17 | ^
18 |
19note: required for this `Drop` impl
20 --> $DIR/drop-impl-nonconst-drop-field.rs:22:1
21 |
22LL | impl<T> const Drop for ConstDrop2<T> {
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24
25error: aborting due to 2 previous errors
26
27For more information about this error, try `rustc --explain E0367`.
tests/ui/derives/auxiliary/derive-no-std.rs created+29
......@@ -0,0 +1,29 @@
1//@ no-prefer-dynamic
2
3#![crate_type = "rlib"]
4#![no_std]
5
6// Issue #16803
7
8#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
9 Debug, Default, Copy)]
10pub struct Foo {
11 pub x: u32,
12}
13
14#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
15 Debug, Copy)]
16pub enum Bar {
17 Qux,
18 Quux(u32),
19}
20
21#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
22 Debug, Copy)]
23pub enum Void {}
24#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
25 Debug, Copy)]
26pub struct Empty;
27#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
28 Debug, Copy)]
29pub struct AlsoEmpty {}
tests/ui/derives/auxiliary/rustc-serialize.rs deleted-16
......@@ -1,16 +0,0 @@
1#![crate_type = "lib"]
2
3pub trait Decoder {
4 type Error;
5
6 fn read_enum<T, F>(&mut self, name: &str, f: F) -> Result<T, Self::Error>
7 where F: FnOnce(&mut Self) -> Result<T, Self::Error>;
8 fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F)
9 -> Result<T, Self::Error>
10 where F: FnMut(&mut Self, usize) -> Result<T, Self::Error>;
11
12}
13
14pub trait Decodable: Sized {
15 fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error>;
16}
tests/ui/derives/clone-copy/clone-vector-element-size.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/104037.
2//! LLVM used to hit an assertion "Vector elements must have same size"
3//! when compiling derived Clone with MIR optimisation level of 3.
4
5//@ build-pass
6//@ compile-flags: -Zmir-opt-level=3 -Copt-level=3
7
8#[derive(Clone)]
9pub struct Foo(Bar, u32);
10
11#[derive(Clone, Copy)]
12pub struct Bar(u8, u8, u8);
13
14fn main() {
15 let foo: Vec<Foo> = Vec::new();
16 let _ = foo.clone();
17}
tests/ui/derives/clone-copy/copy-drop-mutually-exclusive.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for issue #20126: Copy and Drop traits are mutually exclusive
2
3#[derive(Copy, Clone)]
4struct Foo; //~ ERROR the trait `Copy` cannot be implemented
5
6impl Drop for Foo {
7 fn drop(&mut self) {}
8}
9
10#[derive(Copy, Clone)]
11struct Bar<T>(::std::marker::PhantomData<T>); //~ ERROR the trait `Copy` cannot be implemented
12
13impl<T> Drop for Bar<T> {
14 fn drop(&mut self) {}
15}
16
17fn main() {}
tests/ui/derives/clone-copy/copy-drop-mutually-exclusive.stderr created+31
......@@ -0,0 +1,31 @@
1error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
2 --> $DIR/copy-drop-mutually-exclusive.rs:4:8
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- in this derive macro expansion
6LL | struct Foo;
7 | ^^^ `Copy` not allowed on types with destructors
8 |
9note: destructor declared here
10 --> $DIR/copy-drop-mutually-exclusive.rs:7:5
11 |
12LL | fn drop(&mut self) {}
13 | ^^^^^^^^^^^^^^^^^^
14
15error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
16 --> $DIR/copy-drop-mutually-exclusive.rs:11:8
17 |
18LL | #[derive(Copy, Clone)]
19 | ---- in this derive macro expansion
20LL | struct Bar<T>(::std::marker::PhantomData<T>);
21 | ^^^ `Copy` not allowed on types with destructors
22 |
23note: destructor declared here
24 --> $DIR/copy-drop-mutually-exclusive.rs:14:5
25 |
26LL | fn drop(&mut self) {}
27 | ^^^^^^^^^^^^^^^^^^
28
29error: aborting due to 2 previous errors
30
31For more information about this error, try `rustc --explain E0184`.
tests/ui/derives/clone-copy/derive-clone-basic.rs created+65
......@@ -0,0 +1,65 @@
1//! Make sure that `derive(Clone)` works for simple structs and enums.
2//@ run-pass
3#![allow(dead_code)]
4
5#[derive(Clone)]
6enum SimpleEnum {
7 A,
8 B(()),
9 C,
10}
11
12#[derive(Clone)]
13enum GenericEnum<T, U> {
14 A(T),
15 B(T, U),
16 C,
17}
18
19#[derive(Clone)]
20struct TupleStruct((), ());
21
22#[derive(Clone)]
23struct GenericStruct<T> {
24 foo: (),
25 bar: (),
26 baz: T,
27}
28
29#[derive(Clone)]
30struct GenericTupleStruct<T>(T, ());
31
32#[derive(Clone)]
33struct ManyPrimitives {
34 _int: isize,
35 _i8: i8,
36 _i16: i16,
37 _i32: i32,
38 _i64: i64,
39
40 _uint: usize,
41 _u8: u8,
42 _u16: u16,
43 _u32: u32,
44 _u64: u64,
45
46 _f32: f32,
47 _f64: f64,
48
49 _bool: bool,
50 _char: char,
51 _nil: (),
52}
53
54// Regression test for issue #30244
55#[derive(Copy, Clone)]
56struct Array {
57 arr: [[u8; 256]; 4],
58}
59
60pub fn main() {
61 let _ = SimpleEnum::A.clone();
62 let _ = GenericEnum::A::<isize, isize>(1).clone();
63 let _ = GenericStruct { foo: (), bar: (), baz: 1 }.clone();
64 let _ = GenericTupleStruct(1, ()).clone();
65}
tests/ui/derives/clone-copy/derives-span-Clone.rs created+30
......@@ -0,0 +1,30 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Clone)] line.
3
4struct Error;
5
6#[derive(Clone)]
7enum EnumStructVariant {
8 A {
9 x: Error, //~ ERROR
10 },
11}
12
13#[derive(Clone)]
14enum EnumTupleVariant {
15 A(
16 Error, //~ ERROR
17 ),
18}
19
20#[derive(Clone)]
21struct Struct {
22 x: Error, //~ ERROR
23}
24
25#[derive(Clone)]
26struct TupleStruct(
27 Error, //~ ERROR
28);
29
30fn main() {}
tests/ui/derives/clone-copy/derives-span-Clone.stderr created+63
......@@ -0,0 +1,63 @@
1error[E0277]: the trait bound `Error: Clone` is not satisfied
2 --> $DIR/derives-span-Clone.rs:9:9
3 |
4LL | #[derive(Clone)]
5 | ----- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Clone` is not implemented for `Error`
9 |
10help: consider annotating `Error` with `#[derive(Clone)]`
11 |
12LL + #[derive(Clone)]
13LL | struct Error;
14 |
15
16error[E0277]: the trait bound `Error: Clone` is not satisfied
17 --> $DIR/derives-span-Clone.rs:16:9
18 |
19LL | #[derive(Clone)]
20 | ----- in this derive macro expansion
21...
22LL | Error,
23 | ^^^^^ the trait `Clone` is not implemented for `Error`
24 |
25help: consider annotating `Error` with `#[derive(Clone)]`
26 |
27LL + #[derive(Clone)]
28LL | struct Error;
29 |
30
31error[E0277]: the trait bound `Error: Clone` is not satisfied
32 --> $DIR/derives-span-Clone.rs:22:5
33 |
34LL | #[derive(Clone)]
35 | ----- in this derive macro expansion
36LL | struct Struct {
37LL | x: Error,
38 | ^^^^^^^^ the trait `Clone` is not implemented for `Error`
39 |
40help: consider annotating `Error` with `#[derive(Clone)]`
41 |
42LL + #[derive(Clone)]
43LL | struct Error;
44 |
45
46error[E0277]: the trait bound `Error: Clone` is not satisfied
47 --> $DIR/derives-span-Clone.rs:27:5
48 |
49LL | #[derive(Clone)]
50 | ----- in this derive macro expansion
51LL | struct TupleStruct(
52LL | Error,
53 | ^^^^^ the trait `Clone` is not implemented for `Error`
54 |
55help: consider annotating `Error` with `#[derive(Clone)]`
56 |
57LL + #[derive(Clone)]
58LL | struct Error;
59 |
60
61error: aborting due to 4 previous errors
62
63For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/clone-copy/deriving-copyclone.rs created+37
......@@ -0,0 +1,37 @@
1// this will get a no-op Clone impl
2#[derive(Copy, Clone)]
3struct A {
4 a: i32,
5 b: i64
6}
7
8// this will get a deep Clone impl
9#[derive(Copy, Clone)]
10struct B<T> {
11 a: i32,
12 b: T
13}
14
15struct C; // not Copy or Clone
16#[derive(Clone)] struct D; // Clone but not Copy
17
18fn is_copy<T: Copy>(_: T) {}
19fn is_clone<T: Clone>(_: T) {}
20
21fn main() {
22 // A can be copied and cloned
23 is_copy(A { a: 1, b: 2 });
24 is_clone(A { a: 1, b: 2 });
25
26 // B<i32> can be copied and cloned
27 is_copy(B { a: 1, b: 2 });
28 is_clone(B { a: 1, b: 2 });
29
30 // B<C> cannot be copied or cloned
31 is_copy(B { a: 1, b: C }); //~ ERROR Copy
32 is_clone(B { a: 1, b: C }); //~ ERROR Clone
33
34 // B<D> can be cloned but not copied
35 is_copy(B { a: 1, b: D }); //~ ERROR Copy
36 is_clone(B { a: 1, b: D });
37}
tests/ui/derives/clone-copy/deriving-copyclone.stderr created+79
......@@ -0,0 +1,79 @@
1error[E0277]: the trait bound `B<C>: Copy` is not satisfied
2 --> $DIR/deriving-copyclone.rs:31:26
3 |
4LL | is_copy(B { a: 1, b: C });
5 | ------- ^ the trait `Copy` is not implemented for `B<C>`
6 | |
7 | required by a bound introduced by this call
8 |
9note: required for `B<C>` to implement `Copy`
10 --> $DIR/deriving-copyclone.rs:10:8
11 |
12LL | #[derive(Copy, Clone)]
13 | ---- in this derive macro expansion
14LL | struct B<T> {
15 | ^ - type parameter would need to implement `Copy`
16note: required by a bound in `is_copy`
17 --> $DIR/deriving-copyclone.rs:18:15
18 |
19LL | fn is_copy<T: Copy>(_: T) {}
20 | ^^^^ required by this bound in `is_copy`
21help: consider borrowing here
22 |
23LL | is_copy(B { a: 1, b: &C });
24 | +
25
26error[E0277]: the trait bound `B<C>: Clone` is not satisfied
27 --> $DIR/deriving-copyclone.rs:32:27
28 |
29LL | is_clone(B { a: 1, b: C });
30 | -------- ^ the trait `Clone` is not implemented for `B<C>`
31 | |
32 | required by a bound introduced by this call
33 |
34note: required for `B<C>` to implement `Clone`
35 --> $DIR/deriving-copyclone.rs:10:8
36 |
37LL | #[derive(Copy, Clone)]
38 | ----- in this derive macro expansion
39LL | struct B<T> {
40 | ^ - type parameter would need to implement `Clone`
41 = help: consider manually implementing `Clone` to avoid undesired bounds
42note: required by a bound in `is_clone`
43 --> $DIR/deriving-copyclone.rs:19:16
44 |
45LL | fn is_clone<T: Clone>(_: T) {}
46 | ^^^^^ required by this bound in `is_clone`
47help: consider borrowing here
48 |
49LL | is_clone(B { a: 1, b: &C });
50 | +
51
52error[E0277]: the trait bound `B<D>: Copy` is not satisfied
53 --> $DIR/deriving-copyclone.rs:35:26
54 |
55LL | is_copy(B { a: 1, b: D });
56 | ------- ^ the trait `Copy` is not implemented for `B<D>`
57 | |
58 | required by a bound introduced by this call
59 |
60note: required for `B<D>` to implement `Copy`
61 --> $DIR/deriving-copyclone.rs:10:8
62 |
63LL | #[derive(Copy, Clone)]
64 | ---- in this derive macro expansion
65LL | struct B<T> {
66 | ^ - type parameter would need to implement `Copy`
67note: required by a bound in `is_copy`
68 --> $DIR/deriving-copyclone.rs:18:15
69 |
70LL | fn is_copy<T: Copy>(_: T) {}
71 | ^^^^ required by this bound in `is_copy`
72help: consider borrowing here
73 |
74LL | is_copy(B { a: 1, b: &D });
75 | +
76
77error: aborting due to 3 previous errors
78
79For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/clone-copy/duplicate-derive-copy-clone-diagnostics.rs created+11
......@@ -0,0 +1,11 @@
1// Duplicate implementations of Copy/Clone should not trigger
2// borrow check warnings
3// See #131083
4
5#[derive(Copy, Clone)]
6#[derive(Copy, Clone)]
7//~^ ERROR conflicting implementations of trait `Clone` for type `E`
8//~| ERROR conflicting implementations of trait `Copy` for type `E`
9enum E {}
10
11fn main() {}
tests/ui/derives/clone-copy/duplicate-derive-copy-clone-diagnostics.stderr created+19
......@@ -0,0 +1,19 @@
1error[E0119]: conflicting implementations of trait `Copy` for type `E`
2 --> $DIR/duplicate-derive-copy-clone-diagnostics.rs:6:10
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- first implementation here
6LL | #[derive(Copy, Clone)]
7 | ^^^^ conflicting implementation for `E`
8
9error[E0119]: conflicting implementations of trait `Clone` for type `E`
10 --> $DIR/duplicate-derive-copy-clone-diagnostics.rs:6:16
11 |
12LL | #[derive(Copy, Clone)]
13 | ----- first implementation here
14LL | #[derive(Copy, Clone)]
15 | ^^^^^ conflicting implementation for `E`
16
17error: aborting due to 2 previous errors
18
19For more information about this error, try `rustc --explain E0119`.
tests/ui/derives/clone-copy/misbehaving-clone-impl.rs created+38
......@@ -0,0 +1,38 @@
1//@ run-pass
2//! Test that #[derive(Copy, Clone)] produces a shallow copy
3//! even when a member violates RFC 1521
4
5use std::sync::atomic::{AtomicBool, Ordering};
6
7/// A struct that pretends to be Copy, but actually does something
8/// in its Clone impl
9#[derive(Copy)]
10struct Liar;
11
12/// Static cooperating with the rogue Clone impl
13static CLONED: AtomicBool = AtomicBool::new(false);
14
15impl Clone for Liar {
16 fn clone(&self) -> Self {
17 // this makes Clone vs Copy observable
18 CLONED.store(true, Ordering::SeqCst);
19
20 *self
21 }
22}
23
24/// This struct is actually Copy... at least, it thinks it is!
25#[derive(Copy, Clone)]
26struct Innocent(#[allow(dead_code)] Liar);
27
28impl Innocent {
29 fn new() -> Self {
30 Innocent(Liar)
31 }
32}
33
34fn main() {
35 let _ = Innocent::new().clone();
36 // if Innocent was byte-for-byte copied, CLONED will still be false
37 assert!(!CLONED.load(Ordering::SeqCst));
38}
tests/ui/derives/clone-vector-element-size.rs deleted-17
......@@ -1,17 +0,0 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/104037.
2//! LLVM used to hit an assertion "Vector elements must have same size"
3//! when compiling derived Clone with MIR optimisation level of 3.
4
5//@ build-pass
6//@ compile-flags: -Zmir-opt-level=3 -Copt-level=3
7
8#[derive(Clone)]
9pub struct Foo(Bar, u32);
10
11#[derive(Clone, Copy)]
12pub struct Bar(u8, u8, u8);
13
14fn main() {
15 let foo: Vec<Foo> = Vec::new();
16 let _ = foo.clone();
17}
tests/ui/derives/coercepointee/auxiliary/another-proc-macro.rs created+41
......@@ -0,0 +1,41 @@
1#![feature(proc_macro_quote)]
2
3extern crate proc_macro;
4
5use proc_macro::{TokenStream, quote};
6
7#[proc_macro_derive(AnotherMacro, attributes(pointee))]
8pub fn derive(_input: TokenStream) -> TokenStream {
9 quote! {
10 const _: () = {
11 const ANOTHER_MACRO_DERIVED: () = ();
12 };
13 }
14 .into()
15}
16
17#[proc_macro_attribute]
18pub fn pointee(
19 _attr: proc_macro::TokenStream,
20 _item: proc_macro::TokenStream,
21) -> proc_macro::TokenStream {
22 quote! {
23 const _: () = {
24 const POINTEE_MACRO_ATTR_DERIVED: () = ();
25 };
26 }
27 .into()
28}
29
30#[proc_macro_attribute]
31pub fn default(
32 _attr: proc_macro::TokenStream,
33 _item: proc_macro::TokenStream,
34) -> proc_macro::TokenStream {
35 quote! {
36 const _: () = {
37 const DEFAULT_MACRO_ATTR_DERIVED: () = ();
38 };
39 }
40 .into()
41}
tests/ui/derives/coercepointee/auxiliary/malicious-macro.rs created+31
......@@ -0,0 +1,31 @@
1//@ edition: 2024
2
3extern crate proc_macro;
4
5use proc_macro::{Delimiter, TokenStream, TokenTree};
6
7#[proc_macro_attribute]
8pub fn norepr(_: TokenStream, input: TokenStream) -> TokenStream {
9 let mut tokens = vec![];
10 let mut tts = input.into_iter().fuse().peekable();
11 loop {
12 let Some(token) = tts.next() else { break };
13 if let TokenTree::Punct(punct) = &token
14 && punct.as_char() == '#'
15 {
16 if let Some(TokenTree::Group(group)) = tts.peek()
17 && let Delimiter::Bracket = group.delimiter()
18 && let Some(TokenTree::Ident(ident)) = group.stream().into_iter().next()
19 && ident.to_string() == "repr"
20 {
21 let _ = tts.next();
22 // skip '#' and '[repr(..)]
23 } else {
24 tokens.push(token);
25 }
26 } else {
27 tokens.push(token);
28 }
29 }
30 tokens.into_iter().collect()
31}
tests/ui/derives/coercepointee/built-in-proc-macro-scope.rs created+26
......@@ -0,0 +1,26 @@
1//@ check-pass
2//@ proc-macro: another-proc-macro.rs
3//@ compile-flags: -Zunpretty=expanded
4//@ edition:2015
5
6#![feature(derive_coerce_pointee)]
7
8#[macro_use]
9extern crate another_proc_macro;
10
11use another_proc_macro::{AnotherMacro, pointee};
12
13#[derive(core::marker::CoercePointee)]
14#[repr(transparent)]
15pub struct Ptr<'a, #[pointee] T: ?Sized> {
16 data: &'a mut T,
17}
18
19#[pointee]
20fn f() {}
21
22#[derive(AnotherMacro)]
23#[pointee]
24struct MyStruct;
25
26fn main() {}
tests/ui/derives/coercepointee/built-in-proc-macro-scope.stdout created+45
......@@ -0,0 +1,45 @@
1#![feature(prelude_import)]
2#![no_std]
3//@ check-pass
4//@ proc-macro: another-proc-macro.rs
5//@ compile-flags: -Zunpretty=expanded
6//@ edition:2015
7
8#![feature(derive_coerce_pointee)]
9extern crate std;
10#[prelude_import]
11use ::std::prelude::rust_2015::*;
12
13#[macro_use]
14extern crate another_proc_macro;
15
16use another_proc_macro::{AnotherMacro, pointee};
17
18#[repr(transparent)]
19pub struct Ptr<'a, #[pointee] T: ?Sized> {
20 data: &'a mut T,
21}
22#[automatically_derived]
23impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for Ptr<'a, T> { }
24#[automatically_derived]
25impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
26 ::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
27}
28#[automatically_derived]
29impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
30 ::core::ops::CoerceUnsized<Ptr<'a, __S>> for Ptr<'a, T> {
31}
32
33
34
35const _: () =
36 {
37 const POINTEE_MACRO_ATTR_DERIVED: () = ();
38 };
39#[pointee]
40struct MyStruct;
41const _: () =
42 {
43 const ANOTHER_MACRO_DERIVED: () = ();
44 };
45fn main() {}
tests/ui/derives/coercepointee/coerce-pointee-bounds-issue-127647.rs created+78
......@@ -0,0 +1,78 @@
1//@ check-pass
2
3#![feature(derive_coerce_pointee)]
4
5#[derive(core::marker::CoercePointee)]
6#[repr(transparent)]
7pub struct Ptr<'a, #[pointee] T: OnDrop + ?Sized, X> {
8 data: &'a mut T,
9 x: core::marker::PhantomData<X>,
10}
11
12pub trait OnDrop {
13 fn on_drop(&mut self);
14}
15
16#[derive(core::marker::CoercePointee)]
17#[repr(transparent)]
18pub struct Ptr2<'a, #[pointee] T: ?Sized, X>
19where
20 T: OnDrop,
21{
22 data: &'a mut T,
23 x: core::marker::PhantomData<X>,
24}
25
26pub trait MyTrait<T: ?Sized> {}
27
28#[derive(core::marker::CoercePointee)]
29#[repr(transparent)]
30pub struct Ptr3<'a, #[pointee] T: ?Sized, X>
31where
32 T: MyTrait<T>,
33{
34 data: &'a mut T,
35 x: core::marker::PhantomData<X>,
36}
37
38#[derive(core::marker::CoercePointee)]
39#[repr(transparent)]
40pub struct Ptr4<'a, #[pointee] T: MyTrait<T> + ?Sized, X> {
41 data: &'a mut T,
42 x: core::marker::PhantomData<X>,
43}
44
45#[derive(core::marker::CoercePointee)]
46#[repr(transparent)]
47pub struct Ptr5<'a, #[pointee] T: ?Sized, X>
48where
49 Ptr5Companion<T>: MyTrait<T>,
50 Ptr5Companion2: MyTrait<T>,
51{
52 data: &'a mut T,
53 x: core::marker::PhantomData<X>,
54}
55
56pub struct Ptr5Companion<T: ?Sized>(core::marker::PhantomData<T>);
57pub struct Ptr5Companion2;
58
59#[derive(core::marker::CoercePointee)]
60#[repr(transparent)]
61pub struct Ptr6<'a, #[pointee] T: ?Sized, X: MyTrait<T> = (), const PARAM: usize = 0> {
62 data: &'a mut T,
63 x: core::marker::PhantomData<X>,
64}
65
66// a reduced example from https://lore.kernel.org/all/20240402-linked-list-v1-1-b1c59ba7ae3b@google.com/
67#[repr(transparent)]
68#[derive(core::marker::CoercePointee)]
69pub struct ListArc<#[pointee] T, const ID: u64 = 0>
70where
71 T: ListArcSafe<ID> + ?Sized,
72{
73 arc: *const T,
74}
75
76pub trait ListArcSafe<const ID: u64> {}
77
78fn main() {}
tests/ui/derives/coercepointee/deriving-coerce-pointee-expanded.rs created+29
......@@ -0,0 +1,29 @@
1//@ check-pass
2//@ compile-flags: -Zunpretty=expanded
3//@ edition: 2015
4#![feature(derive_coerce_pointee)]
5use std::marker::CoercePointee;
6
7pub trait MyTrait<T: ?Sized> {}
8
9#[derive(CoercePointee)]
10#[repr(transparent)]
11struct MyPointer<'a, #[pointee] T: ?Sized> {
12 ptr: &'a T,
13}
14
15#[derive(core::marker::CoercePointee)]
16#[repr(transparent)]
17pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>, X: MyTrait<T> = ()>
18where
19 Y: MyTrait<T>,
20{
21 data: &'a mut T,
22 x: core::marker::PhantomData<X>,
23}
24
25#[derive(CoercePointee)]
26#[repr(transparent)]
27struct MyPointerWithoutPointee<'a, T: ?Sized> {
28 ptr: &'a T,
29}
tests/ui/derives/coercepointee/deriving-coerce-pointee-expanded.stdout created+72
......@@ -0,0 +1,72 @@
1#![feature(prelude_import)]
2#![no_std]
3//@ check-pass
4//@ compile-flags: -Zunpretty=expanded
5//@ edition: 2015
6#![feature(derive_coerce_pointee)]
7extern crate std;
8#[prelude_import]
9use ::std::prelude::rust_2015::*;
10use std::marker::CoercePointee;
11
12pub trait MyTrait<T: ?Sized> {}
13
14#[repr(transparent)]
15struct MyPointer<'a, #[pointee] T: ?Sized> {
16 ptr: &'a T,
17}
18#[automatically_derived]
19impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
20 MyPointer<'a, T> {
21}
22#[automatically_derived]
23impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
24 ::core::ops::DispatchFromDyn<MyPointer<'a, __S>> for MyPointer<'a, T> {
25}
26#[automatically_derived]
27impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
28 ::core::ops::CoerceUnsized<MyPointer<'a, __S>> for MyPointer<'a, T> {
29}
30
31#[repr(transparent)]
32pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>,
33 X: MyTrait<T> = ()> where Y: MyTrait<T> {
34 data: &'a mut T,
35 x: core::marker::PhantomData<X>,
36}
37#[automatically_derived]
38impl<'a, Y, Z: MyTrait<T>, T: ?Sized + MyTrait<T>, X: MyTrait<T>>
39 ::core::marker::CoercePointeeValidated for MyPointer2<'a, Y, Z, T, X>
40 where Y: MyTrait<T> {
41}
42#[automatically_derived]
43impl<'a, Y, Z: MyTrait<T> + MyTrait<__S>, T: ?Sized + MyTrait<T> +
44 ::core::marker::Unsize<__S>, __S: ?Sized + MyTrait<__S>, X: MyTrait<T> +
45 MyTrait<__S>> ::core::ops::DispatchFromDyn<MyPointer2<'a, Y, Z, __S, X>>
46 for MyPointer2<'a, Y, Z, T, X> where Y: MyTrait<T>, Y: MyTrait<__S> {
47}
48#[automatically_derived]
49impl<'a, Y, Z: MyTrait<T> + MyTrait<__S>, T: ?Sized + MyTrait<T> +
50 ::core::marker::Unsize<__S>, __S: ?Sized + MyTrait<__S>, X: MyTrait<T> +
51 MyTrait<__S>> ::core::ops::CoerceUnsized<MyPointer2<'a, Y, Z, __S, X>> for
52 MyPointer2<'a, Y, Z, T, X> where Y: MyTrait<T>, Y: MyTrait<__S> {
53}
54
55#[repr(transparent)]
56struct MyPointerWithoutPointee<'a, T: ?Sized> {
57 ptr: &'a T,
58}
59#[automatically_derived]
60impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
61 MyPointerWithoutPointee<'a, T> {
62}
63#[automatically_derived]
64impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
65 ::core::ops::DispatchFromDyn<MyPointerWithoutPointee<'a, __S>> for
66 MyPointerWithoutPointee<'a, T> {
67}
68#[automatically_derived]
69impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
70 ::core::ops::CoerceUnsized<MyPointerWithoutPointee<'a, __S>> for
71 MyPointerWithoutPointee<'a, T> {
72}
tests/ui/derives/coercepointee/deriving-coerce-pointee-neg.rs created+168
......@@ -0,0 +1,168 @@
1//@ proc-macro: malicious-macro.rs
2#![feature(derive_coerce_pointee, arbitrary_self_types)]
3
4extern crate core;
5extern crate malicious_macro;
6
7use std::marker::CoercePointee;
8
9#[derive(CoercePointee)]
10//~^ ERROR: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
11enum NotStruct<'a, T: ?Sized> {
12 Variant(&'a T),
13}
14
15#[derive(CoercePointee)]
16//~^ ERROR: `CoercePointee` can only be derived on `struct`s with at least one field
17#[repr(transparent)]
18struct NoField<'a, #[pointee] T: ?Sized> {}
19//~^ ERROR: lifetime parameter `'a` is never used
20//~| ERROR: type parameter `T` is never used
21
22#[derive(CoercePointee)]
23//~^ ERROR: `CoercePointee` can only be derived on `struct`s with at least one field
24#[repr(transparent)]
25struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
26//~^ ERROR: lifetime parameter `'a` is never used
27//~| ERROR: type parameter `T` is never used
28
29#[derive(CoercePointee)]
30//~^ ERROR: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
31#[repr(transparent)]
32struct NoGeneric<'a>(&'a u8);
33
34#[derive(CoercePointee)]
35//~^ ERROR: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
36#[repr(transparent)]
37struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
38 a: (&'a T1, &'a T2),
39}
40
41#[derive(CoercePointee)]
42#[repr(transparent)]
43struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
44//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
45
46#[derive(CoercePointee)]
47struct NotTransparent<'a, #[pointee] T: ?Sized> {
48 //~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
49 ptr: &'a T,
50}
51
52#[derive(CoercePointee)]
53#[repr(transparent)]
54struct NoMaybeSized<'a, #[pointee] T> {
55 //~^ ERROR: `derive(CoercePointee)` requires `T` to be marked `?Sized`
56 ptr: &'a T,
57}
58
59#[derive(CoercePointee)]
60#[repr(transparent)]
61struct PointeeOnField<'a, #[pointee] T: ?Sized> {
62 #[pointee]
63 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
64 ptr: &'a T,
65}
66
67#[derive(CoercePointee)]
68#[repr(transparent)]
69struct PointeeInTypeConstBlock<
70 'a,
71 T: ?Sized = [u32; const {
72 struct UhOh<#[pointee] T>(T);
73 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
74 10
75 }],
76> {
77 ptr: &'a T,
78}
79
80#[derive(CoercePointee)]
81#[repr(transparent)]
82struct PointeeInConstConstBlock<
83 'a,
84 T: ?Sized,
85 const V: u32 = {
86 struct UhOh<#[pointee] T>(T);
87 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
88 10
89 },
90> {
91 ptr: &'a T,
92}
93
94#[derive(CoercePointee)]
95#[repr(transparent)]
96struct PointeeInAnotherTypeConstBlock<'a, #[pointee] T: ?Sized> {
97 ptr: PointeeInConstConstBlock<
98 'a,
99 T,
100 {
101 struct UhOh<#[pointee] T>(T);
102 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
103 0
104 },
105 >,
106}
107
108// However, reordering attributes should work nevertheless.
109#[repr(transparent)]
110#[derive(CoercePointee)]
111struct ThisIsAPossibleCoercePointee<'a, #[pointee] T: ?Sized> {
112 ptr: &'a T,
113}
114
115// Also, these paths to Sized should work
116#[derive(CoercePointee)]
117#[repr(transparent)]
118struct StdSized<'a, #[pointee] T: ?std::marker::Sized> {
119 ptr: &'a T,
120}
121#[derive(CoercePointee)]
122#[repr(transparent)]
123struct CoreSized<'a, #[pointee] T: ?core::marker::Sized> {
124 ptr: &'a T,
125}
126#[derive(CoercePointee)]
127#[repr(transparent)]
128struct GlobalStdSized<'a, #[pointee] T: ?::std::marker::Sized> {
129 ptr: &'a T,
130}
131#[derive(CoercePointee)]
132#[repr(transparent)]
133struct GlobalCoreSized<'a, #[pointee] T: ?::core::marker::Sized> {
134 ptr: &'a T,
135}
136
137#[derive(CoercePointee)]
138#[malicious_macro::norepr]
139#[repr(transparent)]
140struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
141 //~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout [E0802]
142 ptr: &'a T,
143}
144
145#[repr(transparent)]
146#[derive(CoercePointee)]
147//~^ ERROR for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
148struct RcWithId<T: ?Sized> {
149 inner: std::rc::Rc<(i32, Box<T>)>,
150}
151
152#[repr(transparent)]
153#[derive(CoercePointee)]
154//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced
155struct MoreThanOneField<T: ?Sized> {
156 //~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
157 inner1: Box<T>,
158 inner2: Box<T>,
159}
160
161struct NotCoercePointeeData<T: ?Sized>(T);
162
163#[repr(transparent)]
164#[derive(CoercePointee)]
165//~^ ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
166struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
167
168fn main() {}
tests/ui/derives/coercepointee/deriving-coerce-pointee-neg.stderr created+157
......@@ -0,0 +1,157 @@
1error[E0802]: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
2 --> $DIR/deriving-coerce-pointee-neg.rs:9:10
3 |
4LL | #[derive(CoercePointee)]
5 | ^^^^^^^^^^^^^
6
7error[E0802]: `CoercePointee` can only be derived on `struct`s with at least one field
8 --> $DIR/deriving-coerce-pointee-neg.rs:15:10
9 |
10LL | #[derive(CoercePointee)]
11 | ^^^^^^^^^^^^^
12
13error[E0802]: `CoercePointee` can only be derived on `struct`s with at least one field
14 --> $DIR/deriving-coerce-pointee-neg.rs:22:10
15 |
16LL | #[derive(CoercePointee)]
17 | ^^^^^^^^^^^^^
18
19error[E0802]: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
20 --> $DIR/deriving-coerce-pointee-neg.rs:29:10
21 |
22LL | #[derive(CoercePointee)]
23 | ^^^^^^^^^^^^^
24
25error[E0802]: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
26 --> $DIR/deriving-coerce-pointee-neg.rs:34:10
27 |
28LL | #[derive(CoercePointee)]
29 | ^^^^^^^^^^^^^
30
31error[E0802]: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
32 --> $DIR/deriving-coerce-pointee-neg.rs:43:39
33 |
34LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
35 | ^ - here another type parameter is marked as `#[pointee]`
36
37error[E0802]: `derive(CoercePointee)` requires `T` to be marked `?Sized`
38 --> $DIR/deriving-coerce-pointee-neg.rs:54:36
39 |
40LL | struct NoMaybeSized<'a, #[pointee] T> {
41 | ^
42
43error: the `#[pointee]` attribute may only be used on generic parameters
44 --> $DIR/deriving-coerce-pointee-neg.rs:62:5
45 |
46LL | #[pointee]
47 | ^^^^^^^^^^
48
49error: the `#[pointee]` attribute may only be used on generic parameters
50 --> $DIR/deriving-coerce-pointee-neg.rs:72:33
51 |
52LL | struct UhOh<#[pointee] T>(T);
53 | ^^^^^^^^^^
54
55error: the `#[pointee]` attribute may only be used on generic parameters
56 --> $DIR/deriving-coerce-pointee-neg.rs:86:21
57 |
58LL | struct UhOh<#[pointee] T>(T);
59 | ^^^^^^^^^^
60
61error: the `#[pointee]` attribute may only be used on generic parameters
62 --> $DIR/deriving-coerce-pointee-neg.rs:101:25
63 |
64LL | struct UhOh<#[pointee] T>(T);
65 | ^^^^^^^^^^
66
67error[E0392]: lifetime parameter `'a` is never used
68 --> $DIR/deriving-coerce-pointee-neg.rs:18:16
69 |
70LL | struct NoField<'a, #[pointee] T: ?Sized> {}
71 | ^^ unused lifetime parameter
72 |
73 = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
74
75error[E0392]: type parameter `T` is never used
76 --> $DIR/deriving-coerce-pointee-neg.rs:18:31
77 |
78LL | struct NoField<'a, #[pointee] T: ?Sized> {}
79 | ^ unused type parameter
80 |
81 = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
82
83error[E0392]: lifetime parameter `'a` is never used
84 --> $DIR/deriving-coerce-pointee-neg.rs:25:20
85 |
86LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
87 | ^^ unused lifetime parameter
88 |
89 = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
90
91error[E0392]: type parameter `T` is never used
92 --> $DIR/deriving-coerce-pointee-neg.rs:25:35
93 |
94LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
95 | ^ unused type parameter
96 |
97 = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
98
99error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
100 --> $DIR/deriving-coerce-pointee-neg.rs:47:1
101 |
102LL | struct NotTransparent<'a, #[pointee] T: ?Sized> {
103 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104
105error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
106 --> $DIR/deriving-coerce-pointee-neg.rs:140:1
107 |
108LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
109 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110
111error: for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
112 --> $DIR/deriving-coerce-pointee-neg.rs:146:10
113 |
114LL | #[derive(CoercePointee)]
115 | ^^^^^^^^^^^^^
116...
117LL | inner: std::rc::Rc<(i32, Box<T>)>,
118 | --------------------------------- `Rc<(i32, Box<T>)>` must be a pointer, reference, or smart pointer that is allowed to be unsized
119
120error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
121 --> $DIR/deriving-coerce-pointee-neg.rs:153:10
122 |
123LL | #[derive(CoercePointee)]
124 | ^^^^^^^^^^^^^
125 |
126note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
127 --> $DIR/deriving-coerce-pointee-neg.rs:157:5
128 |
129LL | inner1: Box<T>,
130 | ^^^^^^^^^^^^^^
131LL | inner2: Box<T>,
132 | ^^^^^^^^^^^^^^
133
134error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
135 --> $DIR/deriving-coerce-pointee-neg.rs:164:10
136 |
137LL | #[derive(CoercePointee)]
138 | ^^^^^^^^^^^^^
139LL |
140LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
141 | ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized
142
143error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
144 --> $DIR/deriving-coerce-pointee-neg.rs:155:1
145 |
146LL | struct MoreThanOneField<T: ?Sized> {
147 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
148LL |
149LL | inner1: Box<T>,
150 | -------------- this field has non-zero size or requires alignment
151LL | inner2: Box<T>,
152 | -------------- this field has non-zero size or requires alignment
153
154error: aborting due to 21 previous errors
155
156Some errors have detailed explanations: E0375, E0392, E0690, E0802.
157For more information about an error, try `rustc --explain E0375`.
tests/ui/derives/coercepointee/deriving-coerce-pointee.rs created+56
......@@ -0,0 +1,56 @@
1//@ run-pass
2#![feature(derive_coerce_pointee, arbitrary_self_types)]
3
4use std::marker::CoercePointee;
5
6#[derive(CoercePointee)]
7#[repr(transparent)]
8struct MyPointer<'a, #[pointee] T: ?Sized> {
9 ptr: &'a T,
10}
11
12impl<T: ?Sized> Copy for MyPointer<'_, T> {}
13impl<T: ?Sized> Clone for MyPointer<'_, T> {
14 fn clone(&self) -> Self {
15 Self { ptr: self.ptr }
16 }
17}
18
19impl<'a, T: ?Sized> core::ops::Deref for MyPointer<'a, T> {
20 type Target = T;
21 fn deref(&self) -> &'a T {
22 self.ptr
23 }
24}
25
26struct MyValue(u32);
27impl MyValue {
28 fn through_pointer(self: MyPointer<'_, Self>) -> u32 {
29 self.ptr.0
30 }
31}
32
33trait MyTrait {
34 fn through_trait(&self) -> u32;
35 fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32;
36}
37
38impl MyTrait for MyValue {
39 fn through_trait(&self) -> u32 {
40 self.0
41 }
42
43 fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32 {
44 self.ptr.0
45 }
46}
47
48pub fn main() {
49 let v = MyValue(10);
50 let ptr = MyPointer { ptr: &v };
51 assert_eq!(v.0, ptr.through_pointer());
52 assert_eq!(v.0, ptr.through_pointer());
53 let dptr = ptr as MyPointer<dyn MyTrait>;
54 assert_eq!(v.0, dptr.through_trait());
55 assert_eq!(v.0, dptr.through_trait_and_pointer());
56}
tests/ui/derives/coercepointee/proc-macro-attribute-mixing.rs created+21
......@@ -0,0 +1,21 @@
1// This test certify that we can mix attribute macros from Rust and external proc-macros.
2// For instance, `#[derive(Default)]` uses `#[default]` and `#[derive(CoercePointee)]` uses
3// `#[pointee]`.
4// The scoping rule should allow the use of the said two attributes when external proc-macros
5// are in scope.
6
7//@ check-pass
8//@ proc-macro: another-proc-macro.rs
9//@ compile-flags: -Zunpretty=expanded
10//@ edition: 2015
11
12#![feature(derive_coerce_pointee)]
13
14#[macro_use]
15extern crate another_proc_macro;
16
17#[pointee]
18fn f() {}
19
20#[default]
21fn g() {}
tests/ui/derives/coercepointee/proc-macro-attribute-mixing.stdout created+30
......@@ -0,0 +1,30 @@
1#![feature(prelude_import)]
2#![no_std]
3// This test certify that we can mix attribute macros from Rust and external proc-macros.
4// For instance, `#[derive(Default)]` uses `#[default]` and `#[derive(CoercePointee)]` uses
5// `#[pointee]`.
6// The scoping rule should allow the use of the said two attributes when external proc-macros
7// are in scope.
8
9//@ check-pass
10//@ proc-macro: another-proc-macro.rs
11//@ compile-flags: -Zunpretty=expanded
12//@ edition: 2015
13
14#![feature(derive_coerce_pointee)]
15extern crate std;
16#[prelude_import]
17use ::std::prelude::rust_2015::*;
18
19#[macro_use]
20extern crate another_proc_macro;
21
22
23const _: () =
24 {
25 const POINTEE_MACRO_ATTR_DERIVED: () = ();
26 };
27const _: () =
28 {
29 const DEFAULT_MACRO_ATTR_DERIVED: () = ();
30 };
tests/ui/derives/copy-drop-mutually-exclusive.rs deleted-17
......@@ -1,17 +0,0 @@
1//! Regression test for issue #20126: Copy and Drop traits are mutually exclusive
2
3#[derive(Copy, Clone)]
4struct Foo; //~ ERROR the trait `Copy` cannot be implemented
5
6impl Drop for Foo {
7 fn drop(&mut self) {}
8}
9
10#[derive(Copy, Clone)]
11struct Bar<T>(::std::marker::PhantomData<T>); //~ ERROR the trait `Copy` cannot be implemented
12
13impl<T> Drop for Bar<T> {
14 fn drop(&mut self) {}
15}
16
17fn main() {}
tests/ui/derives/copy-drop-mutually-exclusive.stderr deleted-31
......@@ -1,31 +0,0 @@
1error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
2 --> $DIR/copy-drop-mutually-exclusive.rs:4:8
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- in this derive macro expansion
6LL | struct Foo;
7 | ^^^ `Copy` not allowed on types with destructors
8 |
9note: destructor declared here
10 --> $DIR/copy-drop-mutually-exclusive.rs:7:5
11 |
12LL | fn drop(&mut self) {}
13 | ^^^^^^^^^^^^^^^^^^
14
15error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor
16 --> $DIR/copy-drop-mutually-exclusive.rs:11:8
17 |
18LL | #[derive(Copy, Clone)]
19 | ---- in this derive macro expansion
20LL | struct Bar<T>(::std::marker::PhantomData<T>);
21 | ^^^ `Copy` not allowed on types with destructors
22 |
23note: destructor declared here
24 --> $DIR/copy-drop-mutually-exclusive.rs:14:5
25 |
26LL | fn drop(&mut self) {}
27 | ^^^^^^^^^^^^^^^^^^
28
29error: aborting due to 2 previous errors
30
31For more information about this error, try `rustc --explain E0184`.
tests/ui/derives/debug/derive-Debug-enum-variants.rs created+30
......@@ -0,0 +1,30 @@
1//! Test that `#[derive(Debug)]` for enums correctly formats variant names.
2
3//@ run-pass
4
5#[derive(Debug)]
6enum Foo {
7 A(usize),
8 C,
9}
10
11#[derive(Debug)]
12enum Bar {
13 D,
14}
15
16pub fn main() {
17 // Test variant with data
18 let foo_a = Foo::A(22);
19 assert_eq!("A(22)".to_string(), format!("{:?}", foo_a));
20
21 if let Foo::A(value) = foo_a {
22 println!("Value: {}", value); // This needs to remove #[allow(dead_code)]
23 }
24
25 // Test unit variant
26 assert_eq!("C".to_string(), format!("{:?}", Foo::C));
27
28 // Test unit variant from different enum
29 assert_eq!("D".to_string(), format!("{:?}", Bar::D));
30}
tests/ui/derives/debug/derive-Debug-use-ufcs-struct.rs created+40
......@@ -0,0 +1,40 @@
1//@ run-pass
2#![allow(warnings)]
3
4#[derive(Debug)]
5pub struct Bar { pub t: () }
6
7impl<T> Access for T {}
8pub trait Access {
9 fn field(&self, _: impl Sized, _: impl Sized) {
10 panic!("got into Access::field");
11 }
12
13 fn finish(&self) -> Result<(), std::fmt::Error> {
14 panic!("got into Access::finish");
15 }
16
17 fn debug_struct(&self, _: impl Sized, _: impl Sized) {
18 panic!("got into Access::debug_struct");
19 }
20}
21
22impl<T> MutAccess for T {}
23pub trait MutAccess {
24 fn field(&mut self, _: impl Sized, _: impl Sized) {
25 panic!("got into MutAccess::field");
26 }
27
28 fn finish(&mut self) -> Result<(), std::fmt::Error> {
29 panic!("got into MutAccess::finish");
30 }
31
32 fn debug_struct(&mut self, _: impl Sized, _: impl Sized) {
33 panic!("got into MutAccess::debug_struct");
34 }
35}
36
37fn main() {
38 let bar = Bar { t: () };
39 assert_eq!("Bar { t: () }", format!("{:?}", bar));
40}
tests/ui/derives/debug/derive-Debug-use-ufcs-tuple.rs created+32
......@@ -0,0 +1,32 @@
1//@ run-pass
2#![allow(warnings)]
3
4#[derive(Debug)]
5pub struct Foo<T>(pub T);
6
7use std::fmt;
8
9impl<T> Field for T {}
10impl<T> Finish for T {}
11impl Dt for &mut fmt::Formatter<'_> {}
12
13pub trait Field {
14 fn field(&self, _: impl Sized) {
15 panic!("got into field");
16 }
17}
18pub trait Finish {
19 fn finish(&self) -> Result<(), std::fmt::Error> {
20 panic!("got into finish");
21 }
22}
23pub trait Dt {
24 fn debug_tuple(&self, _: &str) {
25 panic!("got into debug_tuple");
26 }
27}
28
29fn main() {
30 let foo = Foo(());
31 assert_eq!("Foo(())", format!("{:?}", foo));
32}
tests/ui/derives/debug/derive-debug-2.rs created+54
......@@ -0,0 +1,54 @@
1//@ run-pass
2#![allow(dead_code)]
3use std::fmt;
4
5#[derive(Debug)]
6enum A {}
7#[derive(Debug)]
8enum B { B1, B2, B3 }
9#[derive(Debug)]
10enum C { C1(isize), C2(B), C3(String) }
11#[derive(Debug)]
12enum D { D1{ a: isize } }
13#[derive(Debug)]
14struct E;
15#[derive(Debug)]
16struct F(isize);
17#[derive(Debug)]
18struct G(isize, isize);
19#[derive(Debug)]
20struct H { a: isize }
21#[derive(Debug)]
22struct I { a: isize, b: isize }
23#[derive(Debug)]
24struct J(Custom);
25
26struct Custom;
27impl fmt::Debug for Custom {
28 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29 write!(f, "yay")
30 }
31}
32
33trait ToDebug {
34 fn to_show(&self) -> String;
35}
36
37impl<T: fmt::Debug> ToDebug for T {
38 fn to_show(&self) -> String {
39 format!("{:?}", self)
40 }
41}
42
43pub fn main() {
44 assert_eq!(B::B1.to_show(), "B1".to_string());
45 assert_eq!(B::B2.to_show(), "B2".to_string());
46 assert_eq!(C::C1(3).to_show(), "C1(3)".to_string());
47 assert_eq!(C::C2(B::B2).to_show(), "C2(B2)".to_string());
48 assert_eq!(D::D1{ a: 2 }.to_show(), "D1 { a: 2 }".to_string());
49 assert_eq!(E.to_show(), "E".to_string());
50 assert_eq!(F(3).to_show(), "F(3)".to_string());
51 assert_eq!(G(3, 4).to_show(), "G(3, 4)".to_string());
52 assert_eq!(I{ a: 2, b: 4 }.to_show(), "I { a: 2, b: 4 }".to_string());
53 assert_eq!(J(Custom).to_show(), "J(yay)".to_string());
54}
tests/ui/derives/debug/derive-debug-generic-with-lifetime.rs created+10
......@@ -0,0 +1,10 @@
1//! regression test for <https://github.com/rust-lang/rust/issues/29030>
2//@ check-pass
3#![allow(dead_code)]
4#[derive(Debug)]
5struct Message<'a, P: 'a = &'a [u8]> {
6 header: &'a [u8],
7 payload: P,
8}
9
10fn main() {}
tests/ui/derives/debug/derive-debug-newtype-unsized-slice.rs created+7
......@@ -0,0 +1,7 @@
1//! regression test for <https://github.com/rust-lang/rust/issues/25394>
2//@ check-pass
3#![allow(dead_code)]
4#[derive(Debug)]
5struct Row<T>([T]);
6
7fn main() {}
tests/ui/derives/debug/derive-debug-uninhabited-enum.rs created+23
......@@ -0,0 +1,23 @@
1//! Regression test for `#[derive(Debug)]` on enums with uninhabited variants.
2//!
3//! Ensures there are no special warnings about uninhabited types when deriving
4//! Debug on an enum with uninhabited variants, only standard unused warnings.
5//!
6//! Issue: https://github.com/rust-lang/rust/issues/38885
7
8//@ check-pass
9//@ compile-flags: -Wunused
10
11#[derive(Debug)]
12enum Void {}
13
14#[derive(Debug)]
15enum Foo {
16 Bar(#[allow(dead_code)] u8),
17 Void(Void), //~ WARN variant `Void` is never constructed
18}
19
20fn main() {
21 let x = Foo::Bar(42);
22 println!("{:?}", x);
23}
tests/ui/derives/debug/derive-debug-uninhabited-enum.stderr created+15
......@@ -0,0 +1,15 @@
1warning: variant `Void` is never constructed
2 --> $DIR/derive-debug-uninhabited-enum.rs:17:5
3 |
4LL | enum Foo {
5 | --- variant in this enum
6LL | Bar(#[allow(dead_code)] u8),
7LL | Void(Void),
8 | ^^^^
9 |
10 = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
11 = note: `-W dead-code` implied by `-W unused`
12 = help: to override `-W unused` add `#[expect(dead_code)]` or `#[allow(dead_code)]`
13
14warning: 1 warning emitted
15
tests/ui/derives/debug/derive-debug.rs created+35
......@@ -0,0 +1,35 @@
1//@ run-pass
2#![allow(dead_code)]
3#[derive(Debug)]
4struct Unit;
5
6#[derive(Debug)]
7struct Tuple(isize, usize);
8
9#[derive(Debug)]
10struct Struct { x: isize, y: usize }
11
12#[derive(Debug)]
13enum Enum {
14 Nullary,
15 Variant(isize, usize),
16 StructVariant { x: isize, y : usize }
17}
18
19#[derive(Debug)]
20struct Pointers(*const dyn Send, *mut dyn Sync);
21
22macro_rules! t {
23 ($x:expr, $expected:expr) => {
24 assert_eq!(format!("{:?}", $x), $expected.to_string())
25 }
26}
27
28pub fn main() {
29 t!(Unit, "Unit");
30 t!(Tuple(1, 2), "Tuple(1, 2)");
31 t!(Struct { x: 1, y: 2 }, "Struct { x: 1, y: 2 }");
32 t!(Enum::Nullary, "Nullary");
33 t!(Enum::Variant(1, 2), "Variant(1, 2)");
34 t!(Enum::StructVariant { x: 1, y: 2 }, "StructVariant { x: 1, y: 2 }");
35}
tests/ui/derives/debug/derives-span-Debug.rs created+29
......@@ -0,0 +1,29 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Debug)] line.
3
4struct Error;
5
6#[derive(Debug)]
7enum EnumStructVariant {
8 A {
9 x: Error, //~ ERROR
10 },
11}
12
13#[derive(Debug)]
14enum EnumTupleVariant {
15 A(
16 Error, //~ ERROR
17 ),
18}
19#[derive(Debug)]
20struct Struct {
21 x: Error, //~ ERROR
22}
23
24#[derive(Debug)]
25struct TupleStruct(
26 Error, //~ ERROR
27);
28
29fn main() {}
tests/ui/derives/debug/derives-span-Debug.stderr created+67
......@@ -0,0 +1,67 @@
1error[E0277]: `Error` doesn't implement `Debug`
2 --> $DIR/derives-span-Debug.rs:9:9
3 |
4LL | #[derive(Debug)]
5 | ----- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Debug` is not implemented for `Error`
9 |
10 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
11help: consider annotating `Error` with `#[derive(Debug)]`
12 |
13LL + #[derive(Debug)]
14LL | struct Error;
15 |
16
17error[E0277]: `Error` doesn't implement `Debug`
18 --> $DIR/derives-span-Debug.rs:16:9
19 |
20LL | #[derive(Debug)]
21 | ----- in this derive macro expansion
22...
23LL | Error,
24 | ^^^^^ the trait `Debug` is not implemented for `Error`
25 |
26 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
27help: consider annotating `Error` with `#[derive(Debug)]`
28 |
29LL + #[derive(Debug)]
30LL | struct Error;
31 |
32
33error[E0277]: `Error` doesn't implement `Debug`
34 --> $DIR/derives-span-Debug.rs:21:5
35 |
36LL | #[derive(Debug)]
37 | ----- in this derive macro expansion
38LL | struct Struct {
39LL | x: Error,
40 | ^^^^^^^^ the trait `Debug` is not implemented for `Error`
41 |
42 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
43help: consider annotating `Error` with `#[derive(Debug)]`
44 |
45LL + #[derive(Debug)]
46LL | struct Error;
47 |
48
49error[E0277]: `Error` doesn't implement `Debug`
50 --> $DIR/derives-span-Debug.rs:26:5
51 |
52LL | #[derive(Debug)]
53 | ----- in this derive macro expansion
54LL | struct TupleStruct(
55LL | Error,
56 | ^^^^^ the trait `Debug` is not implemented for `Error`
57 |
58 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
59help: consider annotating `Error` with `#[derive(Debug)]`
60 |
61LL + #[derive(Debug)]
62LL | struct Error;
63 |
64
65error: aborting due to 4 previous errors
66
67For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/debug/nonsense-input-to-debug.rs created+12
......@@ -0,0 +1,12 @@
1// Issue: #32950
2// Ensure that using macros rather than a type doesn't break `derive`.
3
4#[derive(Debug)]
5struct Nonsense<T> {
6 //~^ ERROR type parameter `T` is never used
7 should_be_vec_t: vec![T],
8 //~^ ERROR `derive` cannot be used on items with type macros
9 //~| ERROR expected type, found `expr` metavariable
10}
11
12fn main() {}
tests/ui/derives/debug/nonsense-input-to-debug.stderr created+28
......@@ -0,0 +1,28 @@
1error: `derive` cannot be used on items with type macros
2 --> $DIR/nonsense-input-to-debug.rs:7:22
3 |
4LL | should_be_vec_t: vec![T],
5 | ^^^^^^^
6
7error: expected type, found `expr` metavariable
8 --> $DIR/nonsense-input-to-debug.rs:7:22
9 |
10LL | should_be_vec_t: vec![T],
11 | ^^^^^^^
12 | |
13 | expected type
14 | in this macro invocation
15 | this macro call doesn't expand to a type
16
17error[E0392]: type parameter `T` is never used
18 --> $DIR/nonsense-input-to-debug.rs:5:17
19 |
20LL | struct Nonsense<T> {
21 | ^ unused type parameter
22 |
23 = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
24 = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
25
26error: aborting due to 3 previous errors
27
28For more information about this error, try `rustc --explain E0392`.
tests/ui/derives/default/derives-span-Default.rs created+16
......@@ -0,0 +1,16 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Default)] line.
3
4struct Error;
5
6#[derive(Default)]
7struct Struct {
8 x: Error, //~ ERROR
9}
10
11#[derive(Default)]
12struct TupleStruct(
13 Error, //~ ERROR
14);
15
16fn main() {}
tests/ui/derives/default/derives-span-Default.stderr created+33
......@@ -0,0 +1,33 @@
1error[E0277]: the trait bound `Error: Default` is not satisfied
2 --> $DIR/derives-span-Default.rs:8:5
3 |
4LL | #[derive(Default)]
5 | ------- in this derive macro expansion
6LL | struct Struct {
7LL | x: Error,
8 | ^^^^^^^^ the trait `Default` is not implemented for `Error`
9 |
10help: consider annotating `Error` with `#[derive(Default)]`
11 |
12LL + #[derive(Default)]
13LL | struct Error;
14 |
15
16error[E0277]: the trait bound `Error: Default` is not satisfied
17 --> $DIR/derives-span-Default.rs:13:5
18 |
19LL | #[derive(Default)]
20 | ------- in this derive macro expansion
21LL | struct TupleStruct(
22LL | Error,
23 | ^^^^^ the trait `Default` is not implemented for `Error`
24 |
25help: consider annotating `Error` with `#[derive(Default)]`
26 |
27LL + #[derive(Default)]
28LL | struct Error;
29 |
30
31error: aborting due to 2 previous errors
32
33For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/default/deriving-default-box.rs created+13
......@@ -0,0 +1,13 @@
1//@ run-pass
2use std::default::Default;
3
4#[derive(Default)]
5struct A {
6 foo: Box<[bool]>,
7}
8
9pub fn main() {
10 let a: A = Default::default();
11 let b: Box<[_]> = Box::<[bool; 0]>::new([]);
12 assert_eq!(a.foo, b);
13}
tests/ui/derives/default/deriving-default-enum.rs created+27
......@@ -0,0 +1,27 @@
1//@ run-pass
2
3// nb: does not impl Default
4#[derive(Debug, PartialEq)]
5struct NotDefault;
6
7#[derive(Debug, Default, PartialEq)]
8enum Foo {
9 #[default]
10 Alpha,
11 #[allow(dead_code)]
12 Beta(NotDefault),
13}
14
15// #[default] on a generic enum does not add `Default` bounds to the type params.
16#[derive(Default)]
17enum MyOption<T> {
18 #[default]
19 None,
20 #[allow(dead_code)]
21 Some(T),
22}
23
24fn main() {
25 assert!(matches!(Foo::default(), Foo::Alpha));
26 assert!(matches!(MyOption::<NotDefault>::default(), MyOption::None));
27}
tests/ui/derives/default/multiple-defaults.rs created+41
......@@ -0,0 +1,41 @@
1//@ compile-flags: --crate-type=lib
2
3// When we get multiple `#[default]` variants, we emit several tool-only suggestions
4// to remove all except one of the `#[default]`s.
5
6#[derive(Default)] //~ ERROR multiple declared defaults
7enum A {
8 #[default] //~ HELP make `B` default
9 #[default] //~ HELP make `A` default
10 A,
11 #[default] // also "HELP make `A` default", but compiletest can't handle multispans
12 B,
13}
14
15// Originally, we took each defaulted variant and emitted the suggestion for every variant
16// with a different identifier, causing an ICE when multiple variants have the same identifier:
17// https://github.com/rust-lang/rust/pull/105106
18#[derive(Default)] //~ ERROR multiple declared defaults
19enum E {
20 #[default] //~ HELP make `A` default
21 A,
22 #[default] //~ HELP make `A` default
23 A, //~ ERROR defined multiple times
24}
25
26// Then, we took each defaulted variant and emitted the suggestion for every variant
27// with a different span, causing an ICE when multiple variants have the same span:
28// https://github.com/rust-lang/rust/issues/118119
29macro_rules! m {
30 { $($id:ident)* } => {
31 #[derive(Default)] //~ ERROR multiple declared defaults
32 enum F {
33 $(
34 #[default]
35 $id,
36 )*
37 }
38 }
39}
40
41m! { A B }
tests/ui/derives/default/multiple-defaults.stderr created+60
......@@ -0,0 +1,60 @@
1error: multiple declared defaults
2 --> $DIR/multiple-defaults.rs:6:10
3 |
4LL | #[derive(Default)]
5 | ^^^^^^^
6...
7LL | A,
8 | - first default
9LL | #[default] // also "HELP make `A` default", but compiletest can't handle multispans
10LL | B,
11 | - additional default
12 |
13 = note: only one variant can be default
14
15error: multiple declared defaults
16 --> $DIR/multiple-defaults.rs:18:10
17 |
18LL | #[derive(Default)]
19 | ^^^^^^^
20...
21LL | A,
22 | - first default
23LL | #[default]
24LL | A,
25 | - additional default
26 |
27 = note: only one variant can be default
28
29error[E0428]: the name `A` is defined multiple times
30 --> $DIR/multiple-defaults.rs:23:5
31 |
32LL | A,
33 | - previous definition of the type `A` here
34LL | #[default]
35LL | A,
36 | ^ `A` redefined here
37 |
38 = note: `A` must be defined only once in the type namespace of this enum
39
40error: multiple declared defaults
41 --> $DIR/multiple-defaults.rs:31:18
42 |
43LL | #[derive(Default)]
44 | ^^^^^^^
45...
46LL | $id,
47 | ---
48 | |
49 | first default
50 | additional default
51...
52LL | m! { A B }
53 | ---------- in this macro invocation
54 |
55 = note: only one variant can be default
56 = note: this error originates in the derive macro `Default` which comes from the expansion of the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
57
58error: aborting due to 4 previous errors
59
60For more information about this error, try `rustc --explain E0428`.
tests/ui/derives/derive-Debug-enum-variants.rs deleted-30
......@@ -1,30 +0,0 @@
1//! Test that `#[derive(Debug)]` for enums correctly formats variant names.
2
3//@ run-pass
4
5#[derive(Debug)]
6enum Foo {
7 A(usize),
8 C,
9}
10
11#[derive(Debug)]
12enum Bar {
13 D,
14}
15
16pub fn main() {
17 // Test variant with data
18 let foo_a = Foo::A(22);
19 assert_eq!("A(22)".to_string(), format!("{:?}", foo_a));
20
21 if let Foo::A(value) = foo_a {
22 println!("Value: {}", value); // This needs to remove #[allow(dead_code)]
23 }
24
25 // Test unit variant
26 assert_eq!("C".to_string(), format!("{:?}", Foo::C));
27
28 // Test unit variant from different enum
29 assert_eq!("D".to_string(), format!("{:?}", Bar::D));
30}
tests/ui/derives/derive-Debug-use-ufcs-struct.rs deleted-40
......@@ -1,40 +0,0 @@
1//@ run-pass
2#![allow(warnings)]
3
4#[derive(Debug)]
5pub struct Bar { pub t: () }
6
7impl<T> Access for T {}
8pub trait Access {
9 fn field(&self, _: impl Sized, _: impl Sized) {
10 panic!("got into Access::field");
11 }
12
13 fn finish(&self) -> Result<(), std::fmt::Error> {
14 panic!("got into Access::finish");
15 }
16
17 fn debug_struct(&self, _: impl Sized, _: impl Sized) {
18 panic!("got into Access::debug_struct");
19 }
20}
21
22impl<T> MutAccess for T {}
23pub trait MutAccess {
24 fn field(&mut self, _: impl Sized, _: impl Sized) {
25 panic!("got into MutAccess::field");
26 }
27
28 fn finish(&mut self) -> Result<(), std::fmt::Error> {
29 panic!("got into MutAccess::finish");
30 }
31
32 fn debug_struct(&mut self, _: impl Sized, _: impl Sized) {
33 panic!("got into MutAccess::debug_struct");
34 }
35}
36
37fn main() {
38 let bar = Bar { t: () };
39 assert_eq!("Bar { t: () }", format!("{:?}", bar));
40}
tests/ui/derives/derive-Debug-use-ufcs-tuple.rs deleted-32
......@@ -1,32 +0,0 @@
1//@ run-pass
2#![allow(warnings)]
3
4#[derive(Debug)]
5pub struct Foo<T>(pub T);
6
7use std::fmt;
8
9impl<T> Field for T {}
10impl<T> Finish for T {}
11impl Dt for &mut fmt::Formatter<'_> {}
12
13pub trait Field {
14 fn field(&self, _: impl Sized) {
15 panic!("got into field");
16 }
17}
18pub trait Finish {
19 fn finish(&self) -> Result<(), std::fmt::Error> {
20 panic!("got into finish");
21 }
22}
23pub trait Dt {
24 fn debug_tuple(&self, _: &str) {
25 panic!("got into debug_tuple");
26 }
27}
28
29fn main() {
30 let foo = Foo(());
31 assert_eq!("Foo(())", format!("{:?}", foo));
32}
tests/ui/derives/derive-clone-basic.rs deleted-65
......@@ -1,65 +0,0 @@
1//! Make sure that `derive(Clone)` works for simple structs and enums.
2//@ run-pass
3#![allow(dead_code)]
4
5#[derive(Clone)]
6enum SimpleEnum {
7 A,
8 B(()),
9 C,
10}
11
12#[derive(Clone)]
13enum GenericEnum<T, U> {
14 A(T),
15 B(T, U),
16 C,
17}
18
19#[derive(Clone)]
20struct TupleStruct((), ());
21
22#[derive(Clone)]
23struct GenericStruct<T> {
24 foo: (),
25 bar: (),
26 baz: T,
27}
28
29#[derive(Clone)]
30struct GenericTupleStruct<T>(T, ());
31
32#[derive(Clone)]
33struct ManyPrimitives {
34 _int: isize,
35 _i8: i8,
36 _i16: i16,
37 _i32: i32,
38 _i64: i64,
39
40 _uint: usize,
41 _u8: u8,
42 _u16: u16,
43 _u32: u32,
44 _u64: u64,
45
46 _f32: f32,
47 _f64: f64,
48
49 _bool: bool,
50 _char: char,
51 _nil: (),
52}
53
54// Regression test for issue #30244
55#[derive(Copy, Clone)]
56struct Array {
57 arr: [[u8; 256]; 4],
58}
59
60pub fn main() {
61 let _ = SimpleEnum::A.clone();
62 let _ = GenericEnum::A::<isize, isize>(1).clone();
63 let _ = GenericStruct { foo: (), bar: (), baz: 1 }.clone();
64 let _ = GenericTupleStruct(1, ()).clone();
65}
tests/ui/derives/derive-debug-generic-with-lifetime.rs deleted-10
......@@ -1,10 +0,0 @@
1//! regression test for <https://github.com/rust-lang/rust/issues/29030>
2//@ check-pass
3#![allow(dead_code)]
4#[derive(Debug)]
5struct Message<'a, P: 'a = &'a [u8]> {
6 header: &'a [u8],
7 payload: P,
8}
9
10fn main() {}
tests/ui/derives/derive-debug-newtype-unsized-slice.rs deleted-7
......@@ -1,7 +0,0 @@
1//! regression test for <https://github.com/rust-lang/rust/issues/25394>
2//@ check-pass
3#![allow(dead_code)]
4#[derive(Debug)]
5struct Row<T>([T]);
6
7fn main() {}
tests/ui/derives/derive-debug-uninhabited-enum.rs deleted-23
......@@ -1,23 +0,0 @@
1//! Regression test for `#[derive(Debug)]` on enums with uninhabited variants.
2//!
3//! Ensures there are no special warnings about uninhabited types when deriving
4//! Debug on an enum with uninhabited variants, only standard unused warnings.
5//!
6//! Issue: https://github.com/rust-lang/rust/issues/38885
7
8//@ check-pass
9//@ compile-flags: -Wunused
10
11#[derive(Debug)]
12enum Void {}
13
14#[derive(Debug)]
15enum Foo {
16 Bar(#[allow(dead_code)] u8),
17 Void(Void), //~ WARN variant `Void` is never constructed
18}
19
20fn main() {
21 let x = Foo::Bar(42);
22 println!("{:?}", x);
23}
tests/ui/derives/derive-debug-uninhabited-enum.stderr deleted-15
......@@ -1,15 +0,0 @@
1warning: variant `Void` is never constructed
2 --> $DIR/derive-debug-uninhabited-enum.rs:17:5
3 |
4LL | enum Foo {
5 | --- variant in this enum
6LL | Bar(#[allow(dead_code)] u8),
7LL | Void(Void),
8 | ^^^^
9 |
10 = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
11 = note: `-W dead-code` implied by `-W unused`
12 = help: to override `-W unused` add `#[expect(dead_code)]` or `#[allow(dead_code)]`
13
14warning: 1 warning emitted
15
tests/ui/derives/derive-eq-check-all-variants.rs deleted-12
......@@ -1,12 +0,0 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/103157.
2
3#[derive(PartialEq, Eq)]
4pub enum Value {
5 Boolean(Option<bool>),
6 Float(Option<f64>), //~ ERROR the trait bound `f64: Eq` is not satisfied
7}
8
9fn main() {
10 let a = Value::Float(Some(f64::NAN));
11 assert!(a == a);
12}
tests/ui/derives/derive-eq-check-all-variants.stderr deleted-26
......@@ -1,26 +0,0 @@
1error[E0277]: the trait bound `f64: Eq` is not satisfied
2 --> $DIR/derive-eq-check-all-variants.rs:6:11
3 |
4LL | #[derive(PartialEq, Eq)]
5 | -- in this derive macro expansion
6...
7LL | Float(Option<f64>),
8 | ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64`
9 |
10 = help: the following other types implement trait `Eq`:
11 i128
12 i16
13 i32
14 i64
15 i8
16 isize
17 u128
18 u16
19 and 4 others
20 = note: required for `Option<f64>` to implement `Eq`
21note: required by a bound in `std::cmp::AssertParamIsEq`
22 --> $SRC_DIR/core/src/cmp.rs:LL:COL
23
24error: aborting due to 1 previous error
25
26For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/derive-no-std.rs created+12
......@@ -0,0 +1,12 @@
1//@ run-pass
2//@ aux-build:derive-no-std.rs
3
4extern crate derive_no_std;
5use derive_no_std::*;
6
7fn main() {
8 let f = Foo { x: 0 };
9 assert_eq!(f.clone(), Foo::default());
10
11 assert!(Bar::Qux < Bar::Quux(42));
12}
tests/ui/derives/derive-partial-ord-discriminant-64bit.rs deleted-40
......@@ -1,40 +0,0 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15523
2
3//@ run-pass
4// Issue 15523: derive(PartialOrd) should use the provided
5// discriminant values for the derived ordering.
6//
7// This test is checking corner cases that arise when you have
8// 64-bit values in the variants.
9
10#[derive(PartialEq, PartialOrd)]
11#[repr(u64)]
12enum Eu64 {
13 Pos2 = 2,
14 PosMax = !0,
15 Pos1 = 1,
16}
17
18#[derive(PartialEq, PartialOrd)]
19#[repr(i64)]
20enum Ei64 {
21 Pos2 = 2,
22 Neg1 = -1,
23 NegMin = 1 << 63,
24 PosMax = !(1 << 63),
25 Pos1 = 1,
26}
27
28fn main() {
29 assert!(Eu64::Pos2 > Eu64::Pos1);
30 assert!(Eu64::Pos2 < Eu64::PosMax);
31 assert!(Eu64::Pos1 < Eu64::PosMax);
32
33 assert!(Ei64::Pos2 > Ei64::Pos1);
34 assert!(Ei64::Pos2 > Ei64::Neg1);
35 assert!(Ei64::Pos1 > Ei64::Neg1);
36 assert!(Ei64::Pos2 > Ei64::NegMin);
37 assert!(Ei64::Pos1 > Ei64::NegMin);
38 assert!(Ei64::Pos2 < Ei64::PosMax);
39 assert!(Ei64::Pos1 < Ei64::PosMax);
40}
tests/ui/derives/derive-partial-ord-discriminant.rs deleted-44
......@@ -1,44 +0,0 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15523
2
3//@ run-pass
4// Issue 15523: derive(PartialOrd) should use the provided
5// discriminant values for the derived ordering.
6//
7// This is checking the basic functionality.
8
9#[derive(PartialEq, PartialOrd)]
10enum E1 {
11 Pos2 = 2,
12 Neg1 = -1,
13 Pos1 = 1,
14}
15
16#[derive(PartialEq, PartialOrd)]
17#[repr(u8)]
18enum E2 {
19 Pos2 = 2,
20 PosMax = !0 as u8,
21 Pos1 = 1,
22}
23
24#[derive(PartialEq, PartialOrd)]
25#[repr(i8)]
26enum E3 {
27 Pos2 = 2,
28 Neg1 = -1_i8,
29 Pos1 = 1,
30}
31
32fn main() {
33 assert!(E1::Pos2 > E1::Pos1);
34 assert!(E1::Pos1 > E1::Neg1);
35 assert!(E1::Pos2 > E1::Neg1);
36
37 assert!(E2::Pos2 > E2::Pos1);
38 assert!(E2::Pos1 < E2::PosMax);
39 assert!(E2::Pos2 < E2::PosMax);
40
41 assert!(E3::Pos2 > E3::Pos1);
42 assert!(E3::Pos1 > E3::Neg1);
43 assert!(E3::Pos2 > E3::Neg1);
44}
tests/ui/derives/derive-partial-ord.rs deleted-60
......@@ -1,60 +0,0 @@
1// Checks that in a derived implementation of PartialOrd the lt, le, ge, gt methods are consistent
2// with partial_cmp. Also verifies that implementation is consistent with that for tuples.
3//
4//@ run-pass
5
6#[derive(PartialEq, PartialOrd)]
7struct P(f64, f64);
8
9fn main() {
10 let values: &[f64] = &[1.0, 2.0, f64::NAN];
11 for a in values {
12 for b in values {
13 for c in values {
14 for d in values {
15 // Check impl for a tuple.
16 check(&(*a, *b), &(*c, *d));
17
18 // Check derived impl.
19 check(&P(*a, *b), &P(*c, *d));
20
21 // Check that impls agree with each other.
22 assert_eq!(
23 PartialOrd::partial_cmp(&(*a, *b), &(*c, *d)),
24 PartialOrd::partial_cmp(&P(*a, *b), &P(*c, *d)),
25 );
26 }
27 }
28 }
29 }
30}
31
32fn check<T: PartialOrd>(a: &T, b: &T) {
33 use std::cmp::Ordering::*;
34 match PartialOrd::partial_cmp(a, b) {
35 None => {
36 assert!(!(a < b));
37 assert!(!(a <= b));
38 assert!(!(a > b));
39 assert!(!(a >= b));
40 }
41 Some(Equal) => {
42 assert!(!(a < b));
43 assert!(a <= b);
44 assert!(!(a > b));
45 assert!(a >= b);
46 }
47 Some(Less) => {
48 assert!(a < b);
49 assert!(a <= b);
50 assert!(!(a > b));
51 assert!(!(a >= b));
52 }
53 Some(Greater) => {
54 assert!(!(a < b));
55 assert!(!(a <= b));
56 assert!(a > b);
57 assert!(a >= b);
58 }
59 }
60}
tests/ui/derives/derives-span-Clone.rs deleted-30
......@@ -1,30 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Clone)] line.
3
4struct Error;
5
6#[derive(Clone)]
7enum EnumStructVariant {
8 A {
9 x: Error, //~ ERROR
10 },
11}
12
13#[derive(Clone)]
14enum EnumTupleVariant {
15 A(
16 Error, //~ ERROR
17 ),
18}
19
20#[derive(Clone)]
21struct Struct {
22 x: Error, //~ ERROR
23}
24
25#[derive(Clone)]
26struct TupleStruct(
27 Error, //~ ERROR
28);
29
30fn main() {}
tests/ui/derives/derives-span-Clone.stderr deleted-63
......@@ -1,63 +0,0 @@
1error[E0277]: the trait bound `Error: Clone` is not satisfied
2 --> $DIR/derives-span-Clone.rs:9:9
3 |
4LL | #[derive(Clone)]
5 | ----- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Clone` is not implemented for `Error`
9 |
10help: consider annotating `Error` with `#[derive(Clone)]`
11 |
12LL + #[derive(Clone)]
13LL | struct Error;
14 |
15
16error[E0277]: the trait bound `Error: Clone` is not satisfied
17 --> $DIR/derives-span-Clone.rs:16:9
18 |
19LL | #[derive(Clone)]
20 | ----- in this derive macro expansion
21...
22LL | Error,
23 | ^^^^^ the trait `Clone` is not implemented for `Error`
24 |
25help: consider annotating `Error` with `#[derive(Clone)]`
26 |
27LL + #[derive(Clone)]
28LL | struct Error;
29 |
30
31error[E0277]: the trait bound `Error: Clone` is not satisfied
32 --> $DIR/derives-span-Clone.rs:22:5
33 |
34LL | #[derive(Clone)]
35 | ----- in this derive macro expansion
36LL | struct Struct {
37LL | x: Error,
38 | ^^^^^^^^ the trait `Clone` is not implemented for `Error`
39 |
40help: consider annotating `Error` with `#[derive(Clone)]`
41 |
42LL + #[derive(Clone)]
43LL | struct Error;
44 |
45
46error[E0277]: the trait bound `Error: Clone` is not satisfied
47 --> $DIR/derives-span-Clone.rs:27:5
48 |
49LL | #[derive(Clone)]
50 | ----- in this derive macro expansion
51LL | struct TupleStruct(
52LL | Error,
53 | ^^^^^ the trait `Clone` is not implemented for `Error`
54 |
55help: consider annotating `Error` with `#[derive(Clone)]`
56 |
57LL + #[derive(Clone)]
58LL | struct Error;
59 |
60
61error: aborting due to 4 previous errors
62
63For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/derives-span-Debug.rs deleted-29
......@@ -1,29 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Debug)] line.
3
4struct Error;
5
6#[derive(Debug)]
7enum EnumStructVariant {
8 A {
9 x: Error, //~ ERROR
10 },
11}
12
13#[derive(Debug)]
14enum EnumTupleVariant {
15 A(
16 Error, //~ ERROR
17 ),
18}
19#[derive(Debug)]
20struct Struct {
21 x: Error, //~ ERROR
22}
23
24#[derive(Debug)]
25struct TupleStruct(
26 Error, //~ ERROR
27);
28
29fn main() {}
tests/ui/derives/derives-span-Debug.stderr deleted-67
......@@ -1,67 +0,0 @@
1error[E0277]: `Error` doesn't implement `Debug`
2 --> $DIR/derives-span-Debug.rs:9:9
3 |
4LL | #[derive(Debug)]
5 | ----- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Debug` is not implemented for `Error`
9 |
10 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
11help: consider annotating `Error` with `#[derive(Debug)]`
12 |
13LL + #[derive(Debug)]
14LL | struct Error;
15 |
16
17error[E0277]: `Error` doesn't implement `Debug`
18 --> $DIR/derives-span-Debug.rs:16:9
19 |
20LL | #[derive(Debug)]
21 | ----- in this derive macro expansion
22...
23LL | Error,
24 | ^^^^^ the trait `Debug` is not implemented for `Error`
25 |
26 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
27help: consider annotating `Error` with `#[derive(Debug)]`
28 |
29LL + #[derive(Debug)]
30LL | struct Error;
31 |
32
33error[E0277]: `Error` doesn't implement `Debug`
34 --> $DIR/derives-span-Debug.rs:21:5
35 |
36LL | #[derive(Debug)]
37 | ----- in this derive macro expansion
38LL | struct Struct {
39LL | x: Error,
40 | ^^^^^^^^ the trait `Debug` is not implemented for `Error`
41 |
42 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
43help: consider annotating `Error` with `#[derive(Debug)]`
44 |
45LL + #[derive(Debug)]
46LL | struct Error;
47 |
48
49error[E0277]: `Error` doesn't implement `Debug`
50 --> $DIR/derives-span-Debug.rs:26:5
51 |
52LL | #[derive(Debug)]
53 | ----- in this derive macro expansion
54LL | struct TupleStruct(
55LL | Error,
56 | ^^^^^ the trait `Debug` is not implemented for `Error`
57 |
58 = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
59help: consider annotating `Error` with `#[derive(Debug)]`
60 |
61LL + #[derive(Debug)]
62LL | struct Error;
63 |
64
65error: aborting due to 4 previous errors
66
67For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/derives-span-Default.rs deleted-16
......@@ -1,16 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Default)] line.
3
4struct Error;
5
6#[derive(Default)]
7struct Struct {
8 x: Error, //~ ERROR
9}
10
11#[derive(Default)]
12struct TupleStruct(
13 Error, //~ ERROR
14);
15
16fn main() {}
tests/ui/derives/derives-span-Default.stderr deleted-33
......@@ -1,33 +0,0 @@
1error[E0277]: the trait bound `Error: Default` is not satisfied
2 --> $DIR/derives-span-Default.rs:8:5
3 |
4LL | #[derive(Default)]
5 | ------- in this derive macro expansion
6LL | struct Struct {
7LL | x: Error,
8 | ^^^^^^^^ the trait `Default` is not implemented for `Error`
9 |
10help: consider annotating `Error` with `#[derive(Default)]`
11 |
12LL + #[derive(Default)]
13LL | struct Error;
14 |
15
16error[E0277]: the trait bound `Error: Default` is not satisfied
17 --> $DIR/derives-span-Default.rs:13:5
18 |
19LL | #[derive(Default)]
20 | ------- in this derive macro expansion
21LL | struct TupleStruct(
22LL | Error,
23 | ^^^^^ the trait `Default` is not implemented for `Error`
24 |
25help: consider annotating `Error` with `#[derive(Default)]`
26 |
27LL + #[derive(Default)]
28LL | struct Error;
29 |
30
31error: aborting due to 2 previous errors
32
33For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/derives-span-Eq.rs deleted-31
......@@ -1,31 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Eq)] line.
3
4#[derive(PartialEq)]
5struct Error;
6
7#[derive(Eq, PartialEq)]
8enum EnumStructVariant {
9 A {
10 x: Error, //~ ERROR
11 },
12}
13
14#[derive(Eq, PartialEq)]
15enum EnumTupleVariant {
16 A(
17 Error, //~ ERROR
18 ),
19}
20
21#[derive(Eq, PartialEq)]
22struct Struct {
23 x: Error, //~ ERROR
24}
25
26#[derive(Eq, PartialEq)]
27struct TupleStruct(
28 Error, //~ ERROR
29);
30
31fn main() {}
tests/ui/derives/derives-span-Eq.stderr deleted-71
......@@ -1,71 +0,0 @@
1error[E0277]: the trait bound `Error: Eq` is not satisfied
2 --> $DIR/derives-span-Eq.rs:10:9
3 |
4LL | #[derive(Eq, PartialEq)]
5 | -- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Eq` is not implemented for `Error`
9 |
10note: required by a bound in `std::cmp::AssertParamIsEq`
11 --> $SRC_DIR/core/src/cmp.rs:LL:COL
12help: consider annotating `Error` with `#[derive(Eq)]`
13 |
14LL + #[derive(Eq)]
15LL | struct Error;
16 |
17
18error[E0277]: the trait bound `Error: Eq` is not satisfied
19 --> $DIR/derives-span-Eq.rs:17:9
20 |
21LL | #[derive(Eq, PartialEq)]
22 | -- in this derive macro expansion
23...
24LL | Error,
25 | ^^^^^ the trait `Eq` is not implemented for `Error`
26 |
27note: required by a bound in `std::cmp::AssertParamIsEq`
28 --> $SRC_DIR/core/src/cmp.rs:LL:COL
29help: consider annotating `Error` with `#[derive(Eq)]`
30 |
31LL + #[derive(Eq)]
32LL | struct Error;
33 |
34
35error[E0277]: the trait bound `Error: Eq` is not satisfied
36 --> $DIR/derives-span-Eq.rs:23:5
37 |
38LL | #[derive(Eq, PartialEq)]
39 | -- in this derive macro expansion
40LL | struct Struct {
41LL | x: Error,
42 | ^^^^^^^^ the trait `Eq` is not implemented for `Error`
43 |
44note: required by a bound in `std::cmp::AssertParamIsEq`
45 --> $SRC_DIR/core/src/cmp.rs:LL:COL
46help: consider annotating `Error` with `#[derive(Eq)]`
47 |
48LL + #[derive(Eq)]
49LL | struct Error;
50 |
51
52error[E0277]: the trait bound `Error: Eq` is not satisfied
53 --> $DIR/derives-span-Eq.rs:28:5
54 |
55LL | #[derive(Eq, PartialEq)]
56 | -- in this derive macro expansion
57LL | struct TupleStruct(
58LL | Error,
59 | ^^^^^ the trait `Eq` is not implemented for `Error`
60 |
61note: required by a bound in `std::cmp::AssertParamIsEq`
62 --> $SRC_DIR/core/src/cmp.rs:LL:COL
63help: consider annotating `Error` with `#[derive(Eq)]`
64 |
65LL + #[derive(Eq)]
66LL | struct Error;
67 |
68
69error: aborting due to 4 previous errors
70
71For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/derives-span-Ord.rs deleted-31
......@@ -1,31 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Ord)] line.
3
4#[derive(Eq, PartialOrd, PartialEq)]
5struct Error;
6
7#[derive(Ord, Eq, PartialOrd, PartialEq)]
8enum EnumStructVariant {
9 A {
10 x: Error, //~ ERROR
11 },
12}
13
14#[derive(Ord, Eq, PartialOrd, PartialEq)]
15enum EnumTupleVariant {
16 A(
17 Error, //~ ERROR
18 ),
19}
20
21#[derive(Ord, Eq, PartialOrd, PartialEq)]
22struct Struct {
23 x: Error, //~ ERROR
24}
25
26#[derive(Ord, Eq, PartialOrd, PartialEq)]
27struct TupleStruct(
28 Error, //~ ERROR
29);
30
31fn main() {}
tests/ui/derives/derives-span-Ord.stderr deleted-63
......@@ -1,63 +0,0 @@
1error[E0277]: the trait bound `Error: Ord` is not satisfied
2 --> $DIR/derives-span-Ord.rs:10:9
3 |
4LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
5 | --- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Ord` is not implemented for `Error`
9 |
10help: consider annotating `Error` with `#[derive(Ord)]`
11 |
12LL + #[derive(Ord)]
13LL | struct Error;
14 |
15
16error[E0277]: the trait bound `Error: Ord` is not satisfied
17 --> $DIR/derives-span-Ord.rs:17:9
18 |
19LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
20 | --- in this derive macro expansion
21...
22LL | Error,
23 | ^^^^^ the trait `Ord` is not implemented for `Error`
24 |
25help: consider annotating `Error` with `#[derive(Ord)]`
26 |
27LL + #[derive(Ord)]
28LL | struct Error;
29 |
30
31error[E0277]: the trait bound `Error: Ord` is not satisfied
32 --> $DIR/derives-span-Ord.rs:23:5
33 |
34LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
35 | --- in this derive macro expansion
36LL | struct Struct {
37LL | x: Error,
38 | ^^^^^^^^ the trait `Ord` is not implemented for `Error`
39 |
40help: consider annotating `Error` with `#[derive(Ord)]`
41 |
42LL + #[derive(Ord)]
43LL | struct Error;
44 |
45
46error[E0277]: the trait bound `Error: Ord` is not satisfied
47 --> $DIR/derives-span-Ord.rs:28:5
48 |
49LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
50 | --- in this derive macro expansion
51LL | struct TupleStruct(
52LL | Error,
53 | ^^^^^ the trait `Ord` is not implemented for `Error`
54 |
55help: consider annotating `Error` with `#[derive(Ord)]`
56 |
57LL + #[derive(Ord)]
58LL | struct Error;
59 |
60
61error: aborting due to 4 previous errors
62
63For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/derives-span-PartialEq.rs deleted-29
......@@ -1,29 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(PartialEq)] line.
3
4struct Error;
5
6#[derive(PartialEq)]
7enum EnumStructVariant {
8 A {
9 x: Error, //~ ERROR
10 },
11}
12
13#[derive(PartialEq)]
14enum EnumTupleVariant {
15 A(
16 Error, //~ ERROR
17 ),
18}
19#[derive(PartialEq)]
20struct Struct {
21 x: Error, //~ ERROR
22}
23
24#[derive(PartialEq)]
25struct TupleStruct(
26 Error, //~ ERROR
27);
28
29fn main() {}
tests/ui/derives/derives-span-PartialEq.stderr deleted-83
......@@ -1,83 +0,0 @@
1error[E0369]: binary operation `==` cannot be applied to type `&Error`
2 --> $DIR/derives-span-PartialEq.rs:9:9
3 |
4LL | #[derive(PartialEq)]
5 | --------- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^
9 |
10note: an implementation of `PartialEq` might be missing for `Error`
11 --> $DIR/derives-span-PartialEq.rs:4:1
12 |
13LL | struct Error;
14 | ^^^^^^^^^^^^ must implement `PartialEq`
15help: consider annotating `Error` with `#[derive(PartialEq)]`
16 |
17LL + #[derive(PartialEq)]
18LL | struct Error;
19 |
20
21error[E0369]: binary operation `==` cannot be applied to type `&Error`
22 --> $DIR/derives-span-PartialEq.rs:16:9
23 |
24LL | #[derive(PartialEq)]
25 | --------- in this derive macro expansion
26...
27LL | Error,
28 | ^^^^^
29 |
30note: an implementation of `PartialEq` might be missing for `Error`
31 --> $DIR/derives-span-PartialEq.rs:4:1
32 |
33LL | struct Error;
34 | ^^^^^^^^^^^^ must implement `PartialEq`
35help: consider annotating `Error` with `#[derive(PartialEq)]`
36 |
37LL + #[derive(PartialEq)]
38LL | struct Error;
39 |
40
41error[E0369]: binary operation `==` cannot be applied to type `Error`
42 --> $DIR/derives-span-PartialEq.rs:21:5
43 |
44LL | #[derive(PartialEq)]
45 | --------- in this derive macro expansion
46LL | struct Struct {
47LL | x: Error,
48 | ^^^^^^^^
49 |
50note: an implementation of `PartialEq` might be missing for `Error`
51 --> $DIR/derives-span-PartialEq.rs:4:1
52 |
53LL | struct Error;
54 | ^^^^^^^^^^^^ must implement `PartialEq`
55help: consider annotating `Error` with `#[derive(PartialEq)]`
56 |
57LL + #[derive(PartialEq)]
58LL | struct Error;
59 |
60
61error[E0369]: binary operation `==` cannot be applied to type `Error`
62 --> $DIR/derives-span-PartialEq.rs:26:5
63 |
64LL | #[derive(PartialEq)]
65 | --------- in this derive macro expansion
66LL | struct TupleStruct(
67LL | Error,
68 | ^^^^^
69 |
70note: an implementation of `PartialEq` might be missing for `Error`
71 --> $DIR/derives-span-PartialEq.rs:4:1
72 |
73LL | struct Error;
74 | ^^^^^^^^^^^^ must implement `PartialEq`
75help: consider annotating `Error` with `#[derive(PartialEq)]`
76 |
77LL + #[derive(PartialEq)]
78LL | struct Error;
79 |
80
81error: aborting due to 4 previous errors
82
83For more information about this error, try `rustc --explain E0369`.
tests/ui/derives/derives-span-PartialOrd.rs deleted-31
......@@ -1,31 +0,0 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(PartialOrd)] line.
3
4#[derive(PartialEq)]
5struct Error;
6
7#[derive(PartialOrd, PartialEq)]
8enum EnumStructVariant {
9 A {
10 x: Error, //~ ERROR
11 },
12}
13
14#[derive(PartialOrd, PartialEq)]
15enum EnumTupleVariant {
16 A(
17 Error, //~ ERROR
18 ),
19}
20
21#[derive(PartialOrd, PartialEq)]
22struct Struct {
23 x: Error, //~ ERROR
24}
25
26#[derive(PartialOrd, PartialEq)]
27struct TupleStruct(
28 Error, //~ ERROR
29);
30
31fn main() {}
tests/ui/derives/derives-span-PartialOrd.stderr deleted-67
......@@ -1,67 +0,0 @@
1error[E0277]: can't compare `Error` with `Error`
2 --> $DIR/derives-span-PartialOrd.rs:10:9
3 |
4LL | #[derive(PartialOrd, PartialEq)]
5 | ---------- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
9 |
10 = help: the trait `PartialOrd` is not implemented for `Error`
11help: consider annotating `Error` with `#[derive(PartialOrd)]`
12 |
13LL + #[derive(PartialOrd)]
14LL | struct Error;
15 |
16
17error[E0277]: can't compare `Error` with `Error`
18 --> $DIR/derives-span-PartialOrd.rs:17:9
19 |
20LL | #[derive(PartialOrd, PartialEq)]
21 | ---------- in this derive macro expansion
22...
23LL | Error,
24 | ^^^^^ no implementation for `Error < Error` and `Error > Error`
25 |
26 = help: the trait `PartialOrd` is not implemented for `Error`
27help: consider annotating `Error` with `#[derive(PartialOrd)]`
28 |
29LL + #[derive(PartialOrd)]
30LL | struct Error;
31 |
32
33error[E0277]: can't compare `Error` with `Error`
34 --> $DIR/derives-span-PartialOrd.rs:23:5
35 |
36LL | #[derive(PartialOrd, PartialEq)]
37 | ---------- in this derive macro expansion
38LL | struct Struct {
39LL | x: Error,
40 | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
41 |
42 = help: the trait `PartialOrd` is not implemented for `Error`
43help: consider annotating `Error` with `#[derive(PartialOrd)]`
44 |
45LL + #[derive(PartialOrd)]
46LL | struct Error;
47 |
48
49error[E0277]: can't compare `Error` with `Error`
50 --> $DIR/derives-span-PartialOrd.rs:28:5
51 |
52LL | #[derive(PartialOrd, PartialEq)]
53 | ---------- in this derive macro expansion
54LL | struct TupleStruct(
55LL | Error,
56 | ^^^^^ no implementation for `Error < Error` and `Error > Error`
57 |
58 = help: the trait `PartialOrd` is not implemented for `Error`
59help: consider annotating `Error` with `#[derive(PartialOrd)]`
60 |
61LL + #[derive(PartialOrd)]
62LL | struct Error;
63 |
64
65error: aborting due to 4 previous errors
66
67For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/deriving-all-codegen.rs created+237
......@@ -0,0 +1,237 @@
1//@ check-pass
2//@ compile-flags: -Zunpretty=expanded
3//@ edition:2021
4//
5// This test checks the code generated for all[*] the builtin derivable traits
6// on a variety of structs and enums. It protects against accidental changes to
7// the generated code, and makes deliberate changes to the generated code
8// easier to review.
9//
10// [*] It excludes `Copy` in some cases, because that changes the code
11// generated for `Clone`.
12//
13// [*] It excludes `RustcEncodable` and `RustDecodable`, which are obsolete and
14// also require the `rustc_serialize` crate.
15
16#![crate_type = "lib"]
17#![allow(dead_code)]
18#![allow(deprecated)]
19#![feature(derive_from)]
20
21use std::from::From;
22
23// Empty struct.
24#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
25struct Empty;
26
27// A basic struct. Note: because this derives `Copy`, it gets the trivial
28// `clone` implemention that just does `*self`.
29#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
30struct Point {
31 x: u32,
32 y: u32,
33}
34
35// A basic packed struct. Note: because this derives `Copy`, it gets the trivial
36// `clone` implemention that just does `*self`.
37#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
38#[repr(packed)]
39struct PackedPoint {
40 x: u32,
41 y: u32,
42}
43
44#[derive(Clone, Copy, Debug, Default, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
45struct TupleSingleField(u32);
46
47#[derive(Clone, Copy, Debug, Default, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
48struct SingleField {
49 foo: bool,
50}
51
52// A large struct. Note: because this derives `Copy`, it gets the trivial
53// `clone` implemention that just does `*self`.
54#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
55struct Big {
56 b1: u32,
57 b2: u32,
58 b3: u32,
59 b4: u32,
60 b5: u32,
61 b6: u32,
62 b7: u32,
63 b8: u32,
64}
65
66// It is more efficient to compare scalar types before non-scalar types.
67#[derive(PartialEq, PartialOrd)]
68struct Reorder {
69 b1: Option<f32>,
70 b2: u16,
71 b3: &'static str,
72 b4: i8,
73 b5: u128,
74 _b: *mut &'static dyn FnMut() -> (),
75 b6: f64,
76 b7: &'static mut (),
77 b8: char,
78 b9: &'static [i64],
79 b10: &'static *const bool,
80}
81
82// A struct that doesn't impl `Copy`, which means it gets the non-trivial
83// `clone` implemention that clones the fields individually.
84#[derive(Clone)]
85struct NonCopy(u32);
86
87// A packed struct that doesn't impl `Copy`, which means it gets the non-trivial
88// `clone` implemention that clones the fields individually.
89#[derive(Clone)]
90#[repr(packed)]
91struct PackedNonCopy(u32);
92
93// A struct that impls `Copy` manually, which means it gets the non-trivial
94// `clone` implemention that clones the fields individually.
95#[derive(Clone)]
96struct ManualCopy(u32);
97impl Copy for ManualCopy {}
98
99// A packed struct that impls `Copy` manually, which means it gets the
100// non-trivial `clone` implemention that clones the fields individually.
101#[derive(Clone)]
102#[repr(packed)]
103struct PackedManualCopy(u32);
104impl Copy for PackedManualCopy {}
105
106// A struct with an unsized field. Some derives are not usable in this case.
107#[derive(Debug, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
108struct Unsized([u32]);
109
110trait Trait {
111 type A;
112}
113
114// A generic struct involving an associated type.
115#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
116struct Generic<T: Trait, U> {
117 t: T,
118 ta: T::A,
119 u: U,
120}
121
122// A packed, generic tuple struct involving an associated type. Because it is
123// packed, a `T: Copy` bound is added to all impls (and where clauses within
124// them) except for `Default`. This is because we must access fields using
125// copies (e.g. `&{self.0}`), instead of using direct references (e.g.
126// `&self.0`) which may be misaligned in a packed struct.
127#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
128#[repr(packed)]
129struct PackedGeneric<T: Trait, U>(T, T::A, U);
130
131// An empty enum.
132#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
133enum Enum0 {}
134
135// A single-variant enum.
136#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
137enum Enum1 {
138 Single { x: u32 },
139}
140
141// A C-like, fieldless enum with a single variant.
142#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
143enum Fieldless1 {
144 #[default]
145 A,
146}
147
148// A C-like, fieldless enum.
149#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
150enum Fieldless {
151 #[default]
152 A,
153 B,
154 C,
155}
156
157// An enum with multiple fieldless and fielded variants.
158#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
159enum Mixed {
160 #[default]
161 P,
162 Q,
163 R(u32),
164 S {
165 d1: Option<u32>,
166 d2: Option<i32>,
167 },
168}
169
170// When comparing enum variant it is more efficient to compare scalar types before non-scalar types.
171#[derive(PartialEq, PartialOrd)]
172enum ReorderEnum {
173 A(i32),
174 B,
175 C(i8),
176 D,
177 E,
178 F,
179 G(&'static mut str, *const u8, *const dyn Fn() -> ()),
180 H,
181 I,
182}
183
184// An enum with no fieldless variants. Note that `Default` cannot be derived
185// for this enum.
186#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
187enum Fielded {
188 X(u32),
189 Y(bool),
190 Z(Option<i32>),
191}
192
193// A generic enum. Note that `Default` cannot be derived for this enum.
194#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
195enum EnumGeneric<T, U> {
196 One(T),
197 Two(U),
198}
199
200// An enum that has variant, which does't implement `Copy`.
201#[derive(PartialEq)]
202enum NonCopyEnum {
203 // The `dyn NonCopyTrait` implements `PartialEq`, but it doesn't require `Copy`.
204 // So we cannot generate `PartialEq` with dereference.
205 NonCopyField(Box<dyn NonCopyTrait>),
206}
207trait NonCopyTrait {}
208impl PartialEq for dyn NonCopyTrait {
209 fn eq(&self, _other: &Self) -> bool {
210 true
211 }
212}
213
214// A union. Most builtin traits are not derivable for unions.
215#[derive(Clone, Copy)]
216pub union Union {
217 pub b: bool,
218 pub u: u32,
219 pub i: i32,
220}
221
222#[derive(Copy, Clone)]
223struct FooCopyClone(i32);
224
225#[derive(Clone, Copy)]
226struct FooCloneCopy(i32);
227
228#[derive(Copy)]
229#[derive(Clone)]
230struct FooCopyAndClone(i32);
231
232// FIXME(#124794): the previous three structs all have a trivial `Copy`-aware
233// `clone`. But this one doesn't because when the `clone` is generated the
234// `derive(Copy)` hasn't yet been seen.
235#[derive(Clone)]
236#[derive(Copy)]
237struct FooCloneAndCopy(i32);
tests/ui/derives/deriving-all-codegen.stdout created+1851
......@@ -0,0 +1,1851 @@
1#![feature(prelude_import)]
2//@ check-pass
3//@ compile-flags: -Zunpretty=expanded
4//@ edition:2021
5//
6// This test checks the code generated for all[*] the builtin derivable traits
7// on a variety of structs and enums. It protects against accidental changes to
8// the generated code, and makes deliberate changes to the generated code
9// easier to review.
10//
11// [*] It excludes `Copy` in some cases, because that changes the code
12// generated for `Clone`.
13//
14// [*] It excludes `RustcEncodable` and `RustDecodable`, which are obsolete and
15// also require the `rustc_serialize` crate.
16
17#![crate_type = "lib"]
18#![allow(dead_code)]
19#![allow(deprecated)]
20#![feature(derive_from)]
21extern crate std;
22#[prelude_import]
23use std::prelude::rust_2021::*;
24
25use std::from::From;
26
27// Empty struct.
28struct Empty;
29#[automatically_derived]
30#[doc(hidden)]
31unsafe impl ::core::clone::TrivialClone for Empty { }
32#[automatically_derived]
33impl ::core::clone::Clone for Empty {
34 #[inline]
35 fn clone(&self) -> Empty { *self }
36}
37#[automatically_derived]
38impl ::core::marker::Copy for Empty { }
39#[automatically_derived]
40impl ::core::fmt::Debug for Empty {
41 #[inline]
42 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
43 ::core::fmt::Formatter::write_str(f, "Empty")
44 }
45}
46#[automatically_derived]
47impl ::core::default::Default for Empty {
48 #[inline]
49 fn default() -> Empty { Empty {} }
50}
51#[automatically_derived]
52impl ::core::hash::Hash for Empty {
53 #[inline]
54 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
55}
56#[automatically_derived]
57impl ::core::marker::StructuralPartialEq for Empty { }
58#[automatically_derived]
59impl ::core::cmp::PartialEq for Empty {
60 #[inline]
61 fn eq(&self, other: &Empty) -> bool { true }
62}
63#[automatically_derived]
64impl ::core::cmp::Eq for Empty {
65 #[inline]
66 #[doc(hidden)]
67 #[coverage(off)]
68 fn assert_fields_are_eq(&self) {}
69}
70#[automatically_derived]
71impl ::core::cmp::PartialOrd for Empty {
72 #[inline]
73 fn partial_cmp(&self, other: &Empty)
74 -> ::core::option::Option<::core::cmp::Ordering> {
75 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
76 }
77}
78#[automatically_derived]
79impl ::core::cmp::Ord for Empty {
80 #[inline]
81 fn cmp(&self, other: &Empty) -> ::core::cmp::Ordering {
82 ::core::cmp::Ordering::Equal
83 }
84}
85
86// A basic struct. Note: because this derives `Copy`, it gets the trivial
87// `clone` implemention that just does `*self`.
88struct Point {
89 x: u32,
90 y: u32,
91}
92#[automatically_derived]
93#[doc(hidden)]
94unsafe impl ::core::clone::TrivialClone for Point { }
95#[automatically_derived]
96impl ::core::clone::Clone for Point {
97 #[inline]
98 fn clone(&self) -> Point {
99 let _: ::core::clone::AssertParamIsClone<u32>;
100 *self
101 }
102}
103#[automatically_derived]
104impl ::core::marker::Copy for Point { }
105#[automatically_derived]
106impl ::core::fmt::Debug for Point {
107 #[inline]
108 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
109 ::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x",
110 &self.x, "y", &&self.y)
111 }
112}
113#[automatically_derived]
114impl ::core::default::Default for Point {
115 #[inline]
116 fn default() -> Point {
117 Point {
118 x: ::core::default::Default::default(),
119 y: ::core::default::Default::default(),
120 }
121 }
122}
123#[automatically_derived]
124impl ::core::hash::Hash for Point {
125 #[inline]
126 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
127 ::core::hash::Hash::hash(&self.x, state);
128 ::core::hash::Hash::hash(&self.y, state)
129 }
130}
131#[automatically_derived]
132impl ::core::marker::StructuralPartialEq for Point { }
133#[automatically_derived]
134impl ::core::cmp::PartialEq for Point {
135 #[inline]
136 fn eq(&self, other: &Point) -> bool {
137 self.x == other.x && self.y == other.y
138 }
139}
140#[automatically_derived]
141impl ::core::cmp::Eq for Point {
142 #[inline]
143 #[doc(hidden)]
144 #[coverage(off)]
145 fn assert_fields_are_eq(&self) {
146 let _: ::core::cmp::AssertParamIsEq<u32>;
147 }
148}
149#[automatically_derived]
150impl ::core::cmp::PartialOrd for Point {
151 #[inline]
152 fn partial_cmp(&self, other: &Point)
153 -> ::core::option::Option<::core::cmp::Ordering> {
154 match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
155 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
156 ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y),
157 cmp => cmp,
158 }
159 }
160}
161#[automatically_derived]
162impl ::core::cmp::Ord for Point {
163 #[inline]
164 fn cmp(&self, other: &Point) -> ::core::cmp::Ordering {
165 match ::core::cmp::Ord::cmp(&self.x, &other.x) {
166 ::core::cmp::Ordering::Equal =>
167 ::core::cmp::Ord::cmp(&self.y, &other.y),
168 cmp => cmp,
169 }
170 }
171}
172
173// A basic packed struct. Note: because this derives `Copy`, it gets the trivial
174// `clone` implemention that just does `*self`.
175#[repr(packed)]
176struct PackedPoint {
177 x: u32,
178 y: u32,
179}
180#[automatically_derived]
181#[doc(hidden)]
182unsafe impl ::core::clone::TrivialClone for PackedPoint { }
183#[automatically_derived]
184impl ::core::clone::Clone for PackedPoint {
185 #[inline]
186 fn clone(&self) -> PackedPoint {
187 let _: ::core::clone::AssertParamIsClone<u32>;
188 *self
189 }
190}
191#[automatically_derived]
192impl ::core::marker::Copy for PackedPoint { }
193#[automatically_derived]
194impl ::core::fmt::Debug for PackedPoint {
195 #[inline]
196 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
197 ::core::fmt::Formatter::debug_struct_field2_finish(f, "PackedPoint",
198 "x", &{ self.x }, "y", &&{ self.y })
199 }
200}
201#[automatically_derived]
202impl ::core::default::Default for PackedPoint {
203 #[inline]
204 fn default() -> PackedPoint {
205 PackedPoint {
206 x: ::core::default::Default::default(),
207 y: ::core::default::Default::default(),
208 }
209 }
210}
211#[automatically_derived]
212impl ::core::hash::Hash for PackedPoint {
213 #[inline]
214 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
215 ::core::hash::Hash::hash(&{ self.x }, state);
216 ::core::hash::Hash::hash(&{ self.y }, state)
217 }
218}
219#[automatically_derived]
220impl ::core::marker::StructuralPartialEq for PackedPoint { }
221#[automatically_derived]
222impl ::core::cmp::PartialEq for PackedPoint {
223 #[inline]
224 fn eq(&self, other: &PackedPoint) -> bool {
225 ({ self.x }) == ({ other.x }) && ({ self.y }) == ({ other.y })
226 }
227}
228#[automatically_derived]
229impl ::core::cmp::Eq for PackedPoint {
230 #[inline]
231 #[doc(hidden)]
232 #[coverage(off)]
233 fn assert_fields_are_eq(&self) {
234 let _: ::core::cmp::AssertParamIsEq<u32>;
235 }
236}
237#[automatically_derived]
238impl ::core::cmp::PartialOrd for PackedPoint {
239 #[inline]
240 fn partial_cmp(&self, other: &PackedPoint)
241 -> ::core::option::Option<::core::cmp::Ordering> {
242 match ::core::cmp::PartialOrd::partial_cmp(&{ self.x }, &{ other.x })
243 {
244 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
245 ::core::cmp::PartialOrd::partial_cmp(&{ self.y },
246 &{ other.y }),
247 cmp => cmp,
248 }
249 }
250}
251#[automatically_derived]
252impl ::core::cmp::Ord for PackedPoint {
253 #[inline]
254 fn cmp(&self, other: &PackedPoint) -> ::core::cmp::Ordering {
255 match ::core::cmp::Ord::cmp(&{ self.x }, &{ other.x }) {
256 ::core::cmp::Ordering::Equal =>
257 ::core::cmp::Ord::cmp(&{ self.y }, &{ other.y }),
258 cmp => cmp,
259 }
260 }
261}
262
263struct TupleSingleField(u32);
264#[automatically_derived]
265#[doc(hidden)]
266unsafe impl ::core::clone::TrivialClone for TupleSingleField { }
267#[automatically_derived]
268impl ::core::clone::Clone for TupleSingleField {
269 #[inline]
270 fn clone(&self) -> TupleSingleField {
271 let _: ::core::clone::AssertParamIsClone<u32>;
272 *self
273 }
274}
275#[automatically_derived]
276impl ::core::marker::Copy for TupleSingleField { }
277#[automatically_derived]
278impl ::core::fmt::Debug for TupleSingleField {
279 #[inline]
280 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
281 ::core::fmt::Formatter::debug_tuple_field1_finish(f,
282 "TupleSingleField", &&self.0)
283 }
284}
285#[automatically_derived]
286impl ::core::default::Default for TupleSingleField {
287 #[inline]
288 fn default() -> TupleSingleField {
289 TupleSingleField(::core::default::Default::default())
290 }
291}
292#[automatically_derived]
293impl ::core::convert::From<u32> for TupleSingleField {
294 #[inline]
295 fn from(value: u32) -> TupleSingleField { Self(value) }
296}
297#[automatically_derived]
298impl ::core::hash::Hash for TupleSingleField {
299 #[inline]
300 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
301 ::core::hash::Hash::hash(&self.0, state)
302 }
303}
304#[automatically_derived]
305impl ::core::marker::StructuralPartialEq for TupleSingleField { }
306#[automatically_derived]
307impl ::core::cmp::PartialEq for TupleSingleField {
308 #[inline]
309 fn eq(&self, other: &TupleSingleField) -> bool { self.0 == other.0 }
310}
311#[automatically_derived]
312impl ::core::cmp::Eq for TupleSingleField {
313 #[inline]
314 #[doc(hidden)]
315 #[coverage(off)]
316 fn assert_fields_are_eq(&self) {
317 let _: ::core::cmp::AssertParamIsEq<u32>;
318 }
319}
320#[automatically_derived]
321impl ::core::cmp::PartialOrd for TupleSingleField {
322 #[inline]
323 fn partial_cmp(&self, other: &TupleSingleField)
324 -> ::core::option::Option<::core::cmp::Ordering> {
325 ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
326 }
327}
328#[automatically_derived]
329impl ::core::cmp::Ord for TupleSingleField {
330 #[inline]
331 fn cmp(&self, other: &TupleSingleField) -> ::core::cmp::Ordering {
332 ::core::cmp::Ord::cmp(&self.0, &other.0)
333 }
334}
335
336struct SingleField {
337 foo: bool,
338}
339#[automatically_derived]
340#[doc(hidden)]
341unsafe impl ::core::clone::TrivialClone for SingleField { }
342#[automatically_derived]
343impl ::core::clone::Clone for SingleField {
344 #[inline]
345 fn clone(&self) -> SingleField {
346 let _: ::core::clone::AssertParamIsClone<bool>;
347 *self
348 }
349}
350#[automatically_derived]
351impl ::core::marker::Copy for SingleField { }
352#[automatically_derived]
353impl ::core::fmt::Debug for SingleField {
354 #[inline]
355 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
356 ::core::fmt::Formatter::debug_struct_field1_finish(f, "SingleField",
357 "foo", &&self.foo)
358 }
359}
360#[automatically_derived]
361impl ::core::default::Default for SingleField {
362 #[inline]
363 fn default() -> SingleField {
364 SingleField { foo: ::core::default::Default::default() }
365 }
366}
367#[automatically_derived]
368impl ::core::convert::From<bool> for SingleField {
369 #[inline]
370 fn from(value: bool) -> SingleField { Self { foo: value } }
371}
372#[automatically_derived]
373impl ::core::hash::Hash for SingleField {
374 #[inline]
375 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
376 ::core::hash::Hash::hash(&self.foo, state)
377 }
378}
379#[automatically_derived]
380impl ::core::marker::StructuralPartialEq for SingleField { }
381#[automatically_derived]
382impl ::core::cmp::PartialEq for SingleField {
383 #[inline]
384 fn eq(&self, other: &SingleField) -> bool { self.foo == other.foo }
385}
386#[automatically_derived]
387impl ::core::cmp::Eq for SingleField {
388 #[inline]
389 #[doc(hidden)]
390 #[coverage(off)]
391 fn assert_fields_are_eq(&self) {
392 let _: ::core::cmp::AssertParamIsEq<bool>;
393 }
394}
395#[automatically_derived]
396impl ::core::cmp::PartialOrd for SingleField {
397 #[inline]
398 fn partial_cmp(&self, other: &SingleField)
399 -> ::core::option::Option<::core::cmp::Ordering> {
400 ::core::cmp::PartialOrd::partial_cmp(&self.foo, &other.foo)
401 }
402}
403#[automatically_derived]
404impl ::core::cmp::Ord for SingleField {
405 #[inline]
406 fn cmp(&self, other: &SingleField) -> ::core::cmp::Ordering {
407 ::core::cmp::Ord::cmp(&self.foo, &other.foo)
408 }
409}
410
411// A large struct. Note: because this derives `Copy`, it gets the trivial
412// `clone` implemention that just does `*self`.
413struct Big {
414 b1: u32,
415 b2: u32,
416 b3: u32,
417 b4: u32,
418 b5: u32,
419 b6: u32,
420 b7: u32,
421 b8: u32,
422}
423#[automatically_derived]
424#[doc(hidden)]
425unsafe impl ::core::clone::TrivialClone for Big { }
426#[automatically_derived]
427impl ::core::clone::Clone for Big {
428 #[inline]
429 fn clone(&self) -> Big {
430 let _: ::core::clone::AssertParamIsClone<u32>;
431 *self
432 }
433}
434#[automatically_derived]
435impl ::core::marker::Copy for Big { }
436#[automatically_derived]
437impl ::core::fmt::Debug for Big {
438 #[inline]
439 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
440 let names: &'static _ =
441 &["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"];
442 let values: &[&dyn ::core::fmt::Debug] =
443 &[&self.b1, &self.b2, &self.b3, &self.b4, &self.b5, &self.b6,
444 &self.b7, &&self.b8];
445 ::core::fmt::Formatter::debug_struct_fields_finish(f, "Big", names,
446 values)
447 }
448}
449#[automatically_derived]
450impl ::core::default::Default for Big {
451 #[inline]
452 fn default() -> Big {
453 Big {
454 b1: ::core::default::Default::default(),
455 b2: ::core::default::Default::default(),
456 b3: ::core::default::Default::default(),
457 b4: ::core::default::Default::default(),
458 b5: ::core::default::Default::default(),
459 b6: ::core::default::Default::default(),
460 b7: ::core::default::Default::default(),
461 b8: ::core::default::Default::default(),
462 }
463 }
464}
465#[automatically_derived]
466impl ::core::hash::Hash for Big {
467 #[inline]
468 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
469 ::core::hash::Hash::hash(&self.b1, state);
470 ::core::hash::Hash::hash(&self.b2, state);
471 ::core::hash::Hash::hash(&self.b3, state);
472 ::core::hash::Hash::hash(&self.b4, state);
473 ::core::hash::Hash::hash(&self.b5, state);
474 ::core::hash::Hash::hash(&self.b6, state);
475 ::core::hash::Hash::hash(&self.b7, state);
476 ::core::hash::Hash::hash(&self.b8, state)
477 }
478}
479#[automatically_derived]
480impl ::core::marker::StructuralPartialEq for Big { }
481#[automatically_derived]
482impl ::core::cmp::PartialEq for Big {
483 #[inline]
484 fn eq(&self, other: &Big) -> bool {
485 self.b1 == other.b1 && self.b2 == other.b2 && self.b3 == other.b3 &&
486 self.b4 == other.b4 && self.b5 == other.b5 &&
487 self.b6 == other.b6 && self.b7 == other.b7 &&
488 self.b8 == other.b8
489 }
490}
491#[automatically_derived]
492impl ::core::cmp::Eq for Big {
493 #[inline]
494 #[doc(hidden)]
495 #[coverage(off)]
496 fn assert_fields_are_eq(&self) {
497 let _: ::core::cmp::AssertParamIsEq<u32>;
498 }
499}
500#[automatically_derived]
501impl ::core::cmp::PartialOrd for Big {
502 #[inline]
503 fn partial_cmp(&self, other: &Big)
504 -> ::core::option::Option<::core::cmp::Ordering> {
505 match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
506 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
507 match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
508 &other.b2) {
509 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
510 =>
511 match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
512 &other.b3) {
513 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
514 =>
515 match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
516 &other.b4) {
517 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
518 =>
519 match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
520 &other.b5) {
521 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
522 =>
523 match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
524 &other.b6) {
525 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
526 =>
527 match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
528 &other.b7) {
529 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
530 =>
531 ::core::cmp::PartialOrd::partial_cmp(&self.b8, &other.b8),
532 cmp => cmp,
533 },
534 cmp => cmp,
535 },
536 cmp => cmp,
537 },
538 cmp => cmp,
539 },
540 cmp => cmp,
541 },
542 cmp => cmp,
543 },
544 cmp => cmp,
545 }
546 }
547}
548#[automatically_derived]
549impl ::core::cmp::Ord for Big {
550 #[inline]
551 fn cmp(&self, other: &Big) -> ::core::cmp::Ordering {
552 match ::core::cmp::Ord::cmp(&self.b1, &other.b1) {
553 ::core::cmp::Ordering::Equal =>
554 match ::core::cmp::Ord::cmp(&self.b2, &other.b2) {
555 ::core::cmp::Ordering::Equal =>
556 match ::core::cmp::Ord::cmp(&self.b3, &other.b3) {
557 ::core::cmp::Ordering::Equal =>
558 match ::core::cmp::Ord::cmp(&self.b4, &other.b4) {
559 ::core::cmp::Ordering::Equal =>
560 match ::core::cmp::Ord::cmp(&self.b5, &other.b5) {
561 ::core::cmp::Ordering::Equal =>
562 match ::core::cmp::Ord::cmp(&self.b6, &other.b6) {
563 ::core::cmp::Ordering::Equal =>
564 match ::core::cmp::Ord::cmp(&self.b7, &other.b7) {
565 ::core::cmp::Ordering::Equal =>
566 ::core::cmp::Ord::cmp(&self.b8, &other.b8),
567 cmp => cmp,
568 },
569 cmp => cmp,
570 },
571 cmp => cmp,
572 },
573 cmp => cmp,
574 },
575 cmp => cmp,
576 },
577 cmp => cmp,
578 },
579 cmp => cmp,
580 }
581 }
582}
583
584// It is more efficient to compare scalar types before non-scalar types.
585struct Reorder {
586 b1: Option<f32>,
587 b2: u16,
588 b3: &'static str,
589 b4: i8,
590 b5: u128,
591 _b: *mut &'static dyn FnMut() -> (),
592 b6: f64,
593 b7: &'static mut (),
594 b8: char,
595 b9: &'static [i64],
596 b10: &'static *const bool,
597}
598#[automatically_derived]
599impl ::core::marker::StructuralPartialEq for Reorder { }
600#[automatically_derived]
601impl ::core::cmp::PartialEq for Reorder {
602 #[inline]
603 fn eq(&self, other: &Reorder) -> bool {
604 self.b2 == other.b2 && self.b4 == other.b4 && self.b5 == other.b5 &&
605 self.b6 == other.b6 && self.b7 == other.b7 &&
606 self.b8 == other.b8 && self.b10 == other.b10 &&
607 self.b1 == other.b1 && self.b3 == other.b3 &&
608 self._b == other._b && self.b9 == other.b9
609 }
610}
611#[automatically_derived]
612impl ::core::cmp::PartialOrd for Reorder {
613 #[inline]
614 fn partial_cmp(&self, other: &Reorder)
615 -> ::core::option::Option<::core::cmp::Ordering> {
616 match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
617 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
618 match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
619 &other.b2) {
620 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
621 =>
622 match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
623 &other.b3) {
624 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
625 =>
626 match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
627 &other.b4) {
628 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
629 =>
630 match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
631 &other.b5) {
632 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
633 =>
634 match ::core::cmp::PartialOrd::partial_cmp(&self._b,
635 &other._b) {
636 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
637 =>
638 match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
639 &other.b6) {
640 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
641 =>
642 match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
643 &other.b7) {
644 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
645 =>
646 match ::core::cmp::PartialOrd::partial_cmp(&self.b8,
647 &other.b8) {
648 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
649 =>
650 match ::core::cmp::PartialOrd::partial_cmp(&self.b9,
651 &other.b9) {
652 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
653 =>
654 ::core::cmp::PartialOrd::partial_cmp(&self.b10, &other.b10),
655 cmp => cmp,
656 },
657 cmp => cmp,
658 },
659 cmp => cmp,
660 },
661 cmp => cmp,
662 },
663 cmp => cmp,
664 },
665 cmp => cmp,
666 },
667 cmp => cmp,
668 },
669 cmp => cmp,
670 },
671 cmp => cmp,
672 },
673 cmp => cmp,
674 }
675 }
676}
677
678// A struct that doesn't impl `Copy`, which means it gets the non-trivial
679// `clone` implemention that clones the fields individually.
680struct NonCopy(u32);
681#[automatically_derived]
682impl ::core::clone::Clone for NonCopy {
683 #[inline]
684 fn clone(&self) -> NonCopy {
685 NonCopy(::core::clone::Clone::clone(&self.0))
686 }
687}
688
689// A packed struct that doesn't impl `Copy`, which means it gets the non-trivial
690// `clone` implemention that clones the fields individually.
691#[repr(packed)]
692struct PackedNonCopy(u32);
693#[automatically_derived]
694impl ::core::clone::Clone for PackedNonCopy {
695 #[inline]
696 fn clone(&self) -> PackedNonCopy {
697 PackedNonCopy(::core::clone::Clone::clone(&{ self.0 }))
698 }
699}
700
701// A struct that impls `Copy` manually, which means it gets the non-trivial
702// `clone` implemention that clones the fields individually.
703struct ManualCopy(u32);
704#[automatically_derived]
705impl ::core::clone::Clone for ManualCopy {
706 #[inline]
707 fn clone(&self) -> ManualCopy {
708 ManualCopy(::core::clone::Clone::clone(&self.0))
709 }
710}
711impl Copy for ManualCopy {}
712
713// A packed struct that impls `Copy` manually, which means it gets the
714// non-trivial `clone` implemention that clones the fields individually.
715#[repr(packed)]
716struct PackedManualCopy(u32);
717#[automatically_derived]
718impl ::core::clone::Clone for PackedManualCopy {
719 #[inline]
720 fn clone(&self) -> PackedManualCopy {
721 PackedManualCopy(::core::clone::Clone::clone(&{ self.0 }))
722 }
723}
724impl Copy for PackedManualCopy {}
725
726// A struct with an unsized field. Some derives are not usable in this case.
727struct Unsized([u32]);
728#[automatically_derived]
729impl ::core::fmt::Debug for Unsized {
730 #[inline]
731 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
732 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Unsized",
733 &&self.0)
734 }
735}
736#[automatically_derived]
737impl ::core::convert::From<[u32]> for Unsized {
738 #[inline]
739 fn from(value: [u32]) -> Unsized { Self(value) }
740}
741#[automatically_derived]
742impl ::core::hash::Hash for Unsized {
743 #[inline]
744 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
745 ::core::hash::Hash::hash(&self.0, state)
746 }
747}
748#[automatically_derived]
749impl ::core::marker::StructuralPartialEq for Unsized { }
750#[automatically_derived]
751impl ::core::cmp::PartialEq for Unsized {
752 #[inline]
753 fn eq(&self, other: &Unsized) -> bool { self.0 == other.0 }
754}
755#[automatically_derived]
756impl ::core::cmp::Eq for Unsized {
757 #[inline]
758 #[doc(hidden)]
759 #[coverage(off)]
760 fn assert_fields_are_eq(&self) {
761 let _: ::core::cmp::AssertParamIsEq<[u32]>;
762 }
763}
764#[automatically_derived]
765impl ::core::cmp::PartialOrd for Unsized {
766 #[inline]
767 fn partial_cmp(&self, other: &Unsized)
768 -> ::core::option::Option<::core::cmp::Ordering> {
769 ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
770 }
771}
772#[automatically_derived]
773impl ::core::cmp::Ord for Unsized {
774 #[inline]
775 fn cmp(&self, other: &Unsized) -> ::core::cmp::Ordering {
776 ::core::cmp::Ord::cmp(&self.0, &other.0)
777 }
778}
779
780trait Trait {
781 type A;
782}
783
784// A generic struct involving an associated type.
785struct Generic<T: Trait, U> {
786 t: T,
787 ta: T::A,
788 u: U,
789}
790#[automatically_derived]
791impl<T: ::core::clone::Clone + Trait, U: ::core::clone::Clone>
792 ::core::clone::Clone for Generic<T, U> where T::A: ::core::clone::Clone {
793 #[inline]
794 fn clone(&self) -> Generic<T, U> {
795 Generic {
796 t: ::core::clone::Clone::clone(&self.t),
797 ta: ::core::clone::Clone::clone(&self.ta),
798 u: ::core::clone::Clone::clone(&self.u),
799 }
800 }
801}
802#[automatically_derived]
803impl<T: ::core::marker::Copy + Trait, U: ::core::marker::Copy>
804 ::core::marker::Copy for Generic<T, U> where T::A: ::core::marker::Copy {
805}
806#[automatically_derived]
807impl<T: ::core::fmt::Debug + Trait, U: ::core::fmt::Debug> ::core::fmt::Debug
808 for Generic<T, U> where T::A: ::core::fmt::Debug {
809 #[inline]
810 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
811 ::core::fmt::Formatter::debug_struct_field3_finish(f, "Generic", "t",
812 &self.t, "ta", &self.ta, "u", &&self.u)
813 }
814}
815#[automatically_derived]
816impl<T: ::core::default::Default + Trait, U: ::core::default::Default>
817 ::core::default::Default for Generic<T, U> where
818 T::A: ::core::default::Default {
819 #[inline]
820 fn default() -> Generic<T, U> {
821 Generic {
822 t: ::core::default::Default::default(),
823 ta: ::core::default::Default::default(),
824 u: ::core::default::Default::default(),
825 }
826 }
827}
828#[automatically_derived]
829impl<T: ::core::hash::Hash + Trait, U: ::core::hash::Hash> ::core::hash::Hash
830 for Generic<T, U> where T::A: ::core::hash::Hash {
831 #[inline]
832 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
833 ::core::hash::Hash::hash(&self.t, state);
834 ::core::hash::Hash::hash(&self.ta, state);
835 ::core::hash::Hash::hash(&self.u, state)
836 }
837}
838#[automatically_derived]
839impl<T: Trait, U> ::core::marker::StructuralPartialEq for Generic<T, U> { }
840#[automatically_derived]
841impl<T: ::core::cmp::PartialEq + Trait, U: ::core::cmp::PartialEq>
842 ::core::cmp::PartialEq for Generic<T, U> where
843 T::A: ::core::cmp::PartialEq {
844 #[inline]
845 fn eq(&self, other: &Generic<T, U>) -> bool {
846 self.t == other.t && self.ta == other.ta && self.u == other.u
847 }
848}
849#[automatically_derived]
850impl<T: ::core::cmp::Eq + Trait, U: ::core::cmp::Eq> ::core::cmp::Eq for
851 Generic<T, U> where T::A: ::core::cmp::Eq {
852 #[inline]
853 #[doc(hidden)]
854 #[coverage(off)]
855 fn assert_fields_are_eq(&self) {
856 let _: ::core::cmp::AssertParamIsEq<T>;
857 let _: ::core::cmp::AssertParamIsEq<T::A>;
858 let _: ::core::cmp::AssertParamIsEq<U>;
859 }
860}
861#[automatically_derived]
862impl<T: ::core::cmp::PartialOrd + Trait, U: ::core::cmp::PartialOrd>
863 ::core::cmp::PartialOrd for Generic<T, U> where
864 T::A: ::core::cmp::PartialOrd {
865 #[inline]
866 fn partial_cmp(&self, other: &Generic<T, U>)
867 -> ::core::option::Option<::core::cmp::Ordering> {
868 match ::core::cmp::PartialOrd::partial_cmp(&self.t, &other.t) {
869 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
870 match ::core::cmp::PartialOrd::partial_cmp(&self.ta,
871 &other.ta) {
872 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
873 => ::core::cmp::PartialOrd::partial_cmp(&self.u, &other.u),
874 cmp => cmp,
875 },
876 cmp => cmp,
877 }
878 }
879}
880#[automatically_derived]
881impl<T: ::core::cmp::Ord + Trait, U: ::core::cmp::Ord> ::core::cmp::Ord for
882 Generic<T, U> where T::A: ::core::cmp::Ord {
883 #[inline]
884 fn cmp(&self, other: &Generic<T, U>) -> ::core::cmp::Ordering {
885 match ::core::cmp::Ord::cmp(&self.t, &other.t) {
886 ::core::cmp::Ordering::Equal =>
887 match ::core::cmp::Ord::cmp(&self.ta, &other.ta) {
888 ::core::cmp::Ordering::Equal =>
889 ::core::cmp::Ord::cmp(&self.u, &other.u),
890 cmp => cmp,
891 },
892 cmp => cmp,
893 }
894 }
895}
896
897// A packed, generic tuple struct involving an associated type. Because it is
898// packed, a `T: Copy` bound is added to all impls (and where clauses within
899// them) except for `Default`. This is because we must access fields using
900// copies (e.g. `&{self.0}`), instead of using direct references (e.g.
901// `&self.0`) which may be misaligned in a packed struct.
902#[repr(packed)]
903struct PackedGeneric<T: Trait, U>(T, T::A, U);
904#[automatically_derived]
905impl<T: ::core::clone::Clone + ::core::marker::Copy + Trait,
906 U: ::core::clone::Clone + ::core::marker::Copy> ::core::clone::Clone for
907 PackedGeneric<T, U> where T::A: ::core::clone::Clone +
908 ::core::marker::Copy {
909 #[inline]
910 fn clone(&self) -> PackedGeneric<T, U> {
911 PackedGeneric(::core::clone::Clone::clone(&{ self.0 }),
912 ::core::clone::Clone::clone(&{ self.1 }),
913 ::core::clone::Clone::clone(&{ self.2 }))
914 }
915}
916#[automatically_derived]
917impl<T: ::core::marker::Copy + Trait, U: ::core::marker::Copy>
918 ::core::marker::Copy for PackedGeneric<T, U> where
919 T::A: ::core::marker::Copy {
920}
921#[automatically_derived]
922impl<T: ::core::fmt::Debug + ::core::marker::Copy + Trait,
923 U: ::core::fmt::Debug + ::core::marker::Copy> ::core::fmt::Debug for
924 PackedGeneric<T, U> where T::A: ::core::fmt::Debug + ::core::marker::Copy
925 {
926 #[inline]
927 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
928 ::core::fmt::Formatter::debug_tuple_field3_finish(f, "PackedGeneric",
929 &{ self.0 }, &{ self.1 }, &&{ self.2 })
930 }
931}
932#[automatically_derived]
933impl<T: ::core::default::Default + Trait, U: ::core::default::Default>
934 ::core::default::Default for PackedGeneric<T, U> where
935 T::A: ::core::default::Default {
936 #[inline]
937 fn default() -> PackedGeneric<T, U> {
938 PackedGeneric(::core::default::Default::default(),
939 ::core::default::Default::default(),
940 ::core::default::Default::default())
941 }
942}
943#[automatically_derived]
944impl<T: ::core::hash::Hash + ::core::marker::Copy + Trait,
945 U: ::core::hash::Hash + ::core::marker::Copy> ::core::hash::Hash for
946 PackedGeneric<T, U> where T::A: ::core::hash::Hash + ::core::marker::Copy
947 {
948 #[inline]
949 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
950 ::core::hash::Hash::hash(&{ self.0 }, state);
951 ::core::hash::Hash::hash(&{ self.1 }, state);
952 ::core::hash::Hash::hash(&{ self.2 }, state)
953 }
954}
955#[automatically_derived]
956impl<T: Trait, U> ::core::marker::StructuralPartialEq for PackedGeneric<T, U>
957 {
958}
959#[automatically_derived]
960impl<T: ::core::cmp::PartialEq + ::core::marker::Copy + Trait,
961 U: ::core::cmp::PartialEq + ::core::marker::Copy> ::core::cmp::PartialEq
962 for PackedGeneric<T, U> where T::A: ::core::cmp::PartialEq +
963 ::core::marker::Copy {
964 #[inline]
965 fn eq(&self, other: &PackedGeneric<T, U>) -> bool {
966 ({ self.0 }) == ({ other.0 }) && ({ self.1 }) == ({ other.1 }) &&
967 ({ self.2 }) == ({ other.2 })
968 }
969}
970#[automatically_derived]
971impl<T: ::core::cmp::Eq + ::core::marker::Copy + Trait, U: ::core::cmp::Eq +
972 ::core::marker::Copy> ::core::cmp::Eq for PackedGeneric<T, U> where
973 T::A: ::core::cmp::Eq + ::core::marker::Copy {
974 #[inline]
975 #[doc(hidden)]
976 #[coverage(off)]
977 fn assert_fields_are_eq(&self) {
978 let _: ::core::cmp::AssertParamIsEq<T>;
979 let _: ::core::cmp::AssertParamIsEq<T::A>;
980 let _: ::core::cmp::AssertParamIsEq<U>;
981 }
982}
983#[automatically_derived]
984impl<T: ::core::cmp::PartialOrd + ::core::marker::Copy + Trait,
985 U: ::core::cmp::PartialOrd + ::core::marker::Copy> ::core::cmp::PartialOrd
986 for PackedGeneric<T, U> where T::A: ::core::cmp::PartialOrd +
987 ::core::marker::Copy {
988 #[inline]
989 fn partial_cmp(&self, other: &PackedGeneric<T, U>)
990 -> ::core::option::Option<::core::cmp::Ordering> {
991 match ::core::cmp::PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
992 {
993 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
994 match ::core::cmp::PartialOrd::partial_cmp(&{ self.1 },
995 &{ other.1 }) {
996 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
997 =>
998 ::core::cmp::PartialOrd::partial_cmp(&{ self.2 },
999 &{ other.2 }),
1000 cmp => cmp,
1001 },
1002 cmp => cmp,
1003 }
1004 }
1005}
1006#[automatically_derived]
1007impl<T: ::core::cmp::Ord + ::core::marker::Copy + Trait, U: ::core::cmp::Ord +
1008 ::core::marker::Copy> ::core::cmp::Ord for PackedGeneric<T, U> where
1009 T::A: ::core::cmp::Ord + ::core::marker::Copy {
1010 #[inline]
1011 fn cmp(&self, other: &PackedGeneric<T, U>) -> ::core::cmp::Ordering {
1012 match ::core::cmp::Ord::cmp(&{ self.0 }, &{ other.0 }) {
1013 ::core::cmp::Ordering::Equal =>
1014 match ::core::cmp::Ord::cmp(&{ self.1 }, &{ other.1 }) {
1015 ::core::cmp::Ordering::Equal =>
1016 ::core::cmp::Ord::cmp(&{ self.2 }, &{ other.2 }),
1017 cmp => cmp,
1018 },
1019 cmp => cmp,
1020 }
1021 }
1022}
1023
1024// An empty enum.
1025enum Enum0 {}
1026#[automatically_derived]
1027#[doc(hidden)]
1028unsafe impl ::core::clone::TrivialClone for Enum0 { }
1029#[automatically_derived]
1030impl ::core::clone::Clone for Enum0 {
1031 #[inline]
1032 fn clone(&self) -> Enum0 { *self }
1033}
1034#[automatically_derived]
1035impl ::core::marker::Copy for Enum0 { }
1036#[automatically_derived]
1037impl ::core::fmt::Debug for Enum0 {
1038 #[inline]
1039 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1040 match *self {}
1041 }
1042}
1043#[automatically_derived]
1044impl ::core::hash::Hash for Enum0 {
1045 #[inline]
1046 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1047 match *self {}
1048 }
1049}
1050#[automatically_derived]
1051impl ::core::marker::StructuralPartialEq for Enum0 { }
1052#[automatically_derived]
1053impl ::core::cmp::PartialEq for Enum0 {
1054 #[inline]
1055 fn eq(&self, other: &Enum0) -> bool { match *self {} }
1056}
1057#[automatically_derived]
1058impl ::core::cmp::Eq for Enum0 {
1059 #[inline]
1060 #[doc(hidden)]
1061 #[coverage(off)]
1062 fn assert_fields_are_eq(&self) {}
1063}
1064#[automatically_derived]
1065impl ::core::cmp::PartialOrd for Enum0 {
1066 #[inline]
1067 fn partial_cmp(&self, other: &Enum0)
1068 -> ::core::option::Option<::core::cmp::Ordering> {
1069 match *self {}
1070 }
1071}
1072#[automatically_derived]
1073impl ::core::cmp::Ord for Enum0 {
1074 #[inline]
1075 fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering { match *self {} }
1076}
1077
1078// A single-variant enum.
1079enum Enum1 {
1080 Single {
1081 x: u32,
1082 },
1083}
1084#[automatically_derived]
1085impl ::core::clone::Clone for Enum1 {
1086 #[inline]
1087 fn clone(&self) -> Enum1 {
1088 match self {
1089 Enum1::Single { x: __self_0 } =>
1090 Enum1::Single { x: ::core::clone::Clone::clone(__self_0) },
1091 }
1092 }
1093}
1094#[automatically_derived]
1095impl ::core::fmt::Debug for Enum1 {
1096 #[inline]
1097 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1098 match self {
1099 Enum1::Single { x: __self_0 } =>
1100 ::core::fmt::Formatter::debug_struct_field1_finish(f,
1101 "Single", "x", &__self_0),
1102 }
1103 }
1104}
1105#[automatically_derived]
1106impl ::core::hash::Hash for Enum1 {
1107 #[inline]
1108 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1109 match self {
1110 Enum1::Single { x: __self_0 } =>
1111 ::core::hash::Hash::hash(__self_0, state),
1112 }
1113 }
1114}
1115#[automatically_derived]
1116impl ::core::marker::StructuralPartialEq for Enum1 { }
1117#[automatically_derived]
1118impl ::core::cmp::PartialEq for Enum1 {
1119 #[inline]
1120 fn eq(&self, other: &Enum1) -> bool {
1121 match (self, other) {
1122 (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
1123 __self_0 == __arg1_0,
1124 }
1125 }
1126}
1127#[automatically_derived]
1128impl ::core::cmp::Eq for Enum1 {
1129 #[inline]
1130 #[doc(hidden)]
1131 #[coverage(off)]
1132 fn assert_fields_are_eq(&self) {
1133 let _: ::core::cmp::AssertParamIsEq<u32>;
1134 }
1135}
1136#[automatically_derived]
1137impl ::core::cmp::PartialOrd for Enum1 {
1138 #[inline]
1139 fn partial_cmp(&self, other: &Enum1)
1140 -> ::core::option::Option<::core::cmp::Ordering> {
1141 match (self, other) {
1142 (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
1143 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1144 }
1145 }
1146}
1147#[automatically_derived]
1148impl ::core::cmp::Ord for Enum1 {
1149 #[inline]
1150 fn cmp(&self, other: &Enum1) -> ::core::cmp::Ordering {
1151 match (self, other) {
1152 (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
1153 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1154 }
1155 }
1156}
1157
1158// A C-like, fieldless enum with a single variant.
1159enum Fieldless1 {
1160
1161 #[default]
1162 A,
1163}
1164#[automatically_derived]
1165impl ::core::clone::Clone for Fieldless1 {
1166 #[inline]
1167 fn clone(&self) -> Fieldless1 { Fieldless1::A }
1168}
1169#[automatically_derived]
1170impl ::core::fmt::Debug for Fieldless1 {
1171 #[inline]
1172 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1173 ::core::fmt::Formatter::write_str(f, "A")
1174 }
1175}
1176#[automatically_derived]
1177impl ::core::default::Default for Fieldless1 {
1178 #[inline]
1179 fn default() -> Fieldless1 { Self::A }
1180}
1181#[automatically_derived]
1182impl ::core::hash::Hash for Fieldless1 {
1183 #[inline]
1184 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
1185}
1186#[automatically_derived]
1187impl ::core::marker::StructuralPartialEq for Fieldless1 { }
1188#[automatically_derived]
1189impl ::core::cmp::PartialEq for Fieldless1 {
1190 #[inline]
1191 fn eq(&self, other: &Fieldless1) -> bool { true }
1192}
1193#[automatically_derived]
1194impl ::core::cmp::Eq for Fieldless1 {
1195 #[inline]
1196 #[doc(hidden)]
1197 #[coverage(off)]
1198 fn assert_fields_are_eq(&self) {}
1199}
1200#[automatically_derived]
1201impl ::core::cmp::PartialOrd for Fieldless1 {
1202 #[inline]
1203 fn partial_cmp(&self, other: &Fieldless1)
1204 -> ::core::option::Option<::core::cmp::Ordering> {
1205 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1206 }
1207}
1208#[automatically_derived]
1209impl ::core::cmp::Ord for Fieldless1 {
1210 #[inline]
1211 fn cmp(&self, other: &Fieldless1) -> ::core::cmp::Ordering {
1212 ::core::cmp::Ordering::Equal
1213 }
1214}
1215
1216// A C-like, fieldless enum.
1217enum Fieldless {
1218
1219 #[default]
1220 A,
1221 B,
1222 C,
1223}
1224#[automatically_derived]
1225#[doc(hidden)]
1226unsafe impl ::core::clone::TrivialClone for Fieldless { }
1227#[automatically_derived]
1228impl ::core::clone::Clone for Fieldless {
1229 #[inline]
1230 fn clone(&self) -> Fieldless { *self }
1231}
1232#[automatically_derived]
1233impl ::core::marker::Copy for Fieldless { }
1234#[automatically_derived]
1235impl ::core::fmt::Debug for Fieldless {
1236 #[inline]
1237 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1238 ::core::fmt::Formatter::write_str(f,
1239 match self {
1240 Fieldless::A => "A",
1241 Fieldless::B => "B",
1242 Fieldless::C => "C",
1243 })
1244 }
1245}
1246#[automatically_derived]
1247impl ::core::default::Default for Fieldless {
1248 #[inline]
1249 fn default() -> Fieldless { Self::A }
1250}
1251#[automatically_derived]
1252impl ::core::hash::Hash for Fieldless {
1253 #[inline]
1254 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1255 let __self_discr = ::core::intrinsics::discriminant_value(self);
1256 ::core::hash::Hash::hash(&__self_discr, state)
1257 }
1258}
1259#[automatically_derived]
1260impl ::core::marker::StructuralPartialEq for Fieldless { }
1261#[automatically_derived]
1262impl ::core::cmp::PartialEq for Fieldless {
1263 #[inline]
1264 fn eq(&self, other: &Fieldless) -> bool {
1265 let __self_discr = ::core::intrinsics::discriminant_value(self);
1266 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1267 __self_discr == __arg1_discr
1268 }
1269}
1270#[automatically_derived]
1271impl ::core::cmp::Eq for Fieldless {
1272 #[inline]
1273 #[doc(hidden)]
1274 #[coverage(off)]
1275 fn assert_fields_are_eq(&self) {}
1276}
1277#[automatically_derived]
1278impl ::core::cmp::PartialOrd for Fieldless {
1279 #[inline]
1280 fn partial_cmp(&self, other: &Fieldless)
1281 -> ::core::option::Option<::core::cmp::Ordering> {
1282 let __self_discr = ::core::intrinsics::discriminant_value(self);
1283 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1284 ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
1285 }
1286}
1287#[automatically_derived]
1288impl ::core::cmp::Ord for Fieldless {
1289 #[inline]
1290 fn cmp(&self, other: &Fieldless) -> ::core::cmp::Ordering {
1291 let __self_discr = ::core::intrinsics::discriminant_value(self);
1292 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1293 ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
1294 }
1295}
1296
1297// An enum with multiple fieldless and fielded variants.
1298enum Mixed {
1299
1300 #[default]
1301 P,
1302 Q,
1303 R(u32),
1304 S {
1305 d1: Option<u32>,
1306 d2: Option<i32>,
1307 },
1308}
1309#[automatically_derived]
1310#[doc(hidden)]
1311unsafe impl ::core::clone::TrivialClone for Mixed { }
1312#[automatically_derived]
1313impl ::core::clone::Clone for Mixed {
1314 #[inline]
1315 fn clone(&self) -> Mixed {
1316 let _: ::core::clone::AssertParamIsClone<u32>;
1317 let _: ::core::clone::AssertParamIsClone<Option<u32>>;
1318 let _: ::core::clone::AssertParamIsClone<Option<i32>>;
1319 *self
1320 }
1321}
1322#[automatically_derived]
1323impl ::core::marker::Copy for Mixed { }
1324#[automatically_derived]
1325impl ::core::fmt::Debug for Mixed {
1326 #[inline]
1327 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1328 match self {
1329 Mixed::P => ::core::fmt::Formatter::write_str(f, "P"),
1330 Mixed::Q => ::core::fmt::Formatter::write_str(f, "Q"),
1331 Mixed::R(__self_0) =>
1332 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "R",
1333 &__self_0),
1334 Mixed::S { d1: __self_0, d2: __self_1 } =>
1335 ::core::fmt::Formatter::debug_struct_field2_finish(f, "S",
1336 "d1", __self_0, "d2", &__self_1),
1337 }
1338 }
1339}
1340#[automatically_derived]
1341impl ::core::default::Default for Mixed {
1342 #[inline]
1343 fn default() -> Mixed { Self::P }
1344}
1345#[automatically_derived]
1346impl ::core::hash::Hash for Mixed {
1347 #[inline]
1348 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1349 let __self_discr = ::core::intrinsics::discriminant_value(self);
1350 ::core::hash::Hash::hash(&__self_discr, state);
1351 match self {
1352 Mixed::R(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1353 Mixed::S { d1: __self_0, d2: __self_1 } => {
1354 ::core::hash::Hash::hash(__self_0, state);
1355 ::core::hash::Hash::hash(__self_1, state)
1356 }
1357 _ => {}
1358 }
1359 }
1360}
1361#[automatically_derived]
1362impl ::core::marker::StructuralPartialEq for Mixed { }
1363#[automatically_derived]
1364impl ::core::cmp::PartialEq for Mixed {
1365 #[inline]
1366 fn eq(&self, other: &Mixed) -> bool {
1367 let __self_discr = ::core::intrinsics::discriminant_value(self);
1368 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1369 __self_discr == __arg1_discr &&
1370 match (self, other) {
1371 (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
1372 __self_0 == __arg1_0,
1373 (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
1374 d1: __arg1_0, d2: __arg1_1 }) =>
1375 __self_0 == __arg1_0 && __self_1 == __arg1_1,
1376 _ => true,
1377 }
1378 }
1379}
1380#[automatically_derived]
1381impl ::core::cmp::Eq for Mixed {
1382 #[inline]
1383 #[doc(hidden)]
1384 #[coverage(off)]
1385 fn assert_fields_are_eq(&self) {
1386 let _: ::core::cmp::AssertParamIsEq<u32>;
1387 let _: ::core::cmp::AssertParamIsEq<Option<u32>>;
1388 let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
1389 }
1390}
1391#[automatically_derived]
1392impl ::core::cmp::PartialOrd for Mixed {
1393 #[inline]
1394 fn partial_cmp(&self, other: &Mixed)
1395 -> ::core::option::Option<::core::cmp::Ordering> {
1396 let __self_discr = ::core::intrinsics::discriminant_value(self);
1397 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1398 match (self, other) {
1399 (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
1400 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1401 (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
1402 d1: __arg1_0, d2: __arg1_1 }) =>
1403 match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
1404 {
1405 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1406 => ::core::cmp::PartialOrd::partial_cmp(__self_1, __arg1_1),
1407 cmp => cmp,
1408 },
1409 _ =>
1410 ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1411 &__arg1_discr),
1412 }
1413 }
1414}
1415#[automatically_derived]
1416impl ::core::cmp::Ord for Mixed {
1417 #[inline]
1418 fn cmp(&self, other: &Mixed) -> ::core::cmp::Ordering {
1419 let __self_discr = ::core::intrinsics::discriminant_value(self);
1420 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1421 match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
1422 ::core::cmp::Ordering::Equal =>
1423 match (self, other) {
1424 (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
1425 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1426 (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
1427 d1: __arg1_0, d2: __arg1_1 }) =>
1428 match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
1429 ::core::cmp::Ordering::Equal =>
1430 ::core::cmp::Ord::cmp(__self_1, __arg1_1),
1431 cmp => cmp,
1432 },
1433 _ => ::core::cmp::Ordering::Equal,
1434 },
1435 cmp => cmp,
1436 }
1437 }
1438}
1439
1440// When comparing enum variant it is more efficient to compare scalar types before non-scalar types.
1441enum ReorderEnum {
1442 A(i32),
1443 B,
1444 C(i8),
1445 D,
1446 E,
1447 F,
1448 G(&'static mut str, *const u8, *const dyn Fn() -> ()),
1449 H,
1450 I,
1451}
1452#[automatically_derived]
1453impl ::core::marker::StructuralPartialEq for ReorderEnum { }
1454#[automatically_derived]
1455impl ::core::cmp::PartialEq for ReorderEnum {
1456 #[inline]
1457 fn eq(&self, other: &ReorderEnum) -> bool {
1458 let __self_discr = ::core::intrinsics::discriminant_value(self);
1459 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1460 __self_discr == __arg1_discr &&
1461 match (self, other) {
1462 (ReorderEnum::A(__self_0), ReorderEnum::A(__arg1_0)) =>
1463 __self_0 == __arg1_0,
1464 (ReorderEnum::C(__self_0), ReorderEnum::C(__arg1_0)) =>
1465 __self_0 == __arg1_0,
1466 (ReorderEnum::G(__self_0, __self_1, __self_2),
1467 ReorderEnum::G(__arg1_0, __arg1_1, __arg1_2)) =>
1468 __self_1 == __arg1_1 && __self_0 == __arg1_0 &&
1469 __self_2 == __arg1_2,
1470 _ => true,
1471 }
1472 }
1473}
1474#[automatically_derived]
1475impl ::core::cmp::PartialOrd for ReorderEnum {
1476 #[inline]
1477 fn partial_cmp(&self, other: &ReorderEnum)
1478 -> ::core::option::Option<::core::cmp::Ordering> {
1479 let __self_discr = ::core::intrinsics::discriminant_value(self);
1480 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1481 match ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1482 &__arg1_discr) {
1483 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
1484 match (self, other) {
1485 (ReorderEnum::A(__self_0), ReorderEnum::A(__arg1_0)) =>
1486 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1487 (ReorderEnum::C(__self_0), ReorderEnum::C(__arg1_0)) =>
1488 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1489 (ReorderEnum::G(__self_0, __self_1, __self_2),
1490 ReorderEnum::G(__arg1_0, __arg1_1, __arg1_2)) =>
1491 match ::core::cmp::PartialOrd::partial_cmp(__self_0,
1492 __arg1_0) {
1493 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1494 =>
1495 match ::core::cmp::PartialOrd::partial_cmp(__self_1,
1496 __arg1_1) {
1497 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1498 => ::core::cmp::PartialOrd::partial_cmp(__self_2, __arg1_2),
1499 cmp => cmp,
1500 },
1501 cmp => cmp,
1502 },
1503 _ =>
1504 ::core::option::Option::Some(::core::cmp::Ordering::Equal),
1505 },
1506 cmp => cmp,
1507 }
1508 }
1509}
1510
1511// An enum with no fieldless variants. Note that `Default` cannot be derived
1512// for this enum.
1513enum Fielded { X(u32), Y(bool), Z(Option<i32>), }
1514#[automatically_derived]
1515impl ::core::clone::Clone for Fielded {
1516 #[inline]
1517 fn clone(&self) -> Fielded {
1518 match self {
1519 Fielded::X(__self_0) =>
1520 Fielded::X(::core::clone::Clone::clone(__self_0)),
1521 Fielded::Y(__self_0) =>
1522 Fielded::Y(::core::clone::Clone::clone(__self_0)),
1523 Fielded::Z(__self_0) =>
1524 Fielded::Z(::core::clone::Clone::clone(__self_0)),
1525 }
1526 }
1527}
1528#[automatically_derived]
1529impl ::core::fmt::Debug for Fielded {
1530 #[inline]
1531 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1532 match self {
1533 Fielded::X(__self_0) =>
1534 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "X",
1535 &__self_0),
1536 Fielded::Y(__self_0) =>
1537 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Y",
1538 &__self_0),
1539 Fielded::Z(__self_0) =>
1540 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Z",
1541 &__self_0),
1542 }
1543 }
1544}
1545#[automatically_derived]
1546impl ::core::hash::Hash for Fielded {
1547 #[inline]
1548 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1549 let __self_discr = ::core::intrinsics::discriminant_value(self);
1550 ::core::hash::Hash::hash(&__self_discr, state);
1551 match self {
1552 Fielded::X(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1553 Fielded::Y(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1554 Fielded::Z(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1555 }
1556 }
1557}
1558#[automatically_derived]
1559impl ::core::marker::StructuralPartialEq for Fielded { }
1560#[automatically_derived]
1561impl ::core::cmp::PartialEq for Fielded {
1562 #[inline]
1563 fn eq(&self, other: &Fielded) -> bool {
1564 let __self_discr = ::core::intrinsics::discriminant_value(self);
1565 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1566 __self_discr == __arg1_discr &&
1567 match (self, other) {
1568 (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
1569 __self_0 == __arg1_0,
1570 (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
1571 __self_0 == __arg1_0,
1572 (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
1573 __self_0 == __arg1_0,
1574 _ => unsafe { ::core::intrinsics::unreachable() }
1575 }
1576 }
1577}
1578#[automatically_derived]
1579impl ::core::cmp::Eq for Fielded {
1580 #[inline]
1581 #[doc(hidden)]
1582 #[coverage(off)]
1583 fn assert_fields_are_eq(&self) {
1584 let _: ::core::cmp::AssertParamIsEq<u32>;
1585 let _: ::core::cmp::AssertParamIsEq<bool>;
1586 let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
1587 }
1588}
1589#[automatically_derived]
1590impl ::core::cmp::PartialOrd for Fielded {
1591 #[inline]
1592 fn partial_cmp(&self, other: &Fielded)
1593 -> ::core::option::Option<::core::cmp::Ordering> {
1594 let __self_discr = ::core::intrinsics::discriminant_value(self);
1595 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1596 match (self, other) {
1597 (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
1598 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1599 (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
1600 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1601 (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
1602 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1603 _ =>
1604 ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1605 &__arg1_discr),
1606 }
1607 }
1608}
1609#[automatically_derived]
1610impl ::core::cmp::Ord for Fielded {
1611 #[inline]
1612 fn cmp(&self, other: &Fielded) -> ::core::cmp::Ordering {
1613 let __self_discr = ::core::intrinsics::discriminant_value(self);
1614 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1615 match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
1616 ::core::cmp::Ordering::Equal =>
1617 match (self, other) {
1618 (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
1619 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1620 (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
1621 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1622 (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
1623 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1624 _ => unsafe { ::core::intrinsics::unreachable() }
1625 },
1626 cmp => cmp,
1627 }
1628 }
1629}
1630
1631// A generic enum. Note that `Default` cannot be derived for this enum.
1632enum EnumGeneric<T, U> { One(T), Two(U), }
1633#[automatically_derived]
1634impl<T: ::core::clone::Clone, U: ::core::clone::Clone> ::core::clone::Clone
1635 for EnumGeneric<T, U> {
1636 #[inline]
1637 fn clone(&self) -> EnumGeneric<T, U> {
1638 match self {
1639 EnumGeneric::One(__self_0) =>
1640 EnumGeneric::One(::core::clone::Clone::clone(__self_0)),
1641 EnumGeneric::Two(__self_0) =>
1642 EnumGeneric::Two(::core::clone::Clone::clone(__self_0)),
1643 }
1644 }
1645}
1646#[automatically_derived]
1647impl<T: ::core::marker::Copy, U: ::core::marker::Copy> ::core::marker::Copy
1648 for EnumGeneric<T, U> {
1649}
1650#[automatically_derived]
1651impl<T: ::core::fmt::Debug, U: ::core::fmt::Debug> ::core::fmt::Debug for
1652 EnumGeneric<T, U> {
1653 #[inline]
1654 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1655 match self {
1656 EnumGeneric::One(__self_0) =>
1657 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "One",
1658 &__self_0),
1659 EnumGeneric::Two(__self_0) =>
1660 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Two",
1661 &__self_0),
1662 }
1663 }
1664}
1665#[automatically_derived]
1666impl<T: ::core::hash::Hash, U: ::core::hash::Hash> ::core::hash::Hash for
1667 EnumGeneric<T, U> {
1668 #[inline]
1669 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1670 let __self_discr = ::core::intrinsics::discriminant_value(self);
1671 ::core::hash::Hash::hash(&__self_discr, state);
1672 match self {
1673 EnumGeneric::One(__self_0) =>
1674 ::core::hash::Hash::hash(__self_0, state),
1675 EnumGeneric::Two(__self_0) =>
1676 ::core::hash::Hash::hash(__self_0, state),
1677 }
1678 }
1679}
1680#[automatically_derived]
1681impl<T, U> ::core::marker::StructuralPartialEq for EnumGeneric<T, U> { }
1682#[automatically_derived]
1683impl<T: ::core::cmp::PartialEq, U: ::core::cmp::PartialEq>
1684 ::core::cmp::PartialEq for EnumGeneric<T, U> {
1685 #[inline]
1686 fn eq(&self, other: &EnumGeneric<T, U>) -> bool {
1687 let __self_discr = ::core::intrinsics::discriminant_value(self);
1688 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1689 __self_discr == __arg1_discr &&
1690 match (self, other) {
1691 (EnumGeneric::One(__self_0), EnumGeneric::One(__arg1_0)) =>
1692 __self_0 == __arg1_0,
1693 (EnumGeneric::Two(__self_0), EnumGeneric::Two(__arg1_0)) =>
1694 __self_0 == __arg1_0,
1695 _ => unsafe { ::core::intrinsics::unreachable() }
1696 }
1697 }
1698}
1699#[automatically_derived]
1700impl<T: ::core::cmp::Eq, U: ::core::cmp::Eq> ::core::cmp::Eq for
1701 EnumGeneric<T, U> {
1702 #[inline]
1703 #[doc(hidden)]
1704 #[coverage(off)]
1705 fn assert_fields_are_eq(&self) {
1706 let _: ::core::cmp::AssertParamIsEq<T>;
1707 let _: ::core::cmp::AssertParamIsEq<U>;
1708 }
1709}
1710#[automatically_derived]
1711impl<T: ::core::cmp::PartialOrd, U: ::core::cmp::PartialOrd>
1712 ::core::cmp::PartialOrd for EnumGeneric<T, U> {
1713 #[inline]
1714 fn partial_cmp(&self, other: &EnumGeneric<T, U>)
1715 -> ::core::option::Option<::core::cmp::Ordering> {
1716 let __self_discr = ::core::intrinsics::discriminant_value(self);
1717 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1718 match (self, other) {
1719 (EnumGeneric::One(__self_0), EnumGeneric::One(__arg1_0)) =>
1720 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1721 (EnumGeneric::Two(__self_0), EnumGeneric::Two(__arg1_0)) =>
1722 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1723 _ =>
1724 ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1725 &__arg1_discr),
1726 }
1727 }
1728}
1729#[automatically_derived]
1730impl<T: ::core::cmp::Ord, U: ::core::cmp::Ord> ::core::cmp::Ord for
1731 EnumGeneric<T, U> {
1732 #[inline]
1733 fn cmp(&self, other: &EnumGeneric<T, U>) -> ::core::cmp::Ordering {
1734 let __self_discr = ::core::intrinsics::discriminant_value(self);
1735 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1736 match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
1737 ::core::cmp::Ordering::Equal =>
1738 match (self, other) {
1739 (EnumGeneric::One(__self_0), EnumGeneric::One(__arg1_0)) =>
1740 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1741 (EnumGeneric::Two(__self_0), EnumGeneric::Two(__arg1_0)) =>
1742 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1743 _ => unsafe { ::core::intrinsics::unreachable() }
1744 },
1745 cmp => cmp,
1746 }
1747 }
1748}
1749
1750// An enum that has variant, which does't implement `Copy`.
1751enum NonCopyEnum {
1752
1753 // The `dyn NonCopyTrait` implements `PartialEq`, but it doesn't require `Copy`.
1754 // So we cannot generate `PartialEq` with dereference.
1755 NonCopyField(Box<dyn NonCopyTrait>),
1756}
1757#[automatically_derived]
1758impl ::core::marker::StructuralPartialEq for NonCopyEnum { }
1759#[automatically_derived]
1760impl ::core::cmp::PartialEq for NonCopyEnum {
1761 #[inline]
1762 fn eq(&self, other: &NonCopyEnum) -> bool {
1763 match (self, other) {
1764 (NonCopyEnum::NonCopyField(__self_0),
1765 NonCopyEnum::NonCopyField(__arg1_0)) => __self_0 == __arg1_0,
1766 }
1767 }
1768}
1769trait NonCopyTrait {}
1770impl PartialEq for dyn NonCopyTrait {
1771 fn eq(&self, _other: &Self) -> bool { true }
1772}
1773
1774// A union. Most builtin traits are not derivable for unions.
1775pub union Union {
1776 pub b: bool,
1777 pub u: u32,
1778 pub i: i32,
1779}
1780#[automatically_derived]
1781#[doc(hidden)]
1782unsafe impl ::core::clone::TrivialClone for Union { }
1783#[automatically_derived]
1784impl ::core::clone::Clone for Union {
1785 #[inline]
1786 fn clone(&self) -> Union {
1787 let _: ::core::clone::AssertParamIsCopy<Self>;
1788 *self
1789 }
1790}
1791#[automatically_derived]
1792impl ::core::marker::Copy for Union { }
1793
1794struct FooCopyClone(i32);
1795#[automatically_derived]
1796impl ::core::marker::Copy for FooCopyClone { }
1797#[automatically_derived]
1798#[doc(hidden)]
1799unsafe impl ::core::clone::TrivialClone for FooCopyClone { }
1800#[automatically_derived]
1801impl ::core::clone::Clone for FooCopyClone {
1802 #[inline]
1803 fn clone(&self) -> FooCopyClone {
1804 let _: ::core::clone::AssertParamIsClone<i32>;
1805 *self
1806 }
1807}
1808
1809struct FooCloneCopy(i32);
1810#[automatically_derived]
1811#[doc(hidden)]
1812unsafe impl ::core::clone::TrivialClone for FooCloneCopy { }
1813#[automatically_derived]
1814impl ::core::clone::Clone for FooCloneCopy {
1815 #[inline]
1816 fn clone(&self) -> FooCloneCopy {
1817 let _: ::core::clone::AssertParamIsClone<i32>;
1818 *self
1819 }
1820}
1821#[automatically_derived]
1822impl ::core::marker::Copy for FooCloneCopy { }
1823
1824struct FooCopyAndClone(i32);
1825#[automatically_derived]
1826#[doc(hidden)]
1827unsafe impl ::core::clone::TrivialClone for FooCopyAndClone { }
1828#[automatically_derived]
1829impl ::core::clone::Clone for FooCopyAndClone {
1830 #[inline]
1831 fn clone(&self) -> FooCopyAndClone {
1832 let _: ::core::clone::AssertParamIsClone<i32>;
1833 *self
1834 }
1835}
1836#[automatically_derived]
1837impl ::core::marker::Copy for FooCopyAndClone { }
1838
1839// FIXME(#124794): the previous three structs all have a trivial `Copy`-aware
1840// `clone`. But this one doesn't because when the `clone` is generated the
1841// `derive(Copy)` hasn't yet been seen.
1842struct FooCloneAndCopy(i32);
1843#[automatically_derived]
1844impl ::core::marker::Copy for FooCloneAndCopy { }
1845#[automatically_derived]
1846impl ::core::clone::Clone for FooCloneAndCopy {
1847 #[inline]
1848 fn clone(&self) -> FooCloneAndCopy {
1849 FooCloneAndCopy(::core::clone::Clone::clone(&self.0))
1850 }
1851}
tests/ui/derives/deriving-associated-types.rs created+199
......@@ -0,0 +1,199 @@
1//@ run-pass
2pub trait DeclaredTrait {
3 type Type;
4}
5
6impl DeclaredTrait for i32 {
7 type Type = i32;
8}
9
10pub trait WhereTrait {
11 type Type;
12}
13
14impl WhereTrait for i32 {
15 type Type = i32;
16}
17
18// Make sure we don't add a bound that just shares a name with an associated
19// type.
20pub mod module {
21 pub type Type = i32;
22}
23
24#[derive(PartialEq, Debug)]
25struct PrivateStruct<T>(T);
26
27#[derive(PartialEq, Debug)]
28struct TupleStruct<A, B: DeclaredTrait, C>(
29 module::Type,
30 Option<module::Type>,
31 A,
32 PrivateStruct<A>,
33 B,
34 B::Type,
35 Option<B::Type>,
36 <B as DeclaredTrait>::Type,
37 Option<<B as DeclaredTrait>::Type>,
38 C,
39 C::Type,
40 Option<C::Type>,
41 <C as WhereTrait>::Type,
42 Option<<C as WhereTrait>::Type>,
43 <i32 as DeclaredTrait>::Type,
44) where C: WhereTrait;
45
46#[derive(PartialEq, Debug)]
47pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait {
48 m1: module::Type,
49 m2: Option<module::Type>,
50 a1: A,
51 a2: PrivateStruct<A>,
52 b: B,
53 b1: B::Type,
54 b2: Option<B::Type>,
55 b3: <B as DeclaredTrait>::Type,
56 b4: Option<<B as DeclaredTrait>::Type>,
57 c: C,
58 c1: C::Type,
59 c2: Option<C::Type>,
60 c3: <C as WhereTrait>::Type,
61 c4: Option<<C as WhereTrait>::Type>,
62 d: <i32 as DeclaredTrait>::Type,
63}
64
65#[derive(PartialEq, Debug)]
66enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait {
67 Unit,
68 Seq(
69 module::Type,
70 Option<module::Type>,
71 A,
72 PrivateStruct<A>,
73 B,
74 B::Type,
75 Option<B::Type>,
76 <B as DeclaredTrait>::Type,
77 Option<<B as DeclaredTrait>::Type>,
78 C,
79 C::Type,
80 Option<C::Type>,
81 <C as WhereTrait>::Type,
82 Option<<C as WhereTrait>::Type>,
83 <i32 as DeclaredTrait>::Type,
84 ),
85 Map {
86 m1: module::Type,
87 m2: Option<module::Type>,
88 a1: A,
89 a2: PrivateStruct<A>,
90 b: B,
91 b1: B::Type,
92 b2: Option<B::Type>,
93 b3: <B as DeclaredTrait>::Type,
94 b4: Option<<B as DeclaredTrait>::Type>,
95 c: C,
96 c1: C::Type,
97 c2: Option<C::Type>,
98 c3: <C as WhereTrait>::Type,
99 c4: Option<<C as WhereTrait>::Type>,
100 d: <i32 as DeclaredTrait>::Type,
101 },
102}
103
104fn main() {
105 let e: TupleStruct<
106 i32,
107 i32,
108 i32,
109 > = TupleStruct(
110 0,
111 None,
112 0,
113 PrivateStruct(0),
114 0,
115 0,
116 None,
117 0,
118 None,
119 0,
120 0,
121 None,
122 0,
123 None,
124 0,
125 );
126 assert_eq!(e, e);
127
128 let e: Struct<
129 i32,
130 i32,
131 i32,
132 > = Struct {
133 m1: 0,
134 m2: None,
135 a1: 0,
136 a2: PrivateStruct(0),
137 b: 0,
138 b1: 0,
139 b2: None,
140 b3: 0,
141 b4: None,
142 c: 0,
143 c1: 0,
144 c2: None,
145 c3: 0,
146 c4: None,
147 d: 0,
148 };
149 assert_eq!(e, e);
150
151 let e = Enum::Unit::<i32, i32, i32>;
152 assert_eq!(e, e);
153
154 let e: Enum<
155 i32,
156 i32,
157 i32,
158 > = Enum::Seq(
159 0,
160 None,
161 0,
162 PrivateStruct(0),
163 0,
164 0,
165 None,
166 0,
167 None,
168 0,
169 0,
170 None,
171 0,
172 None,
173 0,
174 );
175 assert_eq!(e, e);
176
177 let e: Enum<
178 i32,
179 i32,
180 i32,
181 > = Enum::Map {
182 m1: 0,
183 m2: None,
184 a1: 0,
185 a2: PrivateStruct(0),
186 b: 0,
187 b1: 0,
188 b2: None,
189 b3: 0,
190 b4: None,
191 c: 0,
192 c1: 0,
193 c2: None,
194 c3: 0,
195 c4: None,
196 d: 0,
197 };
198 assert_eq!(e, e);
199}
tests/ui/derives/deriving-copyclone.rs deleted-37
......@@ -1,37 +0,0 @@
1// this will get a no-op Clone impl
2#[derive(Copy, Clone)]
3struct A {
4 a: i32,
5 b: i64
6}
7
8// this will get a deep Clone impl
9#[derive(Copy, Clone)]
10struct B<T> {
11 a: i32,
12 b: T
13}
14
15struct C; // not Copy or Clone
16#[derive(Clone)] struct D; // Clone but not Copy
17
18fn is_copy<T: Copy>(_: T) {}
19fn is_clone<T: Clone>(_: T) {}
20
21fn main() {
22 // A can be copied and cloned
23 is_copy(A { a: 1, b: 2 });
24 is_clone(A { a: 1, b: 2 });
25
26 // B<i32> can be copied and cloned
27 is_copy(B { a: 1, b: 2 });
28 is_clone(B { a: 1, b: 2 });
29
30 // B<C> cannot be copied or cloned
31 is_copy(B { a: 1, b: C }); //~ ERROR Copy
32 is_clone(B { a: 1, b: C }); //~ ERROR Clone
33
34 // B<D> can be cloned but not copied
35 is_copy(B { a: 1, b: D }); //~ ERROR Copy
36 is_clone(B { a: 1, b: D });
37}
tests/ui/derives/deriving-copyclone.stderr deleted-79
......@@ -1,79 +0,0 @@
1error[E0277]: the trait bound `B<C>: Copy` is not satisfied
2 --> $DIR/deriving-copyclone.rs:31:26
3 |
4LL | is_copy(B { a: 1, b: C });
5 | ------- ^ the trait `Copy` is not implemented for `B<C>`
6 | |
7 | required by a bound introduced by this call
8 |
9note: required for `B<C>` to implement `Copy`
10 --> $DIR/deriving-copyclone.rs:10:8
11 |
12LL | #[derive(Copy, Clone)]
13 | ---- in this derive macro expansion
14LL | struct B<T> {
15 | ^ - type parameter would need to implement `Copy`
16note: required by a bound in `is_copy`
17 --> $DIR/deriving-copyclone.rs:18:15
18 |
19LL | fn is_copy<T: Copy>(_: T) {}
20 | ^^^^ required by this bound in `is_copy`
21help: consider borrowing here
22 |
23LL | is_copy(B { a: 1, b: &C });
24 | +
25
26error[E0277]: the trait bound `B<C>: Clone` is not satisfied
27 --> $DIR/deriving-copyclone.rs:32:27
28 |
29LL | is_clone(B { a: 1, b: C });
30 | -------- ^ the trait `Clone` is not implemented for `B<C>`
31 | |
32 | required by a bound introduced by this call
33 |
34note: required for `B<C>` to implement `Clone`
35 --> $DIR/deriving-copyclone.rs:10:8
36 |
37LL | #[derive(Copy, Clone)]
38 | ----- in this derive macro expansion
39LL | struct B<T> {
40 | ^ - type parameter would need to implement `Clone`
41 = help: consider manually implementing `Clone` to avoid undesired bounds
42note: required by a bound in `is_clone`
43 --> $DIR/deriving-copyclone.rs:19:16
44 |
45LL | fn is_clone<T: Clone>(_: T) {}
46 | ^^^^^ required by this bound in `is_clone`
47help: consider borrowing here
48 |
49LL | is_clone(B { a: 1, b: &C });
50 | +
51
52error[E0277]: the trait bound `B<D>: Copy` is not satisfied
53 --> $DIR/deriving-copyclone.rs:35:26
54 |
55LL | is_copy(B { a: 1, b: D });
56 | ------- ^ the trait `Copy` is not implemented for `B<D>`
57 | |
58 | required by a bound introduced by this call
59 |
60note: required for `B<D>` to implement `Copy`
61 --> $DIR/deriving-copyclone.rs:10:8
62 |
63LL | #[derive(Copy, Clone)]
64 | ---- in this derive macro expansion
65LL | struct B<T> {
66 | ^ - type parameter would need to implement `Copy`
67note: required by a bound in `is_copy`
68 --> $DIR/deriving-copyclone.rs:18:15
69 |
70LL | fn is_copy<T: Copy>(_: T) {}
71 | ^^^^ required by this bound in `is_copy`
72help: consider borrowing here
73 |
74LL | is_copy(B { a: 1, b: &D });
75 | +
76
77error: aborting due to 3 previous errors
78
79For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/deriving-from-wrong-target.rs created+37
......@@ -0,0 +1,37 @@
1//@ check-fail
2
3#![feature(derive_from)]
4#![allow(dead_code)]
5
6use std::from::From;
7
8#[derive(From)]
9//~^ ERROR `#[derive(From)]` used on a struct with no fields
10struct S1;
11
12#[derive(From)]
13//~^ ERROR `#[derive(From)]` used on a struct with no fields
14struct S2 {}
15
16#[derive(From)]
17//~^ ERROR `#[derive(From)]` used on a struct with multiple fields
18struct S3(u32, bool);
19
20#[derive(From)]
21//~^ ERROR `#[derive(From)]` used on a struct with multiple fields
22struct S4 {
23 a: u32,
24 b: bool,
25}
26
27#[derive(From)]
28//~^ ERROR `#[derive(From)]` used on an enum
29enum E1 {}
30
31#[derive(From)]
32struct SUnsizedField<T: ?Sized> {
33 last: T,
34 //~^ ERROR the size for values of type `T` cannot be known at compilation time [E0277]
35}
36
37fn main() {}
tests/ui/derives/deriving-from-wrong-target.stderr created+77
......@@ -0,0 +1,77 @@
1error: `#[derive(From)]` used on a struct with no fields
2 --> $DIR/deriving-from-wrong-target.rs:8:10
3 |
4LL | #[derive(From)]
5 | ^^^^
6LL |
7LL | struct S1;
8 | ^^
9 |
10 = note: `#[derive(From)]` can only be used on structs with exactly one field
11
12error: `#[derive(From)]` used on a struct with no fields
13 --> $DIR/deriving-from-wrong-target.rs:12:10
14 |
15LL | #[derive(From)]
16 | ^^^^
17LL |
18LL | struct S2 {}
19 | ^^
20 |
21 = note: `#[derive(From)]` can only be used on structs with exactly one field
22
23error: `#[derive(From)]` used on a struct with multiple fields
24 --> $DIR/deriving-from-wrong-target.rs:16:10
25 |
26LL | #[derive(From)]
27 | ^^^^
28LL |
29LL | struct S3(u32, bool);
30 | ^^
31 |
32 = note: `#[derive(From)]` can only be used on structs with exactly one field
33
34error: `#[derive(From)]` used on a struct with multiple fields
35 --> $DIR/deriving-from-wrong-target.rs:20:10
36 |
37LL | #[derive(From)]
38 | ^^^^
39LL |
40LL | struct S4 {
41 | ^^
42 |
43 = note: `#[derive(From)]` can only be used on structs with exactly one field
44
45error: `#[derive(From)]` used on an enum
46 --> $DIR/deriving-from-wrong-target.rs:27:10
47 |
48LL | #[derive(From)]
49 | ^^^^
50LL |
51LL | enum E1 {}
52 | ^^
53 |
54 = note: `#[derive(From)]` can only be used on structs with exactly one field
55
56error[E0277]: the size for values of type `T` cannot be known at compilation time
57 --> $DIR/deriving-from-wrong-target.rs:33:11
58 |
59LL | struct SUnsizedField<T: ?Sized> {
60 | - this type parameter needs to be `Sized`
61LL | last: T,
62 | ^ doesn't have a size known at compile-time
63 |
64 = help: unsized fn params are gated as an unstable feature
65help: consider removing the `?Sized` bound to make the type parameter `Sized`
66 |
67LL - struct SUnsizedField<T: ?Sized> {
68LL + struct SUnsizedField<T> {
69 |
70help: function arguments must have a statically known size, borrowed types always have a known size
71 |
72LL | last: &T,
73 | +
74
75error: aborting due to 6 previous errors
76
77For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/deriving-from.rs created+60
......@@ -0,0 +1,60 @@
1//@ edition: 2021
2//@ run-pass
3
4#![feature(derive_from)]
5
6use core::from::From;
7
8#[derive(From)]
9struct TupleSimple(u32);
10
11#[derive(From)]
12struct TupleNonPathType([u32; 4]);
13
14#[derive(From)]
15struct TupleWithRef<'a, T>(&'a T);
16
17#[derive(From)]
18struct TupleSWithBound<T: std::fmt::Debug>(T);
19
20#[derive(From)]
21struct RawIdentifier {
22 r#use: u32,
23}
24
25#[derive(From)]
26struct Field {
27 foo: bool,
28}
29
30#[derive(From)]
31struct Const<const C: usize> {
32 foo: [u32; C],
33}
34
35fn main() {
36 let a = 42u32;
37 let b: [u32; 4] = [0, 1, 2, 3];
38 let c = true;
39
40 let s1: TupleSimple = a.into();
41 assert_eq!(s1.0, a);
42
43 let s2: TupleNonPathType = b.into();
44 assert_eq!(s2.0, b);
45
46 let s3: TupleWithRef<u32> = (&a).into();
47 assert_eq!(s3.0, &a);
48
49 let s4: TupleSWithBound<u32> = a.into();
50 assert_eq!(s4.0, a);
51
52 let s5: RawIdentifier = a.into();
53 assert_eq!(s5.r#use, a);
54
55 let s6: Field = c.into();
56 assert_eq!(s6.foo, c);
57
58 let s7: Const<4> = b.into();
59 assert_eq!(s7.foo, b);
60}
tests/ui/derives/deriving-hash.rs created+96
......@@ -0,0 +1,96 @@
1//@ run-pass
2#![allow(dead_code)]
3#![allow(unused_imports)]
4#![allow(deprecated)]
5#![allow(non_camel_case_types)]
6#![allow(non_snake_case)]
7#![allow(overflowing_literals)]
8
9use std::hash::{Hash, SipHasher, Hasher};
10use std::mem::size_of;
11
12#[derive(Hash)]
13struct Person {
14 id: usize,
15 name: String,
16 phone: usize,
17}
18
19// test for hygiene name collisions
20#[derive(Hash)] struct __H__H;
21#[derive(Hash)] enum Collision<__H> { __H { __H__H: __H } }
22
23#[derive(Hash)]
24enum E { A=1, B }
25
26fn hash<T: Hash>(t: &T) -> u64 {
27 let mut s = SipHasher::new();
28 t.hash(&mut s);
29 s.finish()
30}
31
32struct FakeHasher<'a>(&'a mut Vec<u8>);
33impl<'a> Hasher for FakeHasher<'a> {
34 fn finish(&self) -> u64 {
35 unimplemented!()
36 }
37
38 fn write(&mut self, bytes: &[u8]) {
39 self.0.extend(bytes);
40 }
41}
42
43fn fake_hash<A: Hash>(v: &mut Vec<u8>, a: A) {
44 a.hash(&mut FakeHasher(v));
45}
46
47struct OnlyOneByteHasher;
48impl Hasher for OnlyOneByteHasher {
49 fn finish(&self) -> u64 {
50 unreachable!()
51 }
52
53 fn write(&mut self, bytes: &[u8]) {
54 assert_eq!(bytes.len(), 1);
55 }
56}
57
58fn main() {
59 let person1 = Person {
60 id: 5,
61 name: "Janet".to_string(),
62 phone: 555_666_7777
63 };
64 let person2 = Person {
65 id: 5,
66 name: "Bob".to_string(),
67 phone: 555_666_7777
68 };
69 assert_eq!(hash(&person1), hash(&person1));
70 assert!(hash(&person1) != hash(&person2));
71
72 // test #21714
73 let mut va = vec![];
74 let mut vb = vec![];
75 fake_hash(&mut va, E::A);
76 fake_hash(&mut vb, E::B);
77 assert!(va != vb);
78
79 // issue #39137: single variant enum hash should not hash discriminant
80 #[derive(Hash)]
81 enum SingleVariantEnum {
82 A(u8),
83 }
84 let mut v = vec![];
85 fake_hash(&mut v, SingleVariantEnum::A(17));
86 assert_eq!(vec![17], v);
87
88 // issue #39137
89 #[repr(u8)]
90 #[derive(Hash)]
91 enum E {
92 A,
93 B,
94 }
95 E::A.hash(&mut OnlyOneByteHasher);
96}
tests/ui/derives/deriving-in-fn.rs created+13
......@@ -0,0 +1,13 @@
1//@ run-pass
2
3#![allow(dead_code)]
4
5pub fn main() {
6 #[derive(Debug)]
7 struct Foo {
8 foo: isize,
9 }
10
11 let f = Foo { foo: 10 };
12 let _ = format!("{:?}", f);
13}
tests/ui/derives/deriving-with-helper.rs created+37
......@@ -0,0 +1,37 @@
1//@ add-minicore
2//@ check-pass
3//@ compile-flags: --crate-type=lib
4
5#![feature(decl_macro)]
6#![feature(lang_items)]
7#![feature(no_core)]
8#![feature(rustc_attrs)]
9
10#![no_core]
11
12extern crate minicore;
13use minicore::*;
14
15#[rustc_builtin_macro]
16macro derive() {}
17
18#[rustc_builtin_macro(Default, attributes(default))]
19macro Default() {}
20
21mod default {
22 pub trait Default {
23 fn default() -> Self;
24 }
25
26 impl Default for u8 {
27 fn default() -> u8 {
28 0
29 }
30 }
31}
32
33#[derive(Default)]
34enum S {
35 #[default] // OK
36 Foo,
37}
tests/ui/derives/deriving-with-repr-packed-3.rs created+36
......@@ -0,0 +1,36 @@
1//@ run-pass
2// check that derive on a packed struct does not call field
3// methods with a misaligned field.
4
5use std::mem;
6
7#[derive(Copy, Clone)]
8struct Aligned(usize);
9
10#[inline(never)]
11fn check_align(ptr: *const Aligned) {
12 assert_eq!(ptr as usize % mem::align_of::<Aligned>(),
13 0);
14}
15
16impl PartialEq for Aligned {
17 fn eq(&self, other: &Self) -> bool {
18 check_align(self);
19 check_align(other);
20 self.0 == other.0
21 }
22}
23
24#[repr(packed)]
25#[derive(Copy, Clone, PartialEq)]
26struct Packed(Aligned, Aligned);
27
28#[derive(PartialEq)]
29#[repr(C)]
30struct Dealigned<T>(u8, T);
31
32fn main() {
33 let d1 = Dealigned(0, Packed(Aligned(1), Aligned(2)));
34 let ck = d1 == d1;
35 assert!(ck);
36}
tests/ui/derives/duplicate-derive-copy-clone-diagnostics.rs deleted-11
......@@ -1,11 +0,0 @@
1// Duplicate implementations of Copy/Clone should not trigger
2// borrow check warnings
3// See #131083
4
5#[derive(Copy, Clone)]
6#[derive(Copy, Clone)]
7//~^ ERROR conflicting implementations of trait `Clone` for type `E`
8//~| ERROR conflicting implementations of trait `Copy` for type `E`
9enum E {}
10
11fn main() {}
tests/ui/derives/duplicate-derive-copy-clone-diagnostics.stderr deleted-19
......@@ -1,19 +0,0 @@
1error[E0119]: conflicting implementations of trait `Copy` for type `E`
2 --> $DIR/duplicate-derive-copy-clone-diagnostics.rs:6:10
3 |
4LL | #[derive(Copy, Clone)]
5 | ---- first implementation here
6LL | #[derive(Copy, Clone)]
7 | ^^^^ conflicting implementation for `E`
8
9error[E0119]: conflicting implementations of trait `Clone` for type `E`
10 --> $DIR/duplicate-derive-copy-clone-diagnostics.rs:6:16
11 |
12LL | #[derive(Copy, Clone)]
13 | ----- first implementation here
14LL | #[derive(Copy, Clone)]
15 | ^^^^^ conflicting implementation for `E`
16
17error: aborting due to 2 previous errors
18
19For more information about this error, try `rustc --explain E0119`.
tests/ui/derives/eq-ord/derive-eq-check-all-variants.rs created+12
......@@ -0,0 +1,12 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/103157.
2
3#[derive(PartialEq, Eq)]
4pub enum Value {
5 Boolean(Option<bool>),
6 Float(Option<f64>), //~ ERROR the trait bound `f64: Eq` is not satisfied
7}
8
9fn main() {
10 let a = Value::Float(Some(f64::NAN));
11 assert!(a == a);
12}
tests/ui/derives/eq-ord/derive-eq-check-all-variants.stderr created+26
......@@ -0,0 +1,26 @@
1error[E0277]: the trait bound `f64: Eq` is not satisfied
2 --> $DIR/derive-eq-check-all-variants.rs:6:11
3 |
4LL | #[derive(PartialEq, Eq)]
5 | -- in this derive macro expansion
6...
7LL | Float(Option<f64>),
8 | ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64`
9 |
10 = help: the following other types implement trait `Eq`:
11 i128
12 i16
13 i32
14 i64
15 i8
16 isize
17 u128
18 u16
19 and 4 others
20 = note: required for `Option<f64>` to implement `Eq`
21note: required by a bound in `std::cmp::AssertParamIsEq`
22 --> $SRC_DIR/core/src/cmp.rs:LL:COL
23
24error: aborting due to 1 previous error
25
26For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/eq-ord/derive-partial-ord-discriminant-64bit.rs created+40
......@@ -0,0 +1,40 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15523
2
3//@ run-pass
4// Issue 15523: derive(PartialOrd) should use the provided
5// discriminant values for the derived ordering.
6//
7// This test is checking corner cases that arise when you have
8// 64-bit values in the variants.
9
10#[derive(PartialEq, PartialOrd)]
11#[repr(u64)]
12enum Eu64 {
13 Pos2 = 2,
14 PosMax = !0,
15 Pos1 = 1,
16}
17
18#[derive(PartialEq, PartialOrd)]
19#[repr(i64)]
20enum Ei64 {
21 Pos2 = 2,
22 Neg1 = -1,
23 NegMin = 1 << 63,
24 PosMax = !(1 << 63),
25 Pos1 = 1,
26}
27
28fn main() {
29 assert!(Eu64::Pos2 > Eu64::Pos1);
30 assert!(Eu64::Pos2 < Eu64::PosMax);
31 assert!(Eu64::Pos1 < Eu64::PosMax);
32
33 assert!(Ei64::Pos2 > Ei64::Pos1);
34 assert!(Ei64::Pos2 > Ei64::Neg1);
35 assert!(Ei64::Pos1 > Ei64::Neg1);
36 assert!(Ei64::Pos2 > Ei64::NegMin);
37 assert!(Ei64::Pos1 > Ei64::NegMin);
38 assert!(Ei64::Pos2 < Ei64::PosMax);
39 assert!(Ei64::Pos1 < Ei64::PosMax);
40}
tests/ui/derives/eq-ord/derive-partial-ord-discriminant.rs created+44
......@@ -0,0 +1,44 @@
1//! Regression test for https://github.com/rust-lang/rust/issues/15523
2
3//@ run-pass
4// Issue 15523: derive(PartialOrd) should use the provided
5// discriminant values for the derived ordering.
6//
7// This is checking the basic functionality.
8
9#[derive(PartialEq, PartialOrd)]
10enum E1 {
11 Pos2 = 2,
12 Neg1 = -1,
13 Pos1 = 1,
14}
15
16#[derive(PartialEq, PartialOrd)]
17#[repr(u8)]
18enum E2 {
19 Pos2 = 2,
20 PosMax = !0 as u8,
21 Pos1 = 1,
22}
23
24#[derive(PartialEq, PartialOrd)]
25#[repr(i8)]
26enum E3 {
27 Pos2 = 2,
28 Neg1 = -1_i8,
29 Pos1 = 1,
30}
31
32fn main() {
33 assert!(E1::Pos2 > E1::Pos1);
34 assert!(E1::Pos1 > E1::Neg1);
35 assert!(E1::Pos2 > E1::Neg1);
36
37 assert!(E2::Pos2 > E2::Pos1);
38 assert!(E2::Pos1 < E2::PosMax);
39 assert!(E2::Pos2 < E2::PosMax);
40
41 assert!(E3::Pos2 > E3::Pos1);
42 assert!(E3::Pos1 > E3::Neg1);
43 assert!(E3::Pos2 > E3::Neg1);
44}
tests/ui/derives/eq-ord/derive-partial-ord.rs created+60
......@@ -0,0 +1,60 @@
1// Checks that in a derived implementation of PartialOrd the lt, le, ge, gt methods are consistent
2// with partial_cmp. Also verifies that implementation is consistent with that for tuples.
3//
4//@ run-pass
5
6#[derive(PartialEq, PartialOrd)]
7struct P(f64, f64);
8
9fn main() {
10 let values: &[f64] = &[1.0, 2.0, f64::NAN];
11 for a in values {
12 for b in values {
13 for c in values {
14 for d in values {
15 // Check impl for a tuple.
16 check(&(*a, *b), &(*c, *d));
17
18 // Check derived impl.
19 check(&P(*a, *b), &P(*c, *d));
20
21 // Check that impls agree with each other.
22 assert_eq!(
23 PartialOrd::partial_cmp(&(*a, *b), &(*c, *d)),
24 PartialOrd::partial_cmp(&P(*a, *b), &P(*c, *d)),
25 );
26 }
27 }
28 }
29 }
30}
31
32fn check<T: PartialOrd>(a: &T, b: &T) {
33 use std::cmp::Ordering::*;
34 match PartialOrd::partial_cmp(a, b) {
35 None => {
36 assert!(!(a < b));
37 assert!(!(a <= b));
38 assert!(!(a > b));
39 assert!(!(a >= b));
40 }
41 Some(Equal) => {
42 assert!(!(a < b));
43 assert!(a <= b);
44 assert!(!(a > b));
45 assert!(a >= b);
46 }
47 Some(Less) => {
48 assert!(a < b);
49 assert!(a <= b);
50 assert!(!(a > b));
51 assert!(!(a >= b));
52 }
53 Some(Greater) => {
54 assert!(!(a < b));
55 assert!(!(a <= b));
56 assert!(a > b);
57 assert!(a >= b);
58 }
59 }
60}
tests/ui/derives/eq-ord/derive-partialord-correctness.rs created+9
......@@ -0,0 +1,9 @@
1//@ run-pass
2// Original issue: #49650
3
4#[derive(PartialOrd, PartialEq)]
5struct FloatWrapper(f64);
6
7fn main() {
8 assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(0.0)))
9}
tests/ui/derives/eq-ord/derives-span-Eq.rs created+31
......@@ -0,0 +1,31 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Eq)] line.
3
4#[derive(PartialEq)]
5struct Error;
6
7#[derive(Eq, PartialEq)]
8enum EnumStructVariant {
9 A {
10 x: Error, //~ ERROR
11 },
12}
13
14#[derive(Eq, PartialEq)]
15enum EnumTupleVariant {
16 A(
17 Error, //~ ERROR
18 ),
19}
20
21#[derive(Eq, PartialEq)]
22struct Struct {
23 x: Error, //~ ERROR
24}
25
26#[derive(Eq, PartialEq)]
27struct TupleStruct(
28 Error, //~ ERROR
29);
30
31fn main() {}
tests/ui/derives/eq-ord/derives-span-Eq.stderr created+71
......@@ -0,0 +1,71 @@
1error[E0277]: the trait bound `Error: Eq` is not satisfied
2 --> $DIR/derives-span-Eq.rs:10:9
3 |
4LL | #[derive(Eq, PartialEq)]
5 | -- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Eq` is not implemented for `Error`
9 |
10note: required by a bound in `std::cmp::AssertParamIsEq`
11 --> $SRC_DIR/core/src/cmp.rs:LL:COL
12help: consider annotating `Error` with `#[derive(Eq)]`
13 |
14LL + #[derive(Eq)]
15LL | struct Error;
16 |
17
18error[E0277]: the trait bound `Error: Eq` is not satisfied
19 --> $DIR/derives-span-Eq.rs:17:9
20 |
21LL | #[derive(Eq, PartialEq)]
22 | -- in this derive macro expansion
23...
24LL | Error,
25 | ^^^^^ the trait `Eq` is not implemented for `Error`
26 |
27note: required by a bound in `std::cmp::AssertParamIsEq`
28 --> $SRC_DIR/core/src/cmp.rs:LL:COL
29help: consider annotating `Error` with `#[derive(Eq)]`
30 |
31LL + #[derive(Eq)]
32LL | struct Error;
33 |
34
35error[E0277]: the trait bound `Error: Eq` is not satisfied
36 --> $DIR/derives-span-Eq.rs:23:5
37 |
38LL | #[derive(Eq, PartialEq)]
39 | -- in this derive macro expansion
40LL | struct Struct {
41LL | x: Error,
42 | ^^^^^^^^ the trait `Eq` is not implemented for `Error`
43 |
44note: required by a bound in `std::cmp::AssertParamIsEq`
45 --> $SRC_DIR/core/src/cmp.rs:LL:COL
46help: consider annotating `Error` with `#[derive(Eq)]`
47 |
48LL + #[derive(Eq)]
49LL | struct Error;
50 |
51
52error[E0277]: the trait bound `Error: Eq` is not satisfied
53 --> $DIR/derives-span-Eq.rs:28:5
54 |
55LL | #[derive(Eq, PartialEq)]
56 | -- in this derive macro expansion
57LL | struct TupleStruct(
58LL | Error,
59 | ^^^^^ the trait `Eq` is not implemented for `Error`
60 |
61note: required by a bound in `std::cmp::AssertParamIsEq`
62 --> $SRC_DIR/core/src/cmp.rs:LL:COL
63help: consider annotating `Error` with `#[derive(Eq)]`
64 |
65LL + #[derive(Eq)]
66LL | struct Error;
67 |
68
69error: aborting due to 4 previous errors
70
71For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/eq-ord/derives-span-Ord.rs created+31
......@@ -0,0 +1,31 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(Ord)] line.
3
4#[derive(Eq, PartialOrd, PartialEq)]
5struct Error;
6
7#[derive(Ord, Eq, PartialOrd, PartialEq)]
8enum EnumStructVariant {
9 A {
10 x: Error, //~ ERROR
11 },
12}
13
14#[derive(Ord, Eq, PartialOrd, PartialEq)]
15enum EnumTupleVariant {
16 A(
17 Error, //~ ERROR
18 ),
19}
20
21#[derive(Ord, Eq, PartialOrd, PartialEq)]
22struct Struct {
23 x: Error, //~ ERROR
24}
25
26#[derive(Ord, Eq, PartialOrd, PartialEq)]
27struct TupleStruct(
28 Error, //~ ERROR
29);
30
31fn main() {}
tests/ui/derives/eq-ord/derives-span-Ord.stderr created+63
......@@ -0,0 +1,63 @@
1error[E0277]: the trait bound `Error: Ord` is not satisfied
2 --> $DIR/derives-span-Ord.rs:10:9
3 |
4LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
5 | --- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ the trait `Ord` is not implemented for `Error`
9 |
10help: consider annotating `Error` with `#[derive(Ord)]`
11 |
12LL + #[derive(Ord)]
13LL | struct Error;
14 |
15
16error[E0277]: the trait bound `Error: Ord` is not satisfied
17 --> $DIR/derives-span-Ord.rs:17:9
18 |
19LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
20 | --- in this derive macro expansion
21...
22LL | Error,
23 | ^^^^^ the trait `Ord` is not implemented for `Error`
24 |
25help: consider annotating `Error` with `#[derive(Ord)]`
26 |
27LL + #[derive(Ord)]
28LL | struct Error;
29 |
30
31error[E0277]: the trait bound `Error: Ord` is not satisfied
32 --> $DIR/derives-span-Ord.rs:23:5
33 |
34LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
35 | --- in this derive macro expansion
36LL | struct Struct {
37LL | x: Error,
38 | ^^^^^^^^ the trait `Ord` is not implemented for `Error`
39 |
40help: consider annotating `Error` with `#[derive(Ord)]`
41 |
42LL + #[derive(Ord)]
43LL | struct Error;
44 |
45
46error[E0277]: the trait bound `Error: Ord` is not satisfied
47 --> $DIR/derives-span-Ord.rs:28:5
48 |
49LL | #[derive(Ord, Eq, PartialOrd, PartialEq)]
50 | --- in this derive macro expansion
51LL | struct TupleStruct(
52LL | Error,
53 | ^^^^^ the trait `Ord` is not implemented for `Error`
54 |
55help: consider annotating `Error` with `#[derive(Ord)]`
56 |
57LL + #[derive(Ord)]
58LL | struct Error;
59 |
60
61error: aborting due to 4 previous errors
62
63For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/eq-ord/derives-span-PartialEq.rs created+29
......@@ -0,0 +1,29 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(PartialEq)] line.
3
4struct Error;
5
6#[derive(PartialEq)]
7enum EnumStructVariant {
8 A {
9 x: Error, //~ ERROR
10 },
11}
12
13#[derive(PartialEq)]
14enum EnumTupleVariant {
15 A(
16 Error, //~ ERROR
17 ),
18}
19#[derive(PartialEq)]
20struct Struct {
21 x: Error, //~ ERROR
22}
23
24#[derive(PartialEq)]
25struct TupleStruct(
26 Error, //~ ERROR
27);
28
29fn main() {}
tests/ui/derives/eq-ord/derives-span-PartialEq.stderr created+83
......@@ -0,0 +1,83 @@
1error[E0369]: binary operation `==` cannot be applied to type `&Error`
2 --> $DIR/derives-span-PartialEq.rs:9:9
3 |
4LL | #[derive(PartialEq)]
5 | --------- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^
9 |
10note: an implementation of `PartialEq` might be missing for `Error`
11 --> $DIR/derives-span-PartialEq.rs:4:1
12 |
13LL | struct Error;
14 | ^^^^^^^^^^^^ must implement `PartialEq`
15help: consider annotating `Error` with `#[derive(PartialEq)]`
16 |
17LL + #[derive(PartialEq)]
18LL | struct Error;
19 |
20
21error[E0369]: binary operation `==` cannot be applied to type `&Error`
22 --> $DIR/derives-span-PartialEq.rs:16:9
23 |
24LL | #[derive(PartialEq)]
25 | --------- in this derive macro expansion
26...
27LL | Error,
28 | ^^^^^
29 |
30note: an implementation of `PartialEq` might be missing for `Error`
31 --> $DIR/derives-span-PartialEq.rs:4:1
32 |
33LL | struct Error;
34 | ^^^^^^^^^^^^ must implement `PartialEq`
35help: consider annotating `Error` with `#[derive(PartialEq)]`
36 |
37LL + #[derive(PartialEq)]
38LL | struct Error;
39 |
40
41error[E0369]: binary operation `==` cannot be applied to type `Error`
42 --> $DIR/derives-span-PartialEq.rs:21:5
43 |
44LL | #[derive(PartialEq)]
45 | --------- in this derive macro expansion
46LL | struct Struct {
47LL | x: Error,
48 | ^^^^^^^^
49 |
50note: an implementation of `PartialEq` might be missing for `Error`
51 --> $DIR/derives-span-PartialEq.rs:4:1
52 |
53LL | struct Error;
54 | ^^^^^^^^^^^^ must implement `PartialEq`
55help: consider annotating `Error` with `#[derive(PartialEq)]`
56 |
57LL + #[derive(PartialEq)]
58LL | struct Error;
59 |
60
61error[E0369]: binary operation `==` cannot be applied to type `Error`
62 --> $DIR/derives-span-PartialEq.rs:26:5
63 |
64LL | #[derive(PartialEq)]
65 | --------- in this derive macro expansion
66LL | struct TupleStruct(
67LL | Error,
68 | ^^^^^
69 |
70note: an implementation of `PartialEq` might be missing for `Error`
71 --> $DIR/derives-span-PartialEq.rs:4:1
72 |
73LL | struct Error;
74 | ^^^^^^^^^^^^ must implement `PartialEq`
75help: consider annotating `Error` with `#[derive(PartialEq)]`
76 |
77LL + #[derive(PartialEq)]
78LL | struct Error;
79 |
80
81error: aborting due to 4 previous errors
82
83For more information about this error, try `rustc --explain E0369`.
tests/ui/derives/eq-ord/derives-span-PartialOrd.rs created+31
......@@ -0,0 +1,31 @@
1//! Check that all the derives have spans that point to the fields,
2//! rather than the #[derive(PartialOrd)] line.
3
4#[derive(PartialEq)]
5struct Error;
6
7#[derive(PartialOrd, PartialEq)]
8enum EnumStructVariant {
9 A {
10 x: Error, //~ ERROR
11 },
12}
13
14#[derive(PartialOrd, PartialEq)]
15enum EnumTupleVariant {
16 A(
17 Error, //~ ERROR
18 ),
19}
20
21#[derive(PartialOrd, PartialEq)]
22struct Struct {
23 x: Error, //~ ERROR
24}
25
26#[derive(PartialOrd, PartialEq)]
27struct TupleStruct(
28 Error, //~ ERROR
29);
30
31fn main() {}
tests/ui/derives/eq-ord/derives-span-PartialOrd.stderr created+67
......@@ -0,0 +1,67 @@
1error[E0277]: can't compare `Error` with `Error`
2 --> $DIR/derives-span-PartialOrd.rs:10:9
3 |
4LL | #[derive(PartialOrd, PartialEq)]
5 | ---------- in this derive macro expansion
6...
7LL | x: Error,
8 | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
9 |
10 = help: the trait `PartialOrd` is not implemented for `Error`
11help: consider annotating `Error` with `#[derive(PartialOrd)]`
12 |
13LL + #[derive(PartialOrd)]
14LL | struct Error;
15 |
16
17error[E0277]: can't compare `Error` with `Error`
18 --> $DIR/derives-span-PartialOrd.rs:17:9
19 |
20LL | #[derive(PartialOrd, PartialEq)]
21 | ---------- in this derive macro expansion
22...
23LL | Error,
24 | ^^^^^ no implementation for `Error < Error` and `Error > Error`
25 |
26 = help: the trait `PartialOrd` is not implemented for `Error`
27help: consider annotating `Error` with `#[derive(PartialOrd)]`
28 |
29LL + #[derive(PartialOrd)]
30LL | struct Error;
31 |
32
33error[E0277]: can't compare `Error` with `Error`
34 --> $DIR/derives-span-PartialOrd.rs:23:5
35 |
36LL | #[derive(PartialOrd, PartialEq)]
37 | ---------- in this derive macro expansion
38LL | struct Struct {
39LL | x: Error,
40 | ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
41 |
42 = help: the trait `PartialOrd` is not implemented for `Error`
43help: consider annotating `Error` with `#[derive(PartialOrd)]`
44 |
45LL + #[derive(PartialOrd)]
46LL | struct Error;
47 |
48
49error[E0277]: can't compare `Error` with `Error`
50 --> $DIR/derives-span-PartialOrd.rs:28:5
51 |
52LL | #[derive(PartialOrd, PartialEq)]
53 | ---------- in this derive macro expansion
54LL | struct TupleStruct(
55LL | Error,
56 | ^^^^^ no implementation for `Error < Error` and `Error > Error`
57 |
58 = help: the trait `PartialOrd` is not implemented for `Error`
59help: consider annotating `Error` with `#[derive(PartialOrd)]`
60 |
61LL + #[derive(PartialOrd)]
62LL | struct Error;
63 |
64
65error: aborting due to 4 previous errors
66
67For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/eq-ord/deriving-cmp-generic-enum.rs created+44
......@@ -0,0 +1,44 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3enum E<T> {
4 E0,
5 E1(T),
6 E2(T,T)
7}
8
9pub fn main() {
10 let e0 = E::E0;
11 let e11 = E::E1(1);
12 let e12 = E::E1(2);
13 let e21 = E::E2(1, 1);
14 let e22 = E::E2(1, 2);
15
16 // in order for both PartialOrd and Ord
17 let es = [e0, e11, e12, e21, e22];
18
19 for (i, e1) in es.iter().enumerate() {
20 for (j, e2) in es.iter().enumerate() {
21 let ord = i.cmp(&j);
22
23 let eq = i == j;
24 let lt = i < j;
25 let le = i <= j;
26 let gt = i > j;
27 let ge = i >= j;
28
29 // PartialEq
30 assert_eq!(*e1 == *e2, eq);
31 assert_eq!(*e1 != *e2, !eq);
32
33 // PartialOrd
34 assert_eq!(*e1 < *e2, lt);
35 assert_eq!(*e1 > *e2, gt);
36
37 assert_eq!(*e1 <= *e2, le);
38 assert_eq!(*e1 >= *e2, ge);
39
40 // Ord
41 assert_eq!(e1.cmp(e2), ord);
42 }
43 }
44}
tests/ui/derives/eq-ord/deriving-cmp-generic-struct-enum.rs created+48
......@@ -0,0 +1,48 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3enum ES<T> {
4 ES1 { x: T },
5 ES2 { x: T, y: T }
6}
7
8
9pub fn main() {
10 let (es11, es12, es21, es22) = (ES::ES1 {
11 x: 1
12 }, ES::ES1 {
13 x: 2
14 }, ES::ES2 {
15 x: 1,
16 y: 1
17 }, ES::ES2 {
18 x: 1,
19 y: 2
20 });
21
22 // in order for both PartialOrd and Ord
23 let ess = [es11, es12, es21, es22];
24
25 for (i, es1) in ess.iter().enumerate() {
26 for (j, es2) in ess.iter().enumerate() {
27 let ord = i.cmp(&j);
28
29 let eq = i == j;
30 let (lt, le) = (i < j, i <= j);
31 let (gt, ge) = (i > j, i >= j);
32
33 // PartialEq
34 assert_eq!(*es1 == *es2, eq);
35 assert_eq!(*es1 != *es2, !eq);
36
37 // PartialOrd
38 assert_eq!(*es1 < *es2, lt);
39 assert_eq!(*es1 > *es2, gt);
40
41 assert_eq!(*es1 <= *es2, le);
42 assert_eq!(*es1 >= *es2, ge);
43
44 // Ord
45 assert_eq!(es1.cmp(es2), ord);
46 }
47 }
48}
tests/ui/derives/eq-ord/deriving-cmp-generic-struct.rs created+40
......@@ -0,0 +1,40 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3struct S<T> {
4 x: T,
5 y: T
6}
7
8pub fn main() {
9 let s1 = S {x: 1, y: 1};
10 let s2 = S {x: 1, y: 2};
11
12 // in order for both PartialOrd and Ord
13 let ss = [s1, s2];
14
15 for (i, s1) in ss.iter().enumerate() {
16 for (j, s2) in ss.iter().enumerate() {
17 let ord = i.cmp(&j);
18
19 let eq = i == j;
20 let lt = i < j;
21 let le = i <= j;
22 let gt = i > j;
23 let ge = i >= j;
24
25 // PartialEq
26 assert_eq!(*s1 == *s2, eq);
27 assert_eq!(*s1 != *s2, !eq);
28
29 // PartialOrd
30 assert_eq!(*s1 < *s2, lt);
31 assert_eq!(*s1 > *s2, gt);
32
33 assert_eq!(*s1 <= *s2, le);
34 assert_eq!(*s1 >= *s2, ge);
35
36 // Ord
37 assert_eq!(s1.cmp(s2), ord);
38 }
39 }
40}
tests/ui/derives/eq-ord/deriving-cmp-generic-tuple-struct.rs created+38
......@@ -0,0 +1,38 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3struct TS<T>(T,T);
4
5
6pub fn main() {
7 let ts1 = TS(1, 1);
8 let ts2 = TS(1, 2);
9
10 // in order for both PartialOrd and Ord
11 let tss = [ts1, ts2];
12
13 for (i, ts1) in tss.iter().enumerate() {
14 for (j, ts2) in tss.iter().enumerate() {
15 let ord = i.cmp(&j);
16
17 let eq = i == j;
18 let lt = i < j;
19 let le = i <= j;
20 let gt = i > j;
21 let ge = i >= j;
22
23 // PartialEq
24 assert_eq!(*ts1 == *ts2, eq);
25 assert_eq!(*ts1 != *ts2, !eq);
26
27 // PartialOrd
28 assert_eq!(*ts1 < *ts2, lt);
29 assert_eq!(*ts1 > *ts2, gt);
30
31 assert_eq!(*ts1 <= *ts2, le);
32 assert_eq!(*ts1 >= *ts2, ge);
33
34 // Ord
35 assert_eq!(ts1.cmp(ts2), ord);
36 }
37 }
38}
tests/ui/derives/eq-ord/deriving-cmp-shortcircuit.rs created+37
......@@ -0,0 +1,37 @@
1//@ run-pass
2// check that the derived impls for the comparison traits shortcircuit
3// where possible, by having a type that panics when compared as the
4// second element, so this passes iff the instances shortcircuit.
5
6
7use std::cmp::Ordering;
8
9pub struct FailCmp;
10impl PartialEq for FailCmp {
11 fn eq(&self, _: &FailCmp) -> bool { panic!("eq") }
12}
13
14impl PartialOrd for FailCmp {
15 fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { panic!("partial_cmp") }
16}
17
18impl Eq for FailCmp {}
19
20impl Ord for FailCmp {
21 fn cmp(&self, _: &FailCmp) -> Ordering { panic!("cmp") }
22}
23
24#[derive(PartialEq,PartialOrd,Eq,Ord)]
25struct ShortCircuit {
26 x: isize,
27 y: FailCmp
28}
29
30pub fn main() {
31 let a = ShortCircuit { x: 1, y: FailCmp };
32 let b = ShortCircuit { x: 2, y: FailCmp };
33
34 assert!(a != b);
35 assert!(a < b);
36 assert_eq!(a.cmp(&b), ::std::cmp::Ordering::Less);
37}
tests/ui/derives/eq-ord/deriving-eq-ord-boxed-slice.rs created+15
......@@ -0,0 +1,15 @@
1//@ run-pass
2#[derive(PartialEq, PartialOrd, Eq, Ord, Debug)]
3struct Foo(Box<[u8]>);
4
5pub fn main() {
6 let a = Foo(Box::new([0, 1, 2]));
7 let b = Foo(Box::new([0, 1, 2]));
8 assert_eq!(a, b);
9 println!("{}", a != b);
10 println!("{}", a < b);
11 println!("{}", a <= b);
12 println!("{}", a == b);
13 println!("{}", a > b);
14 println!("{}", a >= b);
15}
tests/ui/derives/eq-ord/deriving-self-lifetime-totalord-totaleq.rs created+16
......@@ -0,0 +1,16 @@
1//@ run-pass
2use std::cmp::Ordering::{Less,Equal,Greater};
3
4#[derive(PartialEq, Eq, PartialOrd, Ord)]
5struct A<'a> {
6 x: &'a isize
7}
8pub fn main() {
9 let (a, b) = (A { x: &1 }, A { x: &2 });
10
11 assert_eq!(a.cmp(&a), Equal);
12 assert_eq!(b.cmp(&b), Equal);
13
14 assert_eq!(a.cmp(&b), Less);
15 assert_eq!(b.cmp(&a), Greater);
16}
tests/ui/derives/eq-ord/do-not-suggest-calling-fn-in-derive-macro.rs created+8
......@@ -0,0 +1,8 @@
1use std::rc::Rc;
2
3#[derive(PartialEq)] //~ NOTE in this expansion
4pub struct Function {
5 callback: Rc<dyn Fn()>, //~ ERROR binary operation `==` cannot be applied to type `Rc<dyn Fn()>`
6}
7
8fn main() {}
tests/ui/derives/eq-ord/do-not-suggest-calling-fn-in-derive-macro.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0369]: binary operation `==` cannot be applied to type `Rc<dyn Fn()>`
2 --> $DIR/do-not-suggest-calling-fn-in-derive-macro.rs:5:5
3 |
4LL | #[derive(PartialEq)]
5 | --------- in this derive macro expansion
6LL | pub struct Function {
7LL | callback: Rc<dyn Fn()>,
8 | ^^^^^^^^^^^^^^^^^^^^^^
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0369`.
tests/ui/derives/eq-ord/internal_eq_trait_method_impls.rs created+48
......@@ -0,0 +1,48 @@
1#![deny(deprecated, internal_eq_trait_method_impls)]
2pub struct Bad;
3
4impl PartialEq for Bad {
5 fn eq(&self, _: &Self) -> bool {
6 true
7 }
8}
9
10impl Eq for Bad {
11 fn assert_receiver_is_total_eq(&self) {}
12 //~^ ERROR: `Eq::assert_receiver_is_total_eq` should never be implemented by hand [internal_eq_trait_method_impls]
13 //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
14}
15
16#[derive(PartialEq, Eq)]
17pub struct Good;
18
19#[derive(PartialEq)]
20pub struct Good2;
21
22impl Eq for Good2 {}
23
24pub struct Foo;
25
26pub trait SameName {
27 fn assert_receiver_is_total_eq(&self) {}
28}
29
30impl SameName for Foo {
31 fn assert_receiver_is_total_eq(&self) {}
32}
33
34pub fn main() {
35 Foo.assert_receiver_is_total_eq();
36 Good2.assert_receiver_is_total_eq();
37 //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated]
38 Good.assert_receiver_is_total_eq();
39 //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated]
40 Bad.assert_receiver_is_total_eq();
41 //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated]
42}
43
44#[forbid(internal_eq_trait_method_impls)]
45mod forbid {
46 #[derive(PartialEq, Eq)]
47 pub struct Foo;
48}
tests/ui/derives/eq-ord/internal_eq_trait_method_impls.stderr created+41
......@@ -0,0 +1,41 @@
1error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]`
2 --> $DIR/internal_eq_trait_method_impls.rs:36:11
3 |
4LL | Good2.assert_receiver_is_total_eq();
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: the lint level is defined here
8 --> $DIR/internal_eq_trait_method_impls.rs:1:9
9 |
10LL | #![deny(deprecated, internal_eq_trait_method_impls)]
11 | ^^^^^^^^^^
12
13error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]`
14 --> $DIR/internal_eq_trait_method_impls.rs:38:10
15 |
16LL | Good.assert_receiver_is_total_eq();
17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
18
19error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]`
20 --> $DIR/internal_eq_trait_method_impls.rs:40:9
21 |
22LL | Bad.assert_receiver_is_total_eq();
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
24
25error: `Eq::assert_receiver_is_total_eq` should never be implemented by hand
26 --> $DIR/internal_eq_trait_method_impls.rs:11:5
27 |
28LL | fn assert_receiver_is_total_eq(&self) {}
29 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30 |
31 = note: this method was used to add checks to the `Eq` derive macro
32 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
33 = note: for more information, see issue #152336 <https://github.com/rust-lang/rust/issues/152336>
34note: the lint level is defined here
35 --> $DIR/internal_eq_trait_method_impls.rs:1:21
36 |
37LL | #![deny(deprecated, internal_eq_trait_method_impls)]
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
40error: aborting due to 4 previous errors
41
tests/ui/derives/eq-ord/invalid-derive-comparison-34229.rs created+7
......@@ -0,0 +1,7 @@
1#[derive(PartialEq)] struct Comparable;
2#[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
3//~^ ERROR can't compare `Comparable`
4
5fn main() {}
6
7// https://github.com/rust-lang/rust/issues/34229
tests/ui/derives/eq-ord/invalid-derive-comparison-34229.stderr created+17
......@@ -0,0 +1,17 @@
1error[E0277]: can't compare `Comparable` with `Comparable`
2 --> $DIR/invalid-derive-comparison-34229.rs:2:46
3 |
4LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
5 | ---------- ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
6 | |
7 | in this derive macro expansion
8 |
9 = help: the trait `PartialOrd` is not implemented for `Comparable`
10help: consider annotating `Comparable` with `#[derive(PartialOrd)]`
11 |
12LL | #[derive(PartialEq)] #[derive(PartialOrd)]
13 | +++++++++++++++++++++
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/invalid-derive-comparison-34229.rs deleted-7
......@@ -1,7 +0,0 @@
1#[derive(PartialEq)] struct Comparable;
2#[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
3//~^ ERROR can't compare `Comparable`
4
5fn main() {}
6
7// https://github.com/rust-lang/rust/issues/34229
tests/ui/derives/invalid-derive-comparison-34229.stderr deleted-17
......@@ -1,17 +0,0 @@
1error[E0277]: can't compare `Comparable` with `Comparable`
2 --> $DIR/invalid-derive-comparison-34229.rs:2:46
3 |
4LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
5 | ---------- ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
6 | |
7 | in this derive macro expansion
8 |
9 = help: the trait `PartialOrd` is not implemented for `Comparable`
10help: consider annotating `Comparable` with `#[derive(PartialOrd)]`
11 |
12LL | #[derive(PartialEq)] #[derive(PartialOrd)]
13 | +++++++++++++++++++++
14
15error: aborting due to 1 previous error
16
17For more information about this error, try `rustc --explain E0277`.
tests/ui/derives/nonsense-input-to-debug.rs deleted-12
......@@ -1,12 +0,0 @@
1// Issue: #32950
2// Ensure that using macros rather than a type doesn't break `derive`.
3
4#[derive(Debug)]
5struct Nonsense<T> {
6 //~^ ERROR type parameter `T` is never used
7 should_be_vec_t: vec![T],
8 //~^ ERROR `derive` cannot be used on items with type macros
9 //~| ERROR expected type, found `expr` metavariable
10}
11
12fn main() {}
tests/ui/derives/nonsense-input-to-debug.stderr deleted-28
......@@ -1,28 +0,0 @@
1error: `derive` cannot be used on items with type macros
2 --> $DIR/nonsense-input-to-debug.rs:7:22
3 |
4LL | should_be_vec_t: vec![T],
5 | ^^^^^^^
6
7error: expected type, found `expr` metavariable
8 --> $DIR/nonsense-input-to-debug.rs:7:22
9 |
10LL | should_be_vec_t: vec![T],
11 | ^^^^^^^
12 | |
13 | expected type
14 | in this macro invocation
15 | this macro call doesn't expand to a type
16
17error[E0392]: type parameter `T` is never used
18 --> $DIR/nonsense-input-to-debug.rs:5:17
19 |
20LL | struct Nonsense<T> {
21 | ^ unused type parameter
22 |
23 = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
24 = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
25
26error: aborting due to 3 previous errors
27
28For more information about this error, try `rustc --explain E0392`.
tests/ui/deriving/auxiliary/another-proc-macro.rs deleted-41
......@@ -1,41 +0,0 @@
1#![feature(proc_macro_quote)]
2
3extern crate proc_macro;
4
5use proc_macro::{TokenStream, quote};
6
7#[proc_macro_derive(AnotherMacro, attributes(pointee))]
8pub fn derive(_input: TokenStream) -> TokenStream {
9 quote! {
10 const _: () = {
11 const ANOTHER_MACRO_DERIVED: () = ();
12 };
13 }
14 .into()
15}
16
17#[proc_macro_attribute]
18pub fn pointee(
19 _attr: proc_macro::TokenStream,
20 _item: proc_macro::TokenStream,
21) -> proc_macro::TokenStream {
22 quote! {
23 const _: () = {
24 const POINTEE_MACRO_ATTR_DERIVED: () = ();
25 };
26 }
27 .into()
28}
29
30#[proc_macro_attribute]
31pub fn default(
32 _attr: proc_macro::TokenStream,
33 _item: proc_macro::TokenStream,
34) -> proc_macro::TokenStream {
35 quote! {
36 const _: () = {
37 const DEFAULT_MACRO_ATTR_DERIVED: () = ();
38 };
39 }
40 .into()
41}
tests/ui/deriving/auxiliary/derive-no-std.rs deleted-29
......@@ -1,29 +0,0 @@
1//@ no-prefer-dynamic
2
3#![crate_type = "rlib"]
4#![no_std]
5
6// Issue #16803
7
8#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
9 Debug, Default, Copy)]
10pub struct Foo {
11 pub x: u32,
12}
13
14#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
15 Debug, Copy)]
16pub enum Bar {
17 Qux,
18 Quux(u32),
19}
20
21#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
22 Debug, Copy)]
23pub enum Void {}
24#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
25 Debug, Copy)]
26pub struct Empty;
27#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
28 Debug, Copy)]
29pub struct AlsoEmpty {}
tests/ui/deriving/auxiliary/malicious-macro.rs deleted-31
......@@ -1,31 +0,0 @@
1//@ edition: 2024
2
3extern crate proc_macro;
4
5use proc_macro::{Delimiter, TokenStream, TokenTree};
6
7#[proc_macro_attribute]
8pub fn norepr(_: TokenStream, input: TokenStream) -> TokenStream {
9 let mut tokens = vec![];
10 let mut tts = input.into_iter().fuse().peekable();
11 loop {
12 let Some(token) = tts.next() else { break };
13 if let TokenTree::Punct(punct) = &token
14 && punct.as_char() == '#'
15 {
16 if let Some(TokenTree::Group(group)) = tts.peek()
17 && let Delimiter::Bracket = group.delimiter()
18 && let Some(TokenTree::Ident(ident)) = group.stream().into_iter().next()
19 && ident.to_string() == "repr"
20 {
21 let _ = tts.next();
22 // skip '#' and '[repr(..)]
23 } else {
24 tokens.push(token);
25 }
26 } else {
27 tokens.push(token);
28 }
29 }
30 tokens.into_iter().collect()
31}
tests/ui/deriving/built-in-proc-macro-scope.rs deleted-26
......@@ -1,26 +0,0 @@
1//@ check-pass
2//@ proc-macro: another-proc-macro.rs
3//@ compile-flags: -Zunpretty=expanded
4//@ edition:2015
5
6#![feature(derive_coerce_pointee)]
7
8#[macro_use]
9extern crate another_proc_macro;
10
11use another_proc_macro::{AnotherMacro, pointee};
12
13#[derive(core::marker::CoercePointee)]
14#[repr(transparent)]
15pub struct Ptr<'a, #[pointee] T: ?Sized> {
16 data: &'a mut T,
17}
18
19#[pointee]
20fn f() {}
21
22#[derive(AnotherMacro)]
23#[pointee]
24struct MyStruct;
25
26fn main() {}
tests/ui/deriving/built-in-proc-macro-scope.stdout deleted-45
......@@ -1,45 +0,0 @@
1#![feature(prelude_import)]
2#![no_std]
3//@ check-pass
4//@ proc-macro: another-proc-macro.rs
5//@ compile-flags: -Zunpretty=expanded
6//@ edition:2015
7
8#![feature(derive_coerce_pointee)]
9extern crate std;
10#[prelude_import]
11use ::std::prelude::rust_2015::*;
12
13#[macro_use]
14extern crate another_proc_macro;
15
16use another_proc_macro::{AnotherMacro, pointee};
17
18#[repr(transparent)]
19pub struct Ptr<'a, #[pointee] T: ?Sized> {
20 data: &'a mut T,
21}
22#[automatically_derived]
23impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for Ptr<'a, T> { }
24#[automatically_derived]
25impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
26 ::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
27}
28#[automatically_derived]
29impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
30 ::core::ops::CoerceUnsized<Ptr<'a, __S>> for Ptr<'a, T> {
31}
32
33
34
35const _: () =
36 {
37 const POINTEE_MACRO_ATTR_DERIVED: () = ();
38 };
39#[pointee]
40struct MyStruct;
41const _: () =
42 {
43 const ANOTHER_MACRO_DERIVED: () = ();
44 };
45fn main() {}
tests/ui/deriving/coerce-pointee-bounds-issue-127647.rs deleted-78
......@@ -1,78 +0,0 @@
1//@ check-pass
2
3#![feature(derive_coerce_pointee)]
4
5#[derive(core::marker::CoercePointee)]
6#[repr(transparent)]
7pub struct Ptr<'a, #[pointee] T: OnDrop + ?Sized, X> {
8 data: &'a mut T,
9 x: core::marker::PhantomData<X>,
10}
11
12pub trait OnDrop {
13 fn on_drop(&mut self);
14}
15
16#[derive(core::marker::CoercePointee)]
17#[repr(transparent)]
18pub struct Ptr2<'a, #[pointee] T: ?Sized, X>
19where
20 T: OnDrop,
21{
22 data: &'a mut T,
23 x: core::marker::PhantomData<X>,
24}
25
26pub trait MyTrait<T: ?Sized> {}
27
28#[derive(core::marker::CoercePointee)]
29#[repr(transparent)]
30pub struct Ptr3<'a, #[pointee] T: ?Sized, X>
31where
32 T: MyTrait<T>,
33{
34 data: &'a mut T,
35 x: core::marker::PhantomData<X>,
36}
37
38#[derive(core::marker::CoercePointee)]
39#[repr(transparent)]
40pub struct Ptr4<'a, #[pointee] T: MyTrait<T> + ?Sized, X> {
41 data: &'a mut T,
42 x: core::marker::PhantomData<X>,
43}
44
45#[derive(core::marker::CoercePointee)]
46#[repr(transparent)]
47pub struct Ptr5<'a, #[pointee] T: ?Sized, X>
48where
49 Ptr5Companion<T>: MyTrait<T>,
50 Ptr5Companion2: MyTrait<T>,
51{
52 data: &'a mut T,
53 x: core::marker::PhantomData<X>,
54}
55
56pub struct Ptr5Companion<T: ?Sized>(core::marker::PhantomData<T>);
57pub struct Ptr5Companion2;
58
59#[derive(core::marker::CoercePointee)]
60#[repr(transparent)]
61pub struct Ptr6<'a, #[pointee] T: ?Sized, X: MyTrait<T> = (), const PARAM: usize = 0> {
62 data: &'a mut T,
63 x: core::marker::PhantomData<X>,
64}
65
66// a reduced example from https://lore.kernel.org/all/20240402-linked-list-v1-1-b1c59ba7ae3b@google.com/
67#[repr(transparent)]
68#[derive(core::marker::CoercePointee)]
69pub struct ListArc<#[pointee] T, const ID: u64 = 0>
70where
71 T: ListArcSafe<ID> + ?Sized,
72{
73 arc: *const T,
74}
75
76pub trait ListArcSafe<const ID: u64> {}
77
78fn main() {}
tests/ui/deriving/derive-no-std.rs deleted-12
......@@ -1,12 +0,0 @@
1//@ run-pass
2//@ aux-build:derive-no-std.rs
3
4extern crate derive_no_std;
5use derive_no_std::*;
6
7fn main() {
8 let f = Foo { x: 0 };
9 assert_eq!(f.clone(), Foo::default());
10
11 assert!(Bar::Qux < Bar::Quux(42));
12}
tests/ui/deriving/derive-partialord-correctness.rs deleted-9
......@@ -1,9 +0,0 @@
1//@ run-pass
2// Original issue: #49650
3
4#[derive(PartialOrd, PartialEq)]
5struct FloatWrapper(f64);
6
7fn main() {
8 assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(0.0)))
9}
tests/ui/deriving/deriving-all-codegen.rs deleted-237
......@@ -1,237 +0,0 @@
1//@ check-pass
2//@ compile-flags: -Zunpretty=expanded
3//@ edition:2021
4//
5// This test checks the code generated for all[*] the builtin derivable traits
6// on a variety of structs and enums. It protects against accidental changes to
7// the generated code, and makes deliberate changes to the generated code
8// easier to review.
9//
10// [*] It excludes `Copy` in some cases, because that changes the code
11// generated for `Clone`.
12//
13// [*] It excludes `RustcEncodable` and `RustDecodable`, which are obsolete and
14// also require the `rustc_serialize` crate.
15
16#![crate_type = "lib"]
17#![allow(dead_code)]
18#![allow(deprecated)]
19#![feature(derive_from)]
20
21use std::from::From;
22
23// Empty struct.
24#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
25struct Empty;
26
27// A basic struct. Note: because this derives `Copy`, it gets the trivial
28// `clone` implemention that just does `*self`.
29#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
30struct Point {
31 x: u32,
32 y: u32,
33}
34
35// A basic packed struct. Note: because this derives `Copy`, it gets the trivial
36// `clone` implemention that just does `*self`.
37#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
38#[repr(packed)]
39struct PackedPoint {
40 x: u32,
41 y: u32,
42}
43
44#[derive(Clone, Copy, Debug, Default, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
45struct TupleSingleField(u32);
46
47#[derive(Clone, Copy, Debug, Default, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
48struct SingleField {
49 foo: bool,
50}
51
52// A large struct. Note: because this derives `Copy`, it gets the trivial
53// `clone` implemention that just does `*self`.
54#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
55struct Big {
56 b1: u32,
57 b2: u32,
58 b3: u32,
59 b4: u32,
60 b5: u32,
61 b6: u32,
62 b7: u32,
63 b8: u32,
64}
65
66// It is more efficient to compare scalar types before non-scalar types.
67#[derive(PartialEq, PartialOrd)]
68struct Reorder {
69 b1: Option<f32>,
70 b2: u16,
71 b3: &'static str,
72 b4: i8,
73 b5: u128,
74 _b: *mut &'static dyn FnMut() -> (),
75 b6: f64,
76 b7: &'static mut (),
77 b8: char,
78 b9: &'static [i64],
79 b10: &'static *const bool,
80}
81
82// A struct that doesn't impl `Copy`, which means it gets the non-trivial
83// `clone` implemention that clones the fields individually.
84#[derive(Clone)]
85struct NonCopy(u32);
86
87// A packed struct that doesn't impl `Copy`, which means it gets the non-trivial
88// `clone` implemention that clones the fields individually.
89#[derive(Clone)]
90#[repr(packed)]
91struct PackedNonCopy(u32);
92
93// A struct that impls `Copy` manually, which means it gets the non-trivial
94// `clone` implemention that clones the fields individually.
95#[derive(Clone)]
96struct ManualCopy(u32);
97impl Copy for ManualCopy {}
98
99// A packed struct that impls `Copy` manually, which means it gets the
100// non-trivial `clone` implemention that clones the fields individually.
101#[derive(Clone)]
102#[repr(packed)]
103struct PackedManualCopy(u32);
104impl Copy for PackedManualCopy {}
105
106// A struct with an unsized field. Some derives are not usable in this case.
107#[derive(Debug, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
108struct Unsized([u32]);
109
110trait Trait {
111 type A;
112}
113
114// A generic struct involving an associated type.
115#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
116struct Generic<T: Trait, U> {
117 t: T,
118 ta: T::A,
119 u: U,
120}
121
122// A packed, generic tuple struct involving an associated type. Because it is
123// packed, a `T: Copy` bound is added to all impls (and where clauses within
124// them) except for `Default`. This is because we must access fields using
125// copies (e.g. `&{self.0}`), instead of using direct references (e.g.
126// `&self.0`) which may be misaligned in a packed struct.
127#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
128#[repr(packed)]
129struct PackedGeneric<T: Trait, U>(T, T::A, U);
130
131// An empty enum.
132#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
133enum Enum0 {}
134
135// A single-variant enum.
136#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
137enum Enum1 {
138 Single { x: u32 },
139}
140
141// A C-like, fieldless enum with a single variant.
142#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
143enum Fieldless1 {
144 #[default]
145 A,
146}
147
148// A C-like, fieldless enum.
149#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
150enum Fieldless {
151 #[default]
152 A,
153 B,
154 C,
155}
156
157// An enum with multiple fieldless and fielded variants.
158#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
159enum Mixed {
160 #[default]
161 P,
162 Q,
163 R(u32),
164 S {
165 d1: Option<u32>,
166 d2: Option<i32>,
167 },
168}
169
170// When comparing enum variant it is more efficient to compare scalar types before non-scalar types.
171#[derive(PartialEq, PartialOrd)]
172enum ReorderEnum {
173 A(i32),
174 B,
175 C(i8),
176 D,
177 E,
178 F,
179 G(&'static mut str, *const u8, *const dyn Fn() -> ()),
180 H,
181 I,
182}
183
184// An enum with no fieldless variants. Note that `Default` cannot be derived
185// for this enum.
186#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
187enum Fielded {
188 X(u32),
189 Y(bool),
190 Z(Option<i32>),
191}
192
193// A generic enum. Note that `Default` cannot be derived for this enum.
194#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
195enum EnumGeneric<T, U> {
196 One(T),
197 Two(U),
198}
199
200// An enum that has variant, which does't implement `Copy`.
201#[derive(PartialEq)]
202enum NonCopyEnum {
203 // The `dyn NonCopyTrait` implements `PartialEq`, but it doesn't require `Copy`.
204 // So we cannot generate `PartialEq` with dereference.
205 NonCopyField(Box<dyn NonCopyTrait>),
206}
207trait NonCopyTrait {}
208impl PartialEq for dyn NonCopyTrait {
209 fn eq(&self, _other: &Self) -> bool {
210 true
211 }
212}
213
214// A union. Most builtin traits are not derivable for unions.
215#[derive(Clone, Copy)]
216pub union Union {
217 pub b: bool,
218 pub u: u32,
219 pub i: i32,
220}
221
222#[derive(Copy, Clone)]
223struct FooCopyClone(i32);
224
225#[derive(Clone, Copy)]
226struct FooCloneCopy(i32);
227
228#[derive(Copy)]
229#[derive(Clone)]
230struct FooCopyAndClone(i32);
231
232// FIXME(#124794): the previous three structs all have a trivial `Copy`-aware
233// `clone`. But this one doesn't because when the `clone` is generated the
234// `derive(Copy)` hasn't yet been seen.
235#[derive(Clone)]
236#[derive(Copy)]
237struct FooCloneAndCopy(i32);
tests/ui/deriving/deriving-all-codegen.stdout deleted-1851
......@@ -1,1851 +0,0 @@
1#![feature(prelude_import)]
2//@ check-pass
3//@ compile-flags: -Zunpretty=expanded
4//@ edition:2021
5//
6// This test checks the code generated for all[*] the builtin derivable traits
7// on a variety of structs and enums. It protects against accidental changes to
8// the generated code, and makes deliberate changes to the generated code
9// easier to review.
10//
11// [*] It excludes `Copy` in some cases, because that changes the code
12// generated for `Clone`.
13//
14// [*] It excludes `RustcEncodable` and `RustDecodable`, which are obsolete and
15// also require the `rustc_serialize` crate.
16
17#![crate_type = "lib"]
18#![allow(dead_code)]
19#![allow(deprecated)]
20#![feature(derive_from)]
21extern crate std;
22#[prelude_import]
23use std::prelude::rust_2021::*;
24
25use std::from::From;
26
27// Empty struct.
28struct Empty;
29#[automatically_derived]
30#[doc(hidden)]
31unsafe impl ::core::clone::TrivialClone for Empty { }
32#[automatically_derived]
33impl ::core::clone::Clone for Empty {
34 #[inline]
35 fn clone(&self) -> Empty { *self }
36}
37#[automatically_derived]
38impl ::core::marker::Copy for Empty { }
39#[automatically_derived]
40impl ::core::fmt::Debug for Empty {
41 #[inline]
42 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
43 ::core::fmt::Formatter::write_str(f, "Empty")
44 }
45}
46#[automatically_derived]
47impl ::core::default::Default for Empty {
48 #[inline]
49 fn default() -> Empty { Empty {} }
50}
51#[automatically_derived]
52impl ::core::hash::Hash for Empty {
53 #[inline]
54 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
55}
56#[automatically_derived]
57impl ::core::marker::StructuralPartialEq for Empty { }
58#[automatically_derived]
59impl ::core::cmp::PartialEq for Empty {
60 #[inline]
61 fn eq(&self, other: &Empty) -> bool { true }
62}
63#[automatically_derived]
64impl ::core::cmp::Eq for Empty {
65 #[inline]
66 #[doc(hidden)]
67 #[coverage(off)]
68 fn assert_fields_are_eq(&self) {}
69}
70#[automatically_derived]
71impl ::core::cmp::PartialOrd for Empty {
72 #[inline]
73 fn partial_cmp(&self, other: &Empty)
74 -> ::core::option::Option<::core::cmp::Ordering> {
75 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
76 }
77}
78#[automatically_derived]
79impl ::core::cmp::Ord for Empty {
80 #[inline]
81 fn cmp(&self, other: &Empty) -> ::core::cmp::Ordering {
82 ::core::cmp::Ordering::Equal
83 }
84}
85
86// A basic struct. Note: because this derives `Copy`, it gets the trivial
87// `clone` implemention that just does `*self`.
88struct Point {
89 x: u32,
90 y: u32,
91}
92#[automatically_derived]
93#[doc(hidden)]
94unsafe impl ::core::clone::TrivialClone for Point { }
95#[automatically_derived]
96impl ::core::clone::Clone for Point {
97 #[inline]
98 fn clone(&self) -> Point {
99 let _: ::core::clone::AssertParamIsClone<u32>;
100 *self
101 }
102}
103#[automatically_derived]
104impl ::core::marker::Copy for Point { }
105#[automatically_derived]
106impl ::core::fmt::Debug for Point {
107 #[inline]
108 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
109 ::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x",
110 &self.x, "y", &&self.y)
111 }
112}
113#[automatically_derived]
114impl ::core::default::Default for Point {
115 #[inline]
116 fn default() -> Point {
117 Point {
118 x: ::core::default::Default::default(),
119 y: ::core::default::Default::default(),
120 }
121 }
122}
123#[automatically_derived]
124impl ::core::hash::Hash for Point {
125 #[inline]
126 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
127 ::core::hash::Hash::hash(&self.x, state);
128 ::core::hash::Hash::hash(&self.y, state)
129 }
130}
131#[automatically_derived]
132impl ::core::marker::StructuralPartialEq for Point { }
133#[automatically_derived]
134impl ::core::cmp::PartialEq for Point {
135 #[inline]
136 fn eq(&self, other: &Point) -> bool {
137 self.x == other.x && self.y == other.y
138 }
139}
140#[automatically_derived]
141impl ::core::cmp::Eq for Point {
142 #[inline]
143 #[doc(hidden)]
144 #[coverage(off)]
145 fn assert_fields_are_eq(&self) {
146 let _: ::core::cmp::AssertParamIsEq<u32>;
147 }
148}
149#[automatically_derived]
150impl ::core::cmp::PartialOrd for Point {
151 #[inline]
152 fn partial_cmp(&self, other: &Point)
153 -> ::core::option::Option<::core::cmp::Ordering> {
154 match ::core::cmp::PartialOrd::partial_cmp(&self.x, &other.x) {
155 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
156 ::core::cmp::PartialOrd::partial_cmp(&self.y, &other.y),
157 cmp => cmp,
158 }
159 }
160}
161#[automatically_derived]
162impl ::core::cmp::Ord for Point {
163 #[inline]
164 fn cmp(&self, other: &Point) -> ::core::cmp::Ordering {
165 match ::core::cmp::Ord::cmp(&self.x, &other.x) {
166 ::core::cmp::Ordering::Equal =>
167 ::core::cmp::Ord::cmp(&self.y, &other.y),
168 cmp => cmp,
169 }
170 }
171}
172
173// A basic packed struct. Note: because this derives `Copy`, it gets the trivial
174// `clone` implemention that just does `*self`.
175#[repr(packed)]
176struct PackedPoint {
177 x: u32,
178 y: u32,
179}
180#[automatically_derived]
181#[doc(hidden)]
182unsafe impl ::core::clone::TrivialClone for PackedPoint { }
183#[automatically_derived]
184impl ::core::clone::Clone for PackedPoint {
185 #[inline]
186 fn clone(&self) -> PackedPoint {
187 let _: ::core::clone::AssertParamIsClone<u32>;
188 *self
189 }
190}
191#[automatically_derived]
192impl ::core::marker::Copy for PackedPoint { }
193#[automatically_derived]
194impl ::core::fmt::Debug for PackedPoint {
195 #[inline]
196 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
197 ::core::fmt::Formatter::debug_struct_field2_finish(f, "PackedPoint",
198 "x", &{ self.x }, "y", &&{ self.y })
199 }
200}
201#[automatically_derived]
202impl ::core::default::Default for PackedPoint {
203 #[inline]
204 fn default() -> PackedPoint {
205 PackedPoint {
206 x: ::core::default::Default::default(),
207 y: ::core::default::Default::default(),
208 }
209 }
210}
211#[automatically_derived]
212impl ::core::hash::Hash for PackedPoint {
213 #[inline]
214 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
215 ::core::hash::Hash::hash(&{ self.x }, state);
216 ::core::hash::Hash::hash(&{ self.y }, state)
217 }
218}
219#[automatically_derived]
220impl ::core::marker::StructuralPartialEq for PackedPoint { }
221#[automatically_derived]
222impl ::core::cmp::PartialEq for PackedPoint {
223 #[inline]
224 fn eq(&self, other: &PackedPoint) -> bool {
225 ({ self.x }) == ({ other.x }) && ({ self.y }) == ({ other.y })
226 }
227}
228#[automatically_derived]
229impl ::core::cmp::Eq for PackedPoint {
230 #[inline]
231 #[doc(hidden)]
232 #[coverage(off)]
233 fn assert_fields_are_eq(&self) {
234 let _: ::core::cmp::AssertParamIsEq<u32>;
235 }
236}
237#[automatically_derived]
238impl ::core::cmp::PartialOrd for PackedPoint {
239 #[inline]
240 fn partial_cmp(&self, other: &PackedPoint)
241 -> ::core::option::Option<::core::cmp::Ordering> {
242 match ::core::cmp::PartialOrd::partial_cmp(&{ self.x }, &{ other.x })
243 {
244 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
245 ::core::cmp::PartialOrd::partial_cmp(&{ self.y },
246 &{ other.y }),
247 cmp => cmp,
248 }
249 }
250}
251#[automatically_derived]
252impl ::core::cmp::Ord for PackedPoint {
253 #[inline]
254 fn cmp(&self, other: &PackedPoint) -> ::core::cmp::Ordering {
255 match ::core::cmp::Ord::cmp(&{ self.x }, &{ other.x }) {
256 ::core::cmp::Ordering::Equal =>
257 ::core::cmp::Ord::cmp(&{ self.y }, &{ other.y }),
258 cmp => cmp,
259 }
260 }
261}
262
263struct TupleSingleField(u32);
264#[automatically_derived]
265#[doc(hidden)]
266unsafe impl ::core::clone::TrivialClone for TupleSingleField { }
267#[automatically_derived]
268impl ::core::clone::Clone for TupleSingleField {
269 #[inline]
270 fn clone(&self) -> TupleSingleField {
271 let _: ::core::clone::AssertParamIsClone<u32>;
272 *self
273 }
274}
275#[automatically_derived]
276impl ::core::marker::Copy for TupleSingleField { }
277#[automatically_derived]
278impl ::core::fmt::Debug for TupleSingleField {
279 #[inline]
280 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
281 ::core::fmt::Formatter::debug_tuple_field1_finish(f,
282 "TupleSingleField", &&self.0)
283 }
284}
285#[automatically_derived]
286impl ::core::default::Default for TupleSingleField {
287 #[inline]
288 fn default() -> TupleSingleField {
289 TupleSingleField(::core::default::Default::default())
290 }
291}
292#[automatically_derived]
293impl ::core::convert::From<u32> for TupleSingleField {
294 #[inline]
295 fn from(value: u32) -> TupleSingleField { Self(value) }
296}
297#[automatically_derived]
298impl ::core::hash::Hash for TupleSingleField {
299 #[inline]
300 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
301 ::core::hash::Hash::hash(&self.0, state)
302 }
303}
304#[automatically_derived]
305impl ::core::marker::StructuralPartialEq for TupleSingleField { }
306#[automatically_derived]
307impl ::core::cmp::PartialEq for TupleSingleField {
308 #[inline]
309 fn eq(&self, other: &TupleSingleField) -> bool { self.0 == other.0 }
310}
311#[automatically_derived]
312impl ::core::cmp::Eq for TupleSingleField {
313 #[inline]
314 #[doc(hidden)]
315 #[coverage(off)]
316 fn assert_fields_are_eq(&self) {
317 let _: ::core::cmp::AssertParamIsEq<u32>;
318 }
319}
320#[automatically_derived]
321impl ::core::cmp::PartialOrd for TupleSingleField {
322 #[inline]
323 fn partial_cmp(&self, other: &TupleSingleField)
324 -> ::core::option::Option<::core::cmp::Ordering> {
325 ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
326 }
327}
328#[automatically_derived]
329impl ::core::cmp::Ord for TupleSingleField {
330 #[inline]
331 fn cmp(&self, other: &TupleSingleField) -> ::core::cmp::Ordering {
332 ::core::cmp::Ord::cmp(&self.0, &other.0)
333 }
334}
335
336struct SingleField {
337 foo: bool,
338}
339#[automatically_derived]
340#[doc(hidden)]
341unsafe impl ::core::clone::TrivialClone for SingleField { }
342#[automatically_derived]
343impl ::core::clone::Clone for SingleField {
344 #[inline]
345 fn clone(&self) -> SingleField {
346 let _: ::core::clone::AssertParamIsClone<bool>;
347 *self
348 }
349}
350#[automatically_derived]
351impl ::core::marker::Copy for SingleField { }
352#[automatically_derived]
353impl ::core::fmt::Debug for SingleField {
354 #[inline]
355 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
356 ::core::fmt::Formatter::debug_struct_field1_finish(f, "SingleField",
357 "foo", &&self.foo)
358 }
359}
360#[automatically_derived]
361impl ::core::default::Default for SingleField {
362 #[inline]
363 fn default() -> SingleField {
364 SingleField { foo: ::core::default::Default::default() }
365 }
366}
367#[automatically_derived]
368impl ::core::convert::From<bool> for SingleField {
369 #[inline]
370 fn from(value: bool) -> SingleField { Self { foo: value } }
371}
372#[automatically_derived]
373impl ::core::hash::Hash for SingleField {
374 #[inline]
375 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
376 ::core::hash::Hash::hash(&self.foo, state)
377 }
378}
379#[automatically_derived]
380impl ::core::marker::StructuralPartialEq for SingleField { }
381#[automatically_derived]
382impl ::core::cmp::PartialEq for SingleField {
383 #[inline]
384 fn eq(&self, other: &SingleField) -> bool { self.foo == other.foo }
385}
386#[automatically_derived]
387impl ::core::cmp::Eq for SingleField {
388 #[inline]
389 #[doc(hidden)]
390 #[coverage(off)]
391 fn assert_fields_are_eq(&self) {
392 let _: ::core::cmp::AssertParamIsEq<bool>;
393 }
394}
395#[automatically_derived]
396impl ::core::cmp::PartialOrd for SingleField {
397 #[inline]
398 fn partial_cmp(&self, other: &SingleField)
399 -> ::core::option::Option<::core::cmp::Ordering> {
400 ::core::cmp::PartialOrd::partial_cmp(&self.foo, &other.foo)
401 }
402}
403#[automatically_derived]
404impl ::core::cmp::Ord for SingleField {
405 #[inline]
406 fn cmp(&self, other: &SingleField) -> ::core::cmp::Ordering {
407 ::core::cmp::Ord::cmp(&self.foo, &other.foo)
408 }
409}
410
411// A large struct. Note: because this derives `Copy`, it gets the trivial
412// `clone` implemention that just does `*self`.
413struct Big {
414 b1: u32,
415 b2: u32,
416 b3: u32,
417 b4: u32,
418 b5: u32,
419 b6: u32,
420 b7: u32,
421 b8: u32,
422}
423#[automatically_derived]
424#[doc(hidden)]
425unsafe impl ::core::clone::TrivialClone for Big { }
426#[automatically_derived]
427impl ::core::clone::Clone for Big {
428 #[inline]
429 fn clone(&self) -> Big {
430 let _: ::core::clone::AssertParamIsClone<u32>;
431 *self
432 }
433}
434#[automatically_derived]
435impl ::core::marker::Copy for Big { }
436#[automatically_derived]
437impl ::core::fmt::Debug for Big {
438 #[inline]
439 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
440 let names: &'static _ =
441 &["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"];
442 let values: &[&dyn ::core::fmt::Debug] =
443 &[&self.b1, &self.b2, &self.b3, &self.b4, &self.b5, &self.b6,
444 &self.b7, &&self.b8];
445 ::core::fmt::Formatter::debug_struct_fields_finish(f, "Big", names,
446 values)
447 }
448}
449#[automatically_derived]
450impl ::core::default::Default for Big {
451 #[inline]
452 fn default() -> Big {
453 Big {
454 b1: ::core::default::Default::default(),
455 b2: ::core::default::Default::default(),
456 b3: ::core::default::Default::default(),
457 b4: ::core::default::Default::default(),
458 b5: ::core::default::Default::default(),
459 b6: ::core::default::Default::default(),
460 b7: ::core::default::Default::default(),
461 b8: ::core::default::Default::default(),
462 }
463 }
464}
465#[automatically_derived]
466impl ::core::hash::Hash for Big {
467 #[inline]
468 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
469 ::core::hash::Hash::hash(&self.b1, state);
470 ::core::hash::Hash::hash(&self.b2, state);
471 ::core::hash::Hash::hash(&self.b3, state);
472 ::core::hash::Hash::hash(&self.b4, state);
473 ::core::hash::Hash::hash(&self.b5, state);
474 ::core::hash::Hash::hash(&self.b6, state);
475 ::core::hash::Hash::hash(&self.b7, state);
476 ::core::hash::Hash::hash(&self.b8, state)
477 }
478}
479#[automatically_derived]
480impl ::core::marker::StructuralPartialEq for Big { }
481#[automatically_derived]
482impl ::core::cmp::PartialEq for Big {
483 #[inline]
484 fn eq(&self, other: &Big) -> bool {
485 self.b1 == other.b1 && self.b2 == other.b2 && self.b3 == other.b3 &&
486 self.b4 == other.b4 && self.b5 == other.b5 &&
487 self.b6 == other.b6 && self.b7 == other.b7 &&
488 self.b8 == other.b8
489 }
490}
491#[automatically_derived]
492impl ::core::cmp::Eq for Big {
493 #[inline]
494 #[doc(hidden)]
495 #[coverage(off)]
496 fn assert_fields_are_eq(&self) {
497 let _: ::core::cmp::AssertParamIsEq<u32>;
498 }
499}
500#[automatically_derived]
501impl ::core::cmp::PartialOrd for Big {
502 #[inline]
503 fn partial_cmp(&self, other: &Big)
504 -> ::core::option::Option<::core::cmp::Ordering> {
505 match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
506 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
507 match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
508 &other.b2) {
509 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
510 =>
511 match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
512 &other.b3) {
513 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
514 =>
515 match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
516 &other.b4) {
517 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
518 =>
519 match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
520 &other.b5) {
521 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
522 =>
523 match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
524 &other.b6) {
525 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
526 =>
527 match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
528 &other.b7) {
529 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
530 =>
531 ::core::cmp::PartialOrd::partial_cmp(&self.b8, &other.b8),
532 cmp => cmp,
533 },
534 cmp => cmp,
535 },
536 cmp => cmp,
537 },
538 cmp => cmp,
539 },
540 cmp => cmp,
541 },
542 cmp => cmp,
543 },
544 cmp => cmp,
545 }
546 }
547}
548#[automatically_derived]
549impl ::core::cmp::Ord for Big {
550 #[inline]
551 fn cmp(&self, other: &Big) -> ::core::cmp::Ordering {
552 match ::core::cmp::Ord::cmp(&self.b1, &other.b1) {
553 ::core::cmp::Ordering::Equal =>
554 match ::core::cmp::Ord::cmp(&self.b2, &other.b2) {
555 ::core::cmp::Ordering::Equal =>
556 match ::core::cmp::Ord::cmp(&self.b3, &other.b3) {
557 ::core::cmp::Ordering::Equal =>
558 match ::core::cmp::Ord::cmp(&self.b4, &other.b4) {
559 ::core::cmp::Ordering::Equal =>
560 match ::core::cmp::Ord::cmp(&self.b5, &other.b5) {
561 ::core::cmp::Ordering::Equal =>
562 match ::core::cmp::Ord::cmp(&self.b6, &other.b6) {
563 ::core::cmp::Ordering::Equal =>
564 match ::core::cmp::Ord::cmp(&self.b7, &other.b7) {
565 ::core::cmp::Ordering::Equal =>
566 ::core::cmp::Ord::cmp(&self.b8, &other.b8),
567 cmp => cmp,
568 },
569 cmp => cmp,
570 },
571 cmp => cmp,
572 },
573 cmp => cmp,
574 },
575 cmp => cmp,
576 },
577 cmp => cmp,
578 },
579 cmp => cmp,
580 }
581 }
582}
583
584// It is more efficient to compare scalar types before non-scalar types.
585struct Reorder {
586 b1: Option<f32>,
587 b2: u16,
588 b3: &'static str,
589 b4: i8,
590 b5: u128,
591 _b: *mut &'static dyn FnMut() -> (),
592 b6: f64,
593 b7: &'static mut (),
594 b8: char,
595 b9: &'static [i64],
596 b10: &'static *const bool,
597}
598#[automatically_derived]
599impl ::core::marker::StructuralPartialEq for Reorder { }
600#[automatically_derived]
601impl ::core::cmp::PartialEq for Reorder {
602 #[inline]
603 fn eq(&self, other: &Reorder) -> bool {
604 self.b2 == other.b2 && self.b4 == other.b4 && self.b5 == other.b5 &&
605 self.b6 == other.b6 && self.b7 == other.b7 &&
606 self.b8 == other.b8 && self.b10 == other.b10 &&
607 self.b1 == other.b1 && self.b3 == other.b3 &&
608 self._b == other._b && self.b9 == other.b9
609 }
610}
611#[automatically_derived]
612impl ::core::cmp::PartialOrd for Reorder {
613 #[inline]
614 fn partial_cmp(&self, other: &Reorder)
615 -> ::core::option::Option<::core::cmp::Ordering> {
616 match ::core::cmp::PartialOrd::partial_cmp(&self.b1, &other.b1) {
617 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
618 match ::core::cmp::PartialOrd::partial_cmp(&self.b2,
619 &other.b2) {
620 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
621 =>
622 match ::core::cmp::PartialOrd::partial_cmp(&self.b3,
623 &other.b3) {
624 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
625 =>
626 match ::core::cmp::PartialOrd::partial_cmp(&self.b4,
627 &other.b4) {
628 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
629 =>
630 match ::core::cmp::PartialOrd::partial_cmp(&self.b5,
631 &other.b5) {
632 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
633 =>
634 match ::core::cmp::PartialOrd::partial_cmp(&self._b,
635 &other._b) {
636 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
637 =>
638 match ::core::cmp::PartialOrd::partial_cmp(&self.b6,
639 &other.b6) {
640 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
641 =>
642 match ::core::cmp::PartialOrd::partial_cmp(&self.b7,
643 &other.b7) {
644 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
645 =>
646 match ::core::cmp::PartialOrd::partial_cmp(&self.b8,
647 &other.b8) {
648 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
649 =>
650 match ::core::cmp::PartialOrd::partial_cmp(&self.b9,
651 &other.b9) {
652 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
653 =>
654 ::core::cmp::PartialOrd::partial_cmp(&self.b10, &other.b10),
655 cmp => cmp,
656 },
657 cmp => cmp,
658 },
659 cmp => cmp,
660 },
661 cmp => cmp,
662 },
663 cmp => cmp,
664 },
665 cmp => cmp,
666 },
667 cmp => cmp,
668 },
669 cmp => cmp,
670 },
671 cmp => cmp,
672 },
673 cmp => cmp,
674 }
675 }
676}
677
678// A struct that doesn't impl `Copy`, which means it gets the non-trivial
679// `clone` implemention that clones the fields individually.
680struct NonCopy(u32);
681#[automatically_derived]
682impl ::core::clone::Clone for NonCopy {
683 #[inline]
684 fn clone(&self) -> NonCopy {
685 NonCopy(::core::clone::Clone::clone(&self.0))
686 }
687}
688
689// A packed struct that doesn't impl `Copy`, which means it gets the non-trivial
690// `clone` implemention that clones the fields individually.
691#[repr(packed)]
692struct PackedNonCopy(u32);
693#[automatically_derived]
694impl ::core::clone::Clone for PackedNonCopy {
695 #[inline]
696 fn clone(&self) -> PackedNonCopy {
697 PackedNonCopy(::core::clone::Clone::clone(&{ self.0 }))
698 }
699}
700
701// A struct that impls `Copy` manually, which means it gets the non-trivial
702// `clone` implemention that clones the fields individually.
703struct ManualCopy(u32);
704#[automatically_derived]
705impl ::core::clone::Clone for ManualCopy {
706 #[inline]
707 fn clone(&self) -> ManualCopy {
708 ManualCopy(::core::clone::Clone::clone(&self.0))
709 }
710}
711impl Copy for ManualCopy {}
712
713// A packed struct that impls `Copy` manually, which means it gets the
714// non-trivial `clone` implemention that clones the fields individually.
715#[repr(packed)]
716struct PackedManualCopy(u32);
717#[automatically_derived]
718impl ::core::clone::Clone for PackedManualCopy {
719 #[inline]
720 fn clone(&self) -> PackedManualCopy {
721 PackedManualCopy(::core::clone::Clone::clone(&{ self.0 }))
722 }
723}
724impl Copy for PackedManualCopy {}
725
726// A struct with an unsized field. Some derives are not usable in this case.
727struct Unsized([u32]);
728#[automatically_derived]
729impl ::core::fmt::Debug for Unsized {
730 #[inline]
731 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
732 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Unsized",
733 &&self.0)
734 }
735}
736#[automatically_derived]
737impl ::core::convert::From<[u32]> for Unsized {
738 #[inline]
739 fn from(value: [u32]) -> Unsized { Self(value) }
740}
741#[automatically_derived]
742impl ::core::hash::Hash for Unsized {
743 #[inline]
744 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
745 ::core::hash::Hash::hash(&self.0, state)
746 }
747}
748#[automatically_derived]
749impl ::core::marker::StructuralPartialEq for Unsized { }
750#[automatically_derived]
751impl ::core::cmp::PartialEq for Unsized {
752 #[inline]
753 fn eq(&self, other: &Unsized) -> bool { self.0 == other.0 }
754}
755#[automatically_derived]
756impl ::core::cmp::Eq for Unsized {
757 #[inline]
758 #[doc(hidden)]
759 #[coverage(off)]
760 fn assert_fields_are_eq(&self) {
761 let _: ::core::cmp::AssertParamIsEq<[u32]>;
762 }
763}
764#[automatically_derived]
765impl ::core::cmp::PartialOrd for Unsized {
766 #[inline]
767 fn partial_cmp(&self, other: &Unsized)
768 -> ::core::option::Option<::core::cmp::Ordering> {
769 ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
770 }
771}
772#[automatically_derived]
773impl ::core::cmp::Ord for Unsized {
774 #[inline]
775 fn cmp(&self, other: &Unsized) -> ::core::cmp::Ordering {
776 ::core::cmp::Ord::cmp(&self.0, &other.0)
777 }
778}
779
780trait Trait {
781 type A;
782}
783
784// A generic struct involving an associated type.
785struct Generic<T: Trait, U> {
786 t: T,
787 ta: T::A,
788 u: U,
789}
790#[automatically_derived]
791impl<T: ::core::clone::Clone + Trait, U: ::core::clone::Clone>
792 ::core::clone::Clone for Generic<T, U> where T::A: ::core::clone::Clone {
793 #[inline]
794 fn clone(&self) -> Generic<T, U> {
795 Generic {
796 t: ::core::clone::Clone::clone(&self.t),
797 ta: ::core::clone::Clone::clone(&self.ta),
798 u: ::core::clone::Clone::clone(&self.u),
799 }
800 }
801}
802#[automatically_derived]
803impl<T: ::core::marker::Copy + Trait, U: ::core::marker::Copy>
804 ::core::marker::Copy for Generic<T, U> where T::A: ::core::marker::Copy {
805}
806#[automatically_derived]
807impl<T: ::core::fmt::Debug + Trait, U: ::core::fmt::Debug> ::core::fmt::Debug
808 for Generic<T, U> where T::A: ::core::fmt::Debug {
809 #[inline]
810 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
811 ::core::fmt::Formatter::debug_struct_field3_finish(f, "Generic", "t",
812 &self.t, "ta", &self.ta, "u", &&self.u)
813 }
814}
815#[automatically_derived]
816impl<T: ::core::default::Default + Trait, U: ::core::default::Default>
817 ::core::default::Default for Generic<T, U> where
818 T::A: ::core::default::Default {
819 #[inline]
820 fn default() -> Generic<T, U> {
821 Generic {
822 t: ::core::default::Default::default(),
823 ta: ::core::default::Default::default(),
824 u: ::core::default::Default::default(),
825 }
826 }
827}
828#[automatically_derived]
829impl<T: ::core::hash::Hash + Trait, U: ::core::hash::Hash> ::core::hash::Hash
830 for Generic<T, U> where T::A: ::core::hash::Hash {
831 #[inline]
832 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
833 ::core::hash::Hash::hash(&self.t, state);
834 ::core::hash::Hash::hash(&self.ta, state);
835 ::core::hash::Hash::hash(&self.u, state)
836 }
837}
838#[automatically_derived]
839impl<T: Trait, U> ::core::marker::StructuralPartialEq for Generic<T, U> { }
840#[automatically_derived]
841impl<T: ::core::cmp::PartialEq + Trait, U: ::core::cmp::PartialEq>
842 ::core::cmp::PartialEq for Generic<T, U> where
843 T::A: ::core::cmp::PartialEq {
844 #[inline]
845 fn eq(&self, other: &Generic<T, U>) -> bool {
846 self.t == other.t && self.ta == other.ta && self.u == other.u
847 }
848}
849#[automatically_derived]
850impl<T: ::core::cmp::Eq + Trait, U: ::core::cmp::Eq> ::core::cmp::Eq for
851 Generic<T, U> where T::A: ::core::cmp::Eq {
852 #[inline]
853 #[doc(hidden)]
854 #[coverage(off)]
855 fn assert_fields_are_eq(&self) {
856 let _: ::core::cmp::AssertParamIsEq<T>;
857 let _: ::core::cmp::AssertParamIsEq<T::A>;
858 let _: ::core::cmp::AssertParamIsEq<U>;
859 }
860}
861#[automatically_derived]
862impl<T: ::core::cmp::PartialOrd + Trait, U: ::core::cmp::PartialOrd>
863 ::core::cmp::PartialOrd for Generic<T, U> where
864 T::A: ::core::cmp::PartialOrd {
865 #[inline]
866 fn partial_cmp(&self, other: &Generic<T, U>)
867 -> ::core::option::Option<::core::cmp::Ordering> {
868 match ::core::cmp::PartialOrd::partial_cmp(&self.t, &other.t) {
869 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
870 match ::core::cmp::PartialOrd::partial_cmp(&self.ta,
871 &other.ta) {
872 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
873 => ::core::cmp::PartialOrd::partial_cmp(&self.u, &other.u),
874 cmp => cmp,
875 },
876 cmp => cmp,
877 }
878 }
879}
880#[automatically_derived]
881impl<T: ::core::cmp::Ord + Trait, U: ::core::cmp::Ord> ::core::cmp::Ord for
882 Generic<T, U> where T::A: ::core::cmp::Ord {
883 #[inline]
884 fn cmp(&self, other: &Generic<T, U>) -> ::core::cmp::Ordering {
885 match ::core::cmp::Ord::cmp(&self.t, &other.t) {
886 ::core::cmp::Ordering::Equal =>
887 match ::core::cmp::Ord::cmp(&self.ta, &other.ta) {
888 ::core::cmp::Ordering::Equal =>
889 ::core::cmp::Ord::cmp(&self.u, &other.u),
890 cmp => cmp,
891 },
892 cmp => cmp,
893 }
894 }
895}
896
897// A packed, generic tuple struct involving an associated type. Because it is
898// packed, a `T: Copy` bound is added to all impls (and where clauses within
899// them) except for `Default`. This is because we must access fields using
900// copies (e.g. `&{self.0}`), instead of using direct references (e.g.
901// `&self.0`) which may be misaligned in a packed struct.
902#[repr(packed)]
903struct PackedGeneric<T: Trait, U>(T, T::A, U);
904#[automatically_derived]
905impl<T: ::core::clone::Clone + ::core::marker::Copy + Trait,
906 U: ::core::clone::Clone + ::core::marker::Copy> ::core::clone::Clone for
907 PackedGeneric<T, U> where T::A: ::core::clone::Clone +
908 ::core::marker::Copy {
909 #[inline]
910 fn clone(&self) -> PackedGeneric<T, U> {
911 PackedGeneric(::core::clone::Clone::clone(&{ self.0 }),
912 ::core::clone::Clone::clone(&{ self.1 }),
913 ::core::clone::Clone::clone(&{ self.2 }))
914 }
915}
916#[automatically_derived]
917impl<T: ::core::marker::Copy + Trait, U: ::core::marker::Copy>
918 ::core::marker::Copy for PackedGeneric<T, U> where
919 T::A: ::core::marker::Copy {
920}
921#[automatically_derived]
922impl<T: ::core::fmt::Debug + ::core::marker::Copy + Trait,
923 U: ::core::fmt::Debug + ::core::marker::Copy> ::core::fmt::Debug for
924 PackedGeneric<T, U> where T::A: ::core::fmt::Debug + ::core::marker::Copy
925 {
926 #[inline]
927 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
928 ::core::fmt::Formatter::debug_tuple_field3_finish(f, "PackedGeneric",
929 &{ self.0 }, &{ self.1 }, &&{ self.2 })
930 }
931}
932#[automatically_derived]
933impl<T: ::core::default::Default + Trait, U: ::core::default::Default>
934 ::core::default::Default for PackedGeneric<T, U> where
935 T::A: ::core::default::Default {
936 #[inline]
937 fn default() -> PackedGeneric<T, U> {
938 PackedGeneric(::core::default::Default::default(),
939 ::core::default::Default::default(),
940 ::core::default::Default::default())
941 }
942}
943#[automatically_derived]
944impl<T: ::core::hash::Hash + ::core::marker::Copy + Trait,
945 U: ::core::hash::Hash + ::core::marker::Copy> ::core::hash::Hash for
946 PackedGeneric<T, U> where T::A: ::core::hash::Hash + ::core::marker::Copy
947 {
948 #[inline]
949 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
950 ::core::hash::Hash::hash(&{ self.0 }, state);
951 ::core::hash::Hash::hash(&{ self.1 }, state);
952 ::core::hash::Hash::hash(&{ self.2 }, state)
953 }
954}
955#[automatically_derived]
956impl<T: Trait, U> ::core::marker::StructuralPartialEq for PackedGeneric<T, U>
957 {
958}
959#[automatically_derived]
960impl<T: ::core::cmp::PartialEq + ::core::marker::Copy + Trait,
961 U: ::core::cmp::PartialEq + ::core::marker::Copy> ::core::cmp::PartialEq
962 for PackedGeneric<T, U> where T::A: ::core::cmp::PartialEq +
963 ::core::marker::Copy {
964 #[inline]
965 fn eq(&self, other: &PackedGeneric<T, U>) -> bool {
966 ({ self.0 }) == ({ other.0 }) && ({ self.1 }) == ({ other.1 }) &&
967 ({ self.2 }) == ({ other.2 })
968 }
969}
970#[automatically_derived]
971impl<T: ::core::cmp::Eq + ::core::marker::Copy + Trait, U: ::core::cmp::Eq +
972 ::core::marker::Copy> ::core::cmp::Eq for PackedGeneric<T, U> where
973 T::A: ::core::cmp::Eq + ::core::marker::Copy {
974 #[inline]
975 #[doc(hidden)]
976 #[coverage(off)]
977 fn assert_fields_are_eq(&self) {
978 let _: ::core::cmp::AssertParamIsEq<T>;
979 let _: ::core::cmp::AssertParamIsEq<T::A>;
980 let _: ::core::cmp::AssertParamIsEq<U>;
981 }
982}
983#[automatically_derived]
984impl<T: ::core::cmp::PartialOrd + ::core::marker::Copy + Trait,
985 U: ::core::cmp::PartialOrd + ::core::marker::Copy> ::core::cmp::PartialOrd
986 for PackedGeneric<T, U> where T::A: ::core::cmp::PartialOrd +
987 ::core::marker::Copy {
988 #[inline]
989 fn partial_cmp(&self, other: &PackedGeneric<T, U>)
990 -> ::core::option::Option<::core::cmp::Ordering> {
991 match ::core::cmp::PartialOrd::partial_cmp(&{ self.0 }, &{ other.0 })
992 {
993 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
994 match ::core::cmp::PartialOrd::partial_cmp(&{ self.1 },
995 &{ other.1 }) {
996 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
997 =>
998 ::core::cmp::PartialOrd::partial_cmp(&{ self.2 },
999 &{ other.2 }),
1000 cmp => cmp,
1001 },
1002 cmp => cmp,
1003 }
1004 }
1005}
1006#[automatically_derived]
1007impl<T: ::core::cmp::Ord + ::core::marker::Copy + Trait, U: ::core::cmp::Ord +
1008 ::core::marker::Copy> ::core::cmp::Ord for PackedGeneric<T, U> where
1009 T::A: ::core::cmp::Ord + ::core::marker::Copy {
1010 #[inline]
1011 fn cmp(&self, other: &PackedGeneric<T, U>) -> ::core::cmp::Ordering {
1012 match ::core::cmp::Ord::cmp(&{ self.0 }, &{ other.0 }) {
1013 ::core::cmp::Ordering::Equal =>
1014 match ::core::cmp::Ord::cmp(&{ self.1 }, &{ other.1 }) {
1015 ::core::cmp::Ordering::Equal =>
1016 ::core::cmp::Ord::cmp(&{ self.2 }, &{ other.2 }),
1017 cmp => cmp,
1018 },
1019 cmp => cmp,
1020 }
1021 }
1022}
1023
1024// An empty enum.
1025enum Enum0 {}
1026#[automatically_derived]
1027#[doc(hidden)]
1028unsafe impl ::core::clone::TrivialClone for Enum0 { }
1029#[automatically_derived]
1030impl ::core::clone::Clone for Enum0 {
1031 #[inline]
1032 fn clone(&self) -> Enum0 { *self }
1033}
1034#[automatically_derived]
1035impl ::core::marker::Copy for Enum0 { }
1036#[automatically_derived]
1037impl ::core::fmt::Debug for Enum0 {
1038 #[inline]
1039 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1040 match *self {}
1041 }
1042}
1043#[automatically_derived]
1044impl ::core::hash::Hash for Enum0 {
1045 #[inline]
1046 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1047 match *self {}
1048 }
1049}
1050#[automatically_derived]
1051impl ::core::marker::StructuralPartialEq for Enum0 { }
1052#[automatically_derived]
1053impl ::core::cmp::PartialEq for Enum0 {
1054 #[inline]
1055 fn eq(&self, other: &Enum0) -> bool { match *self {} }
1056}
1057#[automatically_derived]
1058impl ::core::cmp::Eq for Enum0 {
1059 #[inline]
1060 #[doc(hidden)]
1061 #[coverage(off)]
1062 fn assert_fields_are_eq(&self) {}
1063}
1064#[automatically_derived]
1065impl ::core::cmp::PartialOrd for Enum0 {
1066 #[inline]
1067 fn partial_cmp(&self, other: &Enum0)
1068 -> ::core::option::Option<::core::cmp::Ordering> {
1069 match *self {}
1070 }
1071}
1072#[automatically_derived]
1073impl ::core::cmp::Ord for Enum0 {
1074 #[inline]
1075 fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering { match *self {} }
1076}
1077
1078// A single-variant enum.
1079enum Enum1 {
1080 Single {
1081 x: u32,
1082 },
1083}
1084#[automatically_derived]
1085impl ::core::clone::Clone for Enum1 {
1086 #[inline]
1087 fn clone(&self) -> Enum1 {
1088 match self {
1089 Enum1::Single { x: __self_0 } =>
1090 Enum1::Single { x: ::core::clone::Clone::clone(__self_0) },
1091 }
1092 }
1093}
1094#[automatically_derived]
1095impl ::core::fmt::Debug for Enum1 {
1096 #[inline]
1097 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1098 match self {
1099 Enum1::Single { x: __self_0 } =>
1100 ::core::fmt::Formatter::debug_struct_field1_finish(f,
1101 "Single", "x", &__self_0),
1102 }
1103 }
1104}
1105#[automatically_derived]
1106impl ::core::hash::Hash for Enum1 {
1107 #[inline]
1108 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1109 match self {
1110 Enum1::Single { x: __self_0 } =>
1111 ::core::hash::Hash::hash(__self_0, state),
1112 }
1113 }
1114}
1115#[automatically_derived]
1116impl ::core::marker::StructuralPartialEq for Enum1 { }
1117#[automatically_derived]
1118impl ::core::cmp::PartialEq for Enum1 {
1119 #[inline]
1120 fn eq(&self, other: &Enum1) -> bool {
1121 match (self, other) {
1122 (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
1123 __self_0 == __arg1_0,
1124 }
1125 }
1126}
1127#[automatically_derived]
1128impl ::core::cmp::Eq for Enum1 {
1129 #[inline]
1130 #[doc(hidden)]
1131 #[coverage(off)]
1132 fn assert_fields_are_eq(&self) {
1133 let _: ::core::cmp::AssertParamIsEq<u32>;
1134 }
1135}
1136#[automatically_derived]
1137impl ::core::cmp::PartialOrd for Enum1 {
1138 #[inline]
1139 fn partial_cmp(&self, other: &Enum1)
1140 -> ::core::option::Option<::core::cmp::Ordering> {
1141 match (self, other) {
1142 (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
1143 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1144 }
1145 }
1146}
1147#[automatically_derived]
1148impl ::core::cmp::Ord for Enum1 {
1149 #[inline]
1150 fn cmp(&self, other: &Enum1) -> ::core::cmp::Ordering {
1151 match (self, other) {
1152 (Enum1::Single { x: __self_0 }, Enum1::Single { x: __arg1_0 }) =>
1153 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1154 }
1155 }
1156}
1157
1158// A C-like, fieldless enum with a single variant.
1159enum Fieldless1 {
1160
1161 #[default]
1162 A,
1163}
1164#[automatically_derived]
1165impl ::core::clone::Clone for Fieldless1 {
1166 #[inline]
1167 fn clone(&self) -> Fieldless1 { Fieldless1::A }
1168}
1169#[automatically_derived]
1170impl ::core::fmt::Debug for Fieldless1 {
1171 #[inline]
1172 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1173 ::core::fmt::Formatter::write_str(f, "A")
1174 }
1175}
1176#[automatically_derived]
1177impl ::core::default::Default for Fieldless1 {
1178 #[inline]
1179 fn default() -> Fieldless1 { Self::A }
1180}
1181#[automatically_derived]
1182impl ::core::hash::Hash for Fieldless1 {
1183 #[inline]
1184 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
1185}
1186#[automatically_derived]
1187impl ::core::marker::StructuralPartialEq for Fieldless1 { }
1188#[automatically_derived]
1189impl ::core::cmp::PartialEq for Fieldless1 {
1190 #[inline]
1191 fn eq(&self, other: &Fieldless1) -> bool { true }
1192}
1193#[automatically_derived]
1194impl ::core::cmp::Eq for Fieldless1 {
1195 #[inline]
1196 #[doc(hidden)]
1197 #[coverage(off)]
1198 fn assert_fields_are_eq(&self) {}
1199}
1200#[automatically_derived]
1201impl ::core::cmp::PartialOrd for Fieldless1 {
1202 #[inline]
1203 fn partial_cmp(&self, other: &Fieldless1)
1204 -> ::core::option::Option<::core::cmp::Ordering> {
1205 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1206 }
1207}
1208#[automatically_derived]
1209impl ::core::cmp::Ord for Fieldless1 {
1210 #[inline]
1211 fn cmp(&self, other: &Fieldless1) -> ::core::cmp::Ordering {
1212 ::core::cmp::Ordering::Equal
1213 }
1214}
1215
1216// A C-like, fieldless enum.
1217enum Fieldless {
1218
1219 #[default]
1220 A,
1221 B,
1222 C,
1223}
1224#[automatically_derived]
1225#[doc(hidden)]
1226unsafe impl ::core::clone::TrivialClone for Fieldless { }
1227#[automatically_derived]
1228impl ::core::clone::Clone for Fieldless {
1229 #[inline]
1230 fn clone(&self) -> Fieldless { *self }
1231}
1232#[automatically_derived]
1233impl ::core::marker::Copy for Fieldless { }
1234#[automatically_derived]
1235impl ::core::fmt::Debug for Fieldless {
1236 #[inline]
1237 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1238 ::core::fmt::Formatter::write_str(f,
1239 match self {
1240 Fieldless::A => "A",
1241 Fieldless::B => "B",
1242 Fieldless::C => "C",
1243 })
1244 }
1245}
1246#[automatically_derived]
1247impl ::core::default::Default for Fieldless {
1248 #[inline]
1249 fn default() -> Fieldless { Self::A }
1250}
1251#[automatically_derived]
1252impl ::core::hash::Hash for Fieldless {
1253 #[inline]
1254 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1255 let __self_discr = ::core::intrinsics::discriminant_value(self);
1256 ::core::hash::Hash::hash(&__self_discr, state)
1257 }
1258}
1259#[automatically_derived]
1260impl ::core::marker::StructuralPartialEq for Fieldless { }
1261#[automatically_derived]
1262impl ::core::cmp::PartialEq for Fieldless {
1263 #[inline]
1264 fn eq(&self, other: &Fieldless) -> bool {
1265 let __self_discr = ::core::intrinsics::discriminant_value(self);
1266 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1267 __self_discr == __arg1_discr
1268 }
1269}
1270#[automatically_derived]
1271impl ::core::cmp::Eq for Fieldless {
1272 #[inline]
1273 #[doc(hidden)]
1274 #[coverage(off)]
1275 fn assert_fields_are_eq(&self) {}
1276}
1277#[automatically_derived]
1278impl ::core::cmp::PartialOrd for Fieldless {
1279 #[inline]
1280 fn partial_cmp(&self, other: &Fieldless)
1281 -> ::core::option::Option<::core::cmp::Ordering> {
1282 let __self_discr = ::core::intrinsics::discriminant_value(self);
1283 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1284 ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
1285 }
1286}
1287#[automatically_derived]
1288impl ::core::cmp::Ord for Fieldless {
1289 #[inline]
1290 fn cmp(&self, other: &Fieldless) -> ::core::cmp::Ordering {
1291 let __self_discr = ::core::intrinsics::discriminant_value(self);
1292 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1293 ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
1294 }
1295}
1296
1297// An enum with multiple fieldless and fielded variants.
1298enum Mixed {
1299
1300 #[default]
1301 P,
1302 Q,
1303 R(u32),
1304 S {
1305 d1: Option<u32>,
1306 d2: Option<i32>,
1307 },
1308}
1309#[automatically_derived]
1310#[doc(hidden)]
1311unsafe impl ::core::clone::TrivialClone for Mixed { }
1312#[automatically_derived]
1313impl ::core::clone::Clone for Mixed {
1314 #[inline]
1315 fn clone(&self) -> Mixed {
1316 let _: ::core::clone::AssertParamIsClone<u32>;
1317 let _: ::core::clone::AssertParamIsClone<Option<u32>>;
1318 let _: ::core::clone::AssertParamIsClone<Option<i32>>;
1319 *self
1320 }
1321}
1322#[automatically_derived]
1323impl ::core::marker::Copy for Mixed { }
1324#[automatically_derived]
1325impl ::core::fmt::Debug for Mixed {
1326 #[inline]
1327 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1328 match self {
1329 Mixed::P => ::core::fmt::Formatter::write_str(f, "P"),
1330 Mixed::Q => ::core::fmt::Formatter::write_str(f, "Q"),
1331 Mixed::R(__self_0) =>
1332 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "R",
1333 &__self_0),
1334 Mixed::S { d1: __self_0, d2: __self_1 } =>
1335 ::core::fmt::Formatter::debug_struct_field2_finish(f, "S",
1336 "d1", __self_0, "d2", &__self_1),
1337 }
1338 }
1339}
1340#[automatically_derived]
1341impl ::core::default::Default for Mixed {
1342 #[inline]
1343 fn default() -> Mixed { Self::P }
1344}
1345#[automatically_derived]
1346impl ::core::hash::Hash for Mixed {
1347 #[inline]
1348 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1349 let __self_discr = ::core::intrinsics::discriminant_value(self);
1350 ::core::hash::Hash::hash(&__self_discr, state);
1351 match self {
1352 Mixed::R(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1353 Mixed::S { d1: __self_0, d2: __self_1 } => {
1354 ::core::hash::Hash::hash(__self_0, state);
1355 ::core::hash::Hash::hash(__self_1, state)
1356 }
1357 _ => {}
1358 }
1359 }
1360}
1361#[automatically_derived]
1362impl ::core::marker::StructuralPartialEq for Mixed { }
1363#[automatically_derived]
1364impl ::core::cmp::PartialEq for Mixed {
1365 #[inline]
1366 fn eq(&self, other: &Mixed) -> bool {
1367 let __self_discr = ::core::intrinsics::discriminant_value(self);
1368 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1369 __self_discr == __arg1_discr &&
1370 match (self, other) {
1371 (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
1372 __self_0 == __arg1_0,
1373 (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
1374 d1: __arg1_0, d2: __arg1_1 }) =>
1375 __self_0 == __arg1_0 && __self_1 == __arg1_1,
1376 _ => true,
1377 }
1378 }
1379}
1380#[automatically_derived]
1381impl ::core::cmp::Eq for Mixed {
1382 #[inline]
1383 #[doc(hidden)]
1384 #[coverage(off)]
1385 fn assert_fields_are_eq(&self) {
1386 let _: ::core::cmp::AssertParamIsEq<u32>;
1387 let _: ::core::cmp::AssertParamIsEq<Option<u32>>;
1388 let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
1389 }
1390}
1391#[automatically_derived]
1392impl ::core::cmp::PartialOrd for Mixed {
1393 #[inline]
1394 fn partial_cmp(&self, other: &Mixed)
1395 -> ::core::option::Option<::core::cmp::Ordering> {
1396 let __self_discr = ::core::intrinsics::discriminant_value(self);
1397 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1398 match (self, other) {
1399 (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
1400 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1401 (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
1402 d1: __arg1_0, d2: __arg1_1 }) =>
1403 match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
1404 {
1405 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1406 => ::core::cmp::PartialOrd::partial_cmp(__self_1, __arg1_1),
1407 cmp => cmp,
1408 },
1409 _ =>
1410 ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1411 &__arg1_discr),
1412 }
1413 }
1414}
1415#[automatically_derived]
1416impl ::core::cmp::Ord for Mixed {
1417 #[inline]
1418 fn cmp(&self, other: &Mixed) -> ::core::cmp::Ordering {
1419 let __self_discr = ::core::intrinsics::discriminant_value(self);
1420 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1421 match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
1422 ::core::cmp::Ordering::Equal =>
1423 match (self, other) {
1424 (Mixed::R(__self_0), Mixed::R(__arg1_0)) =>
1425 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1426 (Mixed::S { d1: __self_0, d2: __self_1 }, Mixed::S {
1427 d1: __arg1_0, d2: __arg1_1 }) =>
1428 match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
1429 ::core::cmp::Ordering::Equal =>
1430 ::core::cmp::Ord::cmp(__self_1, __arg1_1),
1431 cmp => cmp,
1432 },
1433 _ => ::core::cmp::Ordering::Equal,
1434 },
1435 cmp => cmp,
1436 }
1437 }
1438}
1439
1440// When comparing enum variant it is more efficient to compare scalar types before non-scalar types.
1441enum ReorderEnum {
1442 A(i32),
1443 B,
1444 C(i8),
1445 D,
1446 E,
1447 F,
1448 G(&'static mut str, *const u8, *const dyn Fn() -> ()),
1449 H,
1450 I,
1451}
1452#[automatically_derived]
1453impl ::core::marker::StructuralPartialEq for ReorderEnum { }
1454#[automatically_derived]
1455impl ::core::cmp::PartialEq for ReorderEnum {
1456 #[inline]
1457 fn eq(&self, other: &ReorderEnum) -> bool {
1458 let __self_discr = ::core::intrinsics::discriminant_value(self);
1459 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1460 __self_discr == __arg1_discr &&
1461 match (self, other) {
1462 (ReorderEnum::A(__self_0), ReorderEnum::A(__arg1_0)) =>
1463 __self_0 == __arg1_0,
1464 (ReorderEnum::C(__self_0), ReorderEnum::C(__arg1_0)) =>
1465 __self_0 == __arg1_0,
1466 (ReorderEnum::G(__self_0, __self_1, __self_2),
1467 ReorderEnum::G(__arg1_0, __arg1_1, __arg1_2)) =>
1468 __self_1 == __arg1_1 && __self_0 == __arg1_0 &&
1469 __self_2 == __arg1_2,
1470 _ => true,
1471 }
1472 }
1473}
1474#[automatically_derived]
1475impl ::core::cmp::PartialOrd for ReorderEnum {
1476 #[inline]
1477 fn partial_cmp(&self, other: &ReorderEnum)
1478 -> ::core::option::Option<::core::cmp::Ordering> {
1479 let __self_discr = ::core::intrinsics::discriminant_value(self);
1480 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1481 match ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1482 &__arg1_discr) {
1483 ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
1484 match (self, other) {
1485 (ReorderEnum::A(__self_0), ReorderEnum::A(__arg1_0)) =>
1486 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1487 (ReorderEnum::C(__self_0), ReorderEnum::C(__arg1_0)) =>
1488 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1489 (ReorderEnum::G(__self_0, __self_1, __self_2),
1490 ReorderEnum::G(__arg1_0, __arg1_1, __arg1_2)) =>
1491 match ::core::cmp::PartialOrd::partial_cmp(__self_0,
1492 __arg1_0) {
1493 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1494 =>
1495 match ::core::cmp::PartialOrd::partial_cmp(__self_1,
1496 __arg1_1) {
1497 ::core::option::Option::Some(::core::cmp::Ordering::Equal)
1498 => ::core::cmp::PartialOrd::partial_cmp(__self_2, __arg1_2),
1499 cmp => cmp,
1500 },
1501 cmp => cmp,
1502 },
1503 _ =>
1504 ::core::option::Option::Some(::core::cmp::Ordering::Equal),
1505 },
1506 cmp => cmp,
1507 }
1508 }
1509}
1510
1511// An enum with no fieldless variants. Note that `Default` cannot be derived
1512// for this enum.
1513enum Fielded { X(u32), Y(bool), Z(Option<i32>), }
1514#[automatically_derived]
1515impl ::core::clone::Clone for Fielded {
1516 #[inline]
1517 fn clone(&self) -> Fielded {
1518 match self {
1519 Fielded::X(__self_0) =>
1520 Fielded::X(::core::clone::Clone::clone(__self_0)),
1521 Fielded::Y(__self_0) =>
1522 Fielded::Y(::core::clone::Clone::clone(__self_0)),
1523 Fielded::Z(__self_0) =>
1524 Fielded::Z(::core::clone::Clone::clone(__self_0)),
1525 }
1526 }
1527}
1528#[automatically_derived]
1529impl ::core::fmt::Debug for Fielded {
1530 #[inline]
1531 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1532 match self {
1533 Fielded::X(__self_0) =>
1534 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "X",
1535 &__self_0),
1536 Fielded::Y(__self_0) =>
1537 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Y",
1538 &__self_0),
1539 Fielded::Z(__self_0) =>
1540 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Z",
1541 &__self_0),
1542 }
1543 }
1544}
1545#[automatically_derived]
1546impl ::core::hash::Hash for Fielded {
1547 #[inline]
1548 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1549 let __self_discr = ::core::intrinsics::discriminant_value(self);
1550 ::core::hash::Hash::hash(&__self_discr, state);
1551 match self {
1552 Fielded::X(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1553 Fielded::Y(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1554 Fielded::Z(__self_0) => ::core::hash::Hash::hash(__self_0, state),
1555 }
1556 }
1557}
1558#[automatically_derived]
1559impl ::core::marker::StructuralPartialEq for Fielded { }
1560#[automatically_derived]
1561impl ::core::cmp::PartialEq for Fielded {
1562 #[inline]
1563 fn eq(&self, other: &Fielded) -> bool {
1564 let __self_discr = ::core::intrinsics::discriminant_value(self);
1565 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1566 __self_discr == __arg1_discr &&
1567 match (self, other) {
1568 (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
1569 __self_0 == __arg1_0,
1570 (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
1571 __self_0 == __arg1_0,
1572 (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
1573 __self_0 == __arg1_0,
1574 _ => unsafe { ::core::intrinsics::unreachable() }
1575 }
1576 }
1577}
1578#[automatically_derived]
1579impl ::core::cmp::Eq for Fielded {
1580 #[inline]
1581 #[doc(hidden)]
1582 #[coverage(off)]
1583 fn assert_fields_are_eq(&self) {
1584 let _: ::core::cmp::AssertParamIsEq<u32>;
1585 let _: ::core::cmp::AssertParamIsEq<bool>;
1586 let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
1587 }
1588}
1589#[automatically_derived]
1590impl ::core::cmp::PartialOrd for Fielded {
1591 #[inline]
1592 fn partial_cmp(&self, other: &Fielded)
1593 -> ::core::option::Option<::core::cmp::Ordering> {
1594 let __self_discr = ::core::intrinsics::discriminant_value(self);
1595 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1596 match (self, other) {
1597 (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
1598 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1599 (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
1600 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1601 (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
1602 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1603 _ =>
1604 ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1605 &__arg1_discr),
1606 }
1607 }
1608}
1609#[automatically_derived]
1610impl ::core::cmp::Ord for Fielded {
1611 #[inline]
1612 fn cmp(&self, other: &Fielded) -> ::core::cmp::Ordering {
1613 let __self_discr = ::core::intrinsics::discriminant_value(self);
1614 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1615 match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
1616 ::core::cmp::Ordering::Equal =>
1617 match (self, other) {
1618 (Fielded::X(__self_0), Fielded::X(__arg1_0)) =>
1619 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1620 (Fielded::Y(__self_0), Fielded::Y(__arg1_0)) =>
1621 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1622 (Fielded::Z(__self_0), Fielded::Z(__arg1_0)) =>
1623 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1624 _ => unsafe { ::core::intrinsics::unreachable() }
1625 },
1626 cmp => cmp,
1627 }
1628 }
1629}
1630
1631// A generic enum. Note that `Default` cannot be derived for this enum.
1632enum EnumGeneric<T, U> { One(T), Two(U), }
1633#[automatically_derived]
1634impl<T: ::core::clone::Clone, U: ::core::clone::Clone> ::core::clone::Clone
1635 for EnumGeneric<T, U> {
1636 #[inline]
1637 fn clone(&self) -> EnumGeneric<T, U> {
1638 match self {
1639 EnumGeneric::One(__self_0) =>
1640 EnumGeneric::One(::core::clone::Clone::clone(__self_0)),
1641 EnumGeneric::Two(__self_0) =>
1642 EnumGeneric::Two(::core::clone::Clone::clone(__self_0)),
1643 }
1644 }
1645}
1646#[automatically_derived]
1647impl<T: ::core::marker::Copy, U: ::core::marker::Copy> ::core::marker::Copy
1648 for EnumGeneric<T, U> {
1649}
1650#[automatically_derived]
1651impl<T: ::core::fmt::Debug, U: ::core::fmt::Debug> ::core::fmt::Debug for
1652 EnumGeneric<T, U> {
1653 #[inline]
1654 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1655 match self {
1656 EnumGeneric::One(__self_0) =>
1657 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "One",
1658 &__self_0),
1659 EnumGeneric::Two(__self_0) =>
1660 ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Two",
1661 &__self_0),
1662 }
1663 }
1664}
1665#[automatically_derived]
1666impl<T: ::core::hash::Hash, U: ::core::hash::Hash> ::core::hash::Hash for
1667 EnumGeneric<T, U> {
1668 #[inline]
1669 fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
1670 let __self_discr = ::core::intrinsics::discriminant_value(self);
1671 ::core::hash::Hash::hash(&__self_discr, state);
1672 match self {
1673 EnumGeneric::One(__self_0) =>
1674 ::core::hash::Hash::hash(__self_0, state),
1675 EnumGeneric::Two(__self_0) =>
1676 ::core::hash::Hash::hash(__self_0, state),
1677 }
1678 }
1679}
1680#[automatically_derived]
1681impl<T, U> ::core::marker::StructuralPartialEq for EnumGeneric<T, U> { }
1682#[automatically_derived]
1683impl<T: ::core::cmp::PartialEq, U: ::core::cmp::PartialEq>
1684 ::core::cmp::PartialEq for EnumGeneric<T, U> {
1685 #[inline]
1686 fn eq(&self, other: &EnumGeneric<T, U>) -> bool {
1687 let __self_discr = ::core::intrinsics::discriminant_value(self);
1688 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1689 __self_discr == __arg1_discr &&
1690 match (self, other) {
1691 (EnumGeneric::One(__self_0), EnumGeneric::One(__arg1_0)) =>
1692 __self_0 == __arg1_0,
1693 (EnumGeneric::Two(__self_0), EnumGeneric::Two(__arg1_0)) =>
1694 __self_0 == __arg1_0,
1695 _ => unsafe { ::core::intrinsics::unreachable() }
1696 }
1697 }
1698}
1699#[automatically_derived]
1700impl<T: ::core::cmp::Eq, U: ::core::cmp::Eq> ::core::cmp::Eq for
1701 EnumGeneric<T, U> {
1702 #[inline]
1703 #[doc(hidden)]
1704 #[coverage(off)]
1705 fn assert_fields_are_eq(&self) {
1706 let _: ::core::cmp::AssertParamIsEq<T>;
1707 let _: ::core::cmp::AssertParamIsEq<U>;
1708 }
1709}
1710#[automatically_derived]
1711impl<T: ::core::cmp::PartialOrd, U: ::core::cmp::PartialOrd>
1712 ::core::cmp::PartialOrd for EnumGeneric<T, U> {
1713 #[inline]
1714 fn partial_cmp(&self, other: &EnumGeneric<T, U>)
1715 -> ::core::option::Option<::core::cmp::Ordering> {
1716 let __self_discr = ::core::intrinsics::discriminant_value(self);
1717 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1718 match (self, other) {
1719 (EnumGeneric::One(__self_0), EnumGeneric::One(__arg1_0)) =>
1720 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1721 (EnumGeneric::Two(__self_0), EnumGeneric::Two(__arg1_0)) =>
1722 ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
1723 _ =>
1724 ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
1725 &__arg1_discr),
1726 }
1727 }
1728}
1729#[automatically_derived]
1730impl<T: ::core::cmp::Ord, U: ::core::cmp::Ord> ::core::cmp::Ord for
1731 EnumGeneric<T, U> {
1732 #[inline]
1733 fn cmp(&self, other: &EnumGeneric<T, U>) -> ::core::cmp::Ordering {
1734 let __self_discr = ::core::intrinsics::discriminant_value(self);
1735 let __arg1_discr = ::core::intrinsics::discriminant_value(other);
1736 match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
1737 ::core::cmp::Ordering::Equal =>
1738 match (self, other) {
1739 (EnumGeneric::One(__self_0), EnumGeneric::One(__arg1_0)) =>
1740 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1741 (EnumGeneric::Two(__self_0), EnumGeneric::Two(__arg1_0)) =>
1742 ::core::cmp::Ord::cmp(__self_0, __arg1_0),
1743 _ => unsafe { ::core::intrinsics::unreachable() }
1744 },
1745 cmp => cmp,
1746 }
1747 }
1748}
1749
1750// An enum that has variant, which does't implement `Copy`.
1751enum NonCopyEnum {
1752
1753 // The `dyn NonCopyTrait` implements `PartialEq`, but it doesn't require `Copy`.
1754 // So we cannot generate `PartialEq` with dereference.
1755 NonCopyField(Box<dyn NonCopyTrait>),
1756}
1757#[automatically_derived]
1758impl ::core::marker::StructuralPartialEq for NonCopyEnum { }
1759#[automatically_derived]
1760impl ::core::cmp::PartialEq for NonCopyEnum {
1761 #[inline]
1762 fn eq(&self, other: &NonCopyEnum) -> bool {
1763 match (self, other) {
1764 (NonCopyEnum::NonCopyField(__self_0),
1765 NonCopyEnum::NonCopyField(__arg1_0)) => __self_0 == __arg1_0,
1766 }
1767 }
1768}
1769trait NonCopyTrait {}
1770impl PartialEq for dyn NonCopyTrait {
1771 fn eq(&self, _other: &Self) -> bool { true }
1772}
1773
1774// A union. Most builtin traits are not derivable for unions.
1775pub union Union {
1776 pub b: bool,
1777 pub u: u32,
1778 pub i: i32,
1779}
1780#[automatically_derived]
1781#[doc(hidden)]
1782unsafe impl ::core::clone::TrivialClone for Union { }
1783#[automatically_derived]
1784impl ::core::clone::Clone for Union {
1785 #[inline]
1786 fn clone(&self) -> Union {
1787 let _: ::core::clone::AssertParamIsCopy<Self>;
1788 *self
1789 }
1790}
1791#[automatically_derived]
1792impl ::core::marker::Copy for Union { }
1793
1794struct FooCopyClone(i32);
1795#[automatically_derived]
1796impl ::core::marker::Copy for FooCopyClone { }
1797#[automatically_derived]
1798#[doc(hidden)]
1799unsafe impl ::core::clone::TrivialClone for FooCopyClone { }
1800#[automatically_derived]
1801impl ::core::clone::Clone for FooCopyClone {
1802 #[inline]
1803 fn clone(&self) -> FooCopyClone {
1804 let _: ::core::clone::AssertParamIsClone<i32>;
1805 *self
1806 }
1807}
1808
1809struct FooCloneCopy(i32);
1810#[automatically_derived]
1811#[doc(hidden)]
1812unsafe impl ::core::clone::TrivialClone for FooCloneCopy { }
1813#[automatically_derived]
1814impl ::core::clone::Clone for FooCloneCopy {
1815 #[inline]
1816 fn clone(&self) -> FooCloneCopy {
1817 let _: ::core::clone::AssertParamIsClone<i32>;
1818 *self
1819 }
1820}
1821#[automatically_derived]
1822impl ::core::marker::Copy for FooCloneCopy { }
1823
1824struct FooCopyAndClone(i32);
1825#[automatically_derived]
1826#[doc(hidden)]
1827unsafe impl ::core::clone::TrivialClone for FooCopyAndClone { }
1828#[automatically_derived]
1829impl ::core::clone::Clone for FooCopyAndClone {
1830 #[inline]
1831 fn clone(&self) -> FooCopyAndClone {
1832 let _: ::core::clone::AssertParamIsClone<i32>;
1833 *self
1834 }
1835}
1836#[automatically_derived]
1837impl ::core::marker::Copy for FooCopyAndClone { }
1838
1839// FIXME(#124794): the previous three structs all have a trivial `Copy`-aware
1840// `clone`. But this one doesn't because when the `clone` is generated the
1841// `derive(Copy)` hasn't yet been seen.
1842struct FooCloneAndCopy(i32);
1843#[automatically_derived]
1844impl ::core::marker::Copy for FooCloneAndCopy { }
1845#[automatically_derived]
1846impl ::core::clone::Clone for FooCloneAndCopy {
1847 #[inline]
1848 fn clone(&self) -> FooCloneAndCopy {
1849 FooCloneAndCopy(::core::clone::Clone::clone(&self.0))
1850 }
1851}
tests/ui/deriving/deriving-associated-types.rs deleted-199
......@@ -1,199 +0,0 @@
1//@ run-pass
2pub trait DeclaredTrait {
3 type Type;
4}
5
6impl DeclaredTrait for i32 {
7 type Type = i32;
8}
9
10pub trait WhereTrait {
11 type Type;
12}
13
14impl WhereTrait for i32 {
15 type Type = i32;
16}
17
18// Make sure we don't add a bound that just shares a name with an associated
19// type.
20pub mod module {
21 pub type Type = i32;
22}
23
24#[derive(PartialEq, Debug)]
25struct PrivateStruct<T>(T);
26
27#[derive(PartialEq, Debug)]
28struct TupleStruct<A, B: DeclaredTrait, C>(
29 module::Type,
30 Option<module::Type>,
31 A,
32 PrivateStruct<A>,
33 B,
34 B::Type,
35 Option<B::Type>,
36 <B as DeclaredTrait>::Type,
37 Option<<B as DeclaredTrait>::Type>,
38 C,
39 C::Type,
40 Option<C::Type>,
41 <C as WhereTrait>::Type,
42 Option<<C as WhereTrait>::Type>,
43 <i32 as DeclaredTrait>::Type,
44) where C: WhereTrait;
45
46#[derive(PartialEq, Debug)]
47pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait {
48 m1: module::Type,
49 m2: Option<module::Type>,
50 a1: A,
51 a2: PrivateStruct<A>,
52 b: B,
53 b1: B::Type,
54 b2: Option<B::Type>,
55 b3: <B as DeclaredTrait>::Type,
56 b4: Option<<B as DeclaredTrait>::Type>,
57 c: C,
58 c1: C::Type,
59 c2: Option<C::Type>,
60 c3: <C as WhereTrait>::Type,
61 c4: Option<<C as WhereTrait>::Type>,
62 d: <i32 as DeclaredTrait>::Type,
63}
64
65#[derive(PartialEq, Debug)]
66enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait {
67 Unit,
68 Seq(
69 module::Type,
70 Option<module::Type>,
71 A,
72 PrivateStruct<A>,
73 B,
74 B::Type,
75 Option<B::Type>,
76 <B as DeclaredTrait>::Type,
77 Option<<B as DeclaredTrait>::Type>,
78 C,
79 C::Type,
80 Option<C::Type>,
81 <C as WhereTrait>::Type,
82 Option<<C as WhereTrait>::Type>,
83 <i32 as DeclaredTrait>::Type,
84 ),
85 Map {
86 m1: module::Type,
87 m2: Option<module::Type>,
88 a1: A,
89 a2: PrivateStruct<A>,
90 b: B,
91 b1: B::Type,
92 b2: Option<B::Type>,
93 b3: <B as DeclaredTrait>::Type,
94 b4: Option<<B as DeclaredTrait>::Type>,
95 c: C,
96 c1: C::Type,
97 c2: Option<C::Type>,
98 c3: <C as WhereTrait>::Type,
99 c4: Option<<C as WhereTrait>::Type>,
100 d: <i32 as DeclaredTrait>::Type,
101 },
102}
103
104fn main() {
105 let e: TupleStruct<
106 i32,
107 i32,
108 i32,
109 > = TupleStruct(
110 0,
111 None,
112 0,
113 PrivateStruct(0),
114 0,
115 0,
116 None,
117 0,
118 None,
119 0,
120 0,
121 None,
122 0,
123 None,
124 0,
125 );
126 assert_eq!(e, e);
127
128 let e: Struct<
129 i32,
130 i32,
131 i32,
132 > = Struct {
133 m1: 0,
134 m2: None,
135 a1: 0,
136 a2: PrivateStruct(0),
137 b: 0,
138 b1: 0,
139 b2: None,
140 b3: 0,
141 b4: None,
142 c: 0,
143 c1: 0,
144 c2: None,
145 c3: 0,
146 c4: None,
147 d: 0,
148 };
149 assert_eq!(e, e);
150
151 let e = Enum::Unit::<i32, i32, i32>;
152 assert_eq!(e, e);
153
154 let e: Enum<
155 i32,
156 i32,
157 i32,
158 > = Enum::Seq(
159 0,
160 None,
161 0,
162 PrivateStruct(0),
163 0,
164 0,
165 None,
166 0,
167 None,
168 0,
169 0,
170 None,
171 0,
172 None,
173 0,
174 );
175 assert_eq!(e, e);
176
177 let e: Enum<
178 i32,
179 i32,
180 i32,
181 > = Enum::Map {
182 m1: 0,
183 m2: None,
184 a1: 0,
185 a2: PrivateStruct(0),
186 b: 0,
187 b1: 0,
188 b2: None,
189 b3: 0,
190 b4: None,
191 c: 0,
192 c1: 0,
193 c2: None,
194 c3: 0,
195 c4: None,
196 d: 0,
197 };
198 assert_eq!(e, e);
199}
tests/ui/deriving/deriving-cmp-generic-enum.rs deleted-44
......@@ -1,44 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3enum E<T> {
4 E0,
5 E1(T),
6 E2(T,T)
7}
8
9pub fn main() {
10 let e0 = E::E0;
11 let e11 = E::E1(1);
12 let e12 = E::E1(2);
13 let e21 = E::E2(1, 1);
14 let e22 = E::E2(1, 2);
15
16 // in order for both PartialOrd and Ord
17 let es = [e0, e11, e12, e21, e22];
18
19 for (i, e1) in es.iter().enumerate() {
20 for (j, e2) in es.iter().enumerate() {
21 let ord = i.cmp(&j);
22
23 let eq = i == j;
24 let lt = i < j;
25 let le = i <= j;
26 let gt = i > j;
27 let ge = i >= j;
28
29 // PartialEq
30 assert_eq!(*e1 == *e2, eq);
31 assert_eq!(*e1 != *e2, !eq);
32
33 // PartialOrd
34 assert_eq!(*e1 < *e2, lt);
35 assert_eq!(*e1 > *e2, gt);
36
37 assert_eq!(*e1 <= *e2, le);
38 assert_eq!(*e1 >= *e2, ge);
39
40 // Ord
41 assert_eq!(e1.cmp(e2), ord);
42 }
43 }
44}
tests/ui/deriving/deriving-cmp-generic-struct-enum.rs deleted-48
......@@ -1,48 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3enum ES<T> {
4 ES1 { x: T },
5 ES2 { x: T, y: T }
6}
7
8
9pub fn main() {
10 let (es11, es12, es21, es22) = (ES::ES1 {
11 x: 1
12 }, ES::ES1 {
13 x: 2
14 }, ES::ES2 {
15 x: 1,
16 y: 1
17 }, ES::ES2 {
18 x: 1,
19 y: 2
20 });
21
22 // in order for both PartialOrd and Ord
23 let ess = [es11, es12, es21, es22];
24
25 for (i, es1) in ess.iter().enumerate() {
26 for (j, es2) in ess.iter().enumerate() {
27 let ord = i.cmp(&j);
28
29 let eq = i == j;
30 let (lt, le) = (i < j, i <= j);
31 let (gt, ge) = (i > j, i >= j);
32
33 // PartialEq
34 assert_eq!(*es1 == *es2, eq);
35 assert_eq!(*es1 != *es2, !eq);
36
37 // PartialOrd
38 assert_eq!(*es1 < *es2, lt);
39 assert_eq!(*es1 > *es2, gt);
40
41 assert_eq!(*es1 <= *es2, le);
42 assert_eq!(*es1 >= *es2, ge);
43
44 // Ord
45 assert_eq!(es1.cmp(es2), ord);
46 }
47 }
48}
tests/ui/deriving/deriving-cmp-generic-struct.rs deleted-40
......@@ -1,40 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3struct S<T> {
4 x: T,
5 y: T
6}
7
8pub fn main() {
9 let s1 = S {x: 1, y: 1};
10 let s2 = S {x: 1, y: 2};
11
12 // in order for both PartialOrd and Ord
13 let ss = [s1, s2];
14
15 for (i, s1) in ss.iter().enumerate() {
16 for (j, s2) in ss.iter().enumerate() {
17 let ord = i.cmp(&j);
18
19 let eq = i == j;
20 let lt = i < j;
21 let le = i <= j;
22 let gt = i > j;
23 let ge = i >= j;
24
25 // PartialEq
26 assert_eq!(*s1 == *s2, eq);
27 assert_eq!(*s1 != *s2, !eq);
28
29 // PartialOrd
30 assert_eq!(*s1 < *s2, lt);
31 assert_eq!(*s1 > *s2, gt);
32
33 assert_eq!(*s1 <= *s2, le);
34 assert_eq!(*s1 >= *s2, ge);
35
36 // Ord
37 assert_eq!(s1.cmp(s2), ord);
38 }
39 }
40}
tests/ui/deriving/deriving-cmp-generic-tuple-struct.rs deleted-38
......@@ -1,38 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Eq, PartialOrd, Ord)]
3struct TS<T>(T,T);
4
5
6pub fn main() {
7 let ts1 = TS(1, 1);
8 let ts2 = TS(1, 2);
9
10 // in order for both PartialOrd and Ord
11 let tss = [ts1, ts2];
12
13 for (i, ts1) in tss.iter().enumerate() {
14 for (j, ts2) in tss.iter().enumerate() {
15 let ord = i.cmp(&j);
16
17 let eq = i == j;
18 let lt = i < j;
19 let le = i <= j;
20 let gt = i > j;
21 let ge = i >= j;
22
23 // PartialEq
24 assert_eq!(*ts1 == *ts2, eq);
25 assert_eq!(*ts1 != *ts2, !eq);
26
27 // PartialOrd
28 assert_eq!(*ts1 < *ts2, lt);
29 assert_eq!(*ts1 > *ts2, gt);
30
31 assert_eq!(*ts1 <= *ts2, le);
32 assert_eq!(*ts1 >= *ts2, ge);
33
34 // Ord
35 assert_eq!(ts1.cmp(ts2), ord);
36 }
37 }
38}
tests/ui/deriving/deriving-cmp-shortcircuit.rs deleted-37
......@@ -1,37 +0,0 @@
1//@ run-pass
2// check that the derived impls for the comparison traits shortcircuit
3// where possible, by having a type that panics when compared as the
4// second element, so this passes iff the instances shortcircuit.
5
6
7use std::cmp::Ordering;
8
9pub struct FailCmp;
10impl PartialEq for FailCmp {
11 fn eq(&self, _: &FailCmp) -> bool { panic!("eq") }
12}
13
14impl PartialOrd for FailCmp {
15 fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { panic!("partial_cmp") }
16}
17
18impl Eq for FailCmp {}
19
20impl Ord for FailCmp {
21 fn cmp(&self, _: &FailCmp) -> Ordering { panic!("cmp") }
22}
23
24#[derive(PartialEq,PartialOrd,Eq,Ord)]
25struct ShortCircuit {
26 x: isize,
27 y: FailCmp
28}
29
30pub fn main() {
31 let a = ShortCircuit { x: 1, y: FailCmp };
32 let b = ShortCircuit { x: 2, y: FailCmp };
33
34 assert!(a != b);
35 assert!(a < b);
36 assert_eq!(a.cmp(&b), ::std::cmp::Ordering::Less);
37}
tests/ui/deriving/deriving-coerce-pointee-expanded.rs deleted-29
......@@ -1,29 +0,0 @@
1//@ check-pass
2//@ compile-flags: -Zunpretty=expanded
3//@ edition: 2015
4#![feature(derive_coerce_pointee)]
5use std::marker::CoercePointee;
6
7pub trait MyTrait<T: ?Sized> {}
8
9#[derive(CoercePointee)]
10#[repr(transparent)]
11struct MyPointer<'a, #[pointee] T: ?Sized> {
12 ptr: &'a T,
13}
14
15#[derive(core::marker::CoercePointee)]
16#[repr(transparent)]
17pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>, X: MyTrait<T> = ()>
18where
19 Y: MyTrait<T>,
20{
21 data: &'a mut T,
22 x: core::marker::PhantomData<X>,
23}
24
25#[derive(CoercePointee)]
26#[repr(transparent)]
27struct MyPointerWithoutPointee<'a, T: ?Sized> {
28 ptr: &'a T,
29}
tests/ui/deriving/deriving-coerce-pointee-expanded.stdout deleted-72
......@@ -1,72 +0,0 @@
1#![feature(prelude_import)]
2#![no_std]
3//@ check-pass
4//@ compile-flags: -Zunpretty=expanded
5//@ edition: 2015
6#![feature(derive_coerce_pointee)]
7extern crate std;
8#[prelude_import]
9use ::std::prelude::rust_2015::*;
10use std::marker::CoercePointee;
11
12pub trait MyTrait<T: ?Sized> {}
13
14#[repr(transparent)]
15struct MyPointer<'a, #[pointee] T: ?Sized> {
16 ptr: &'a T,
17}
18#[automatically_derived]
19impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
20 MyPointer<'a, T> {
21}
22#[automatically_derived]
23impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
24 ::core::ops::DispatchFromDyn<MyPointer<'a, __S>> for MyPointer<'a, T> {
25}
26#[automatically_derived]
27impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
28 ::core::ops::CoerceUnsized<MyPointer<'a, __S>> for MyPointer<'a, T> {
29}
30
31#[repr(transparent)]
32pub struct MyPointer2<'a, Y, Z: MyTrait<T>, #[pointee] T: ?Sized + MyTrait<T>,
33 X: MyTrait<T> = ()> where Y: MyTrait<T> {
34 data: &'a mut T,
35 x: core::marker::PhantomData<X>,
36}
37#[automatically_derived]
38impl<'a, Y, Z: MyTrait<T>, T: ?Sized + MyTrait<T>, X: MyTrait<T>>
39 ::core::marker::CoercePointeeValidated for MyPointer2<'a, Y, Z, T, X>
40 where Y: MyTrait<T> {
41}
42#[automatically_derived]
43impl<'a, Y, Z: MyTrait<T> + MyTrait<__S>, T: ?Sized + MyTrait<T> +
44 ::core::marker::Unsize<__S>, __S: ?Sized + MyTrait<__S>, X: MyTrait<T> +
45 MyTrait<__S>> ::core::ops::DispatchFromDyn<MyPointer2<'a, Y, Z, __S, X>>
46 for MyPointer2<'a, Y, Z, T, X> where Y: MyTrait<T>, Y: MyTrait<__S> {
47}
48#[automatically_derived]
49impl<'a, Y, Z: MyTrait<T> + MyTrait<__S>, T: ?Sized + MyTrait<T> +
50 ::core::marker::Unsize<__S>, __S: ?Sized + MyTrait<__S>, X: MyTrait<T> +
51 MyTrait<__S>> ::core::ops::CoerceUnsized<MyPointer2<'a, Y, Z, __S, X>> for
52 MyPointer2<'a, Y, Z, T, X> where Y: MyTrait<T>, Y: MyTrait<__S> {
53}
54
55#[repr(transparent)]
56struct MyPointerWithoutPointee<'a, T: ?Sized> {
57 ptr: &'a T,
58}
59#[automatically_derived]
60impl<'a, T: ?Sized> ::core::marker::CoercePointeeValidated for
61 MyPointerWithoutPointee<'a, T> {
62}
63#[automatically_derived]
64impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
65 ::core::ops::DispatchFromDyn<MyPointerWithoutPointee<'a, __S>> for
66 MyPointerWithoutPointee<'a, T> {
67}
68#[automatically_derived]
69impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
70 ::core::ops::CoerceUnsized<MyPointerWithoutPointee<'a, __S>> for
71 MyPointerWithoutPointee<'a, T> {
72}
tests/ui/deriving/deriving-coerce-pointee-neg.rs deleted-168
......@@ -1,168 +0,0 @@
1//@ proc-macro: malicious-macro.rs
2#![feature(derive_coerce_pointee, arbitrary_self_types)]
3
4extern crate core;
5extern crate malicious_macro;
6
7use std::marker::CoercePointee;
8
9#[derive(CoercePointee)]
10//~^ ERROR: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
11enum NotStruct<'a, T: ?Sized> {
12 Variant(&'a T),
13}
14
15#[derive(CoercePointee)]
16//~^ ERROR: `CoercePointee` can only be derived on `struct`s with at least one field
17#[repr(transparent)]
18struct NoField<'a, #[pointee] T: ?Sized> {}
19//~^ ERROR: lifetime parameter `'a` is never used
20//~| ERROR: type parameter `T` is never used
21
22#[derive(CoercePointee)]
23//~^ ERROR: `CoercePointee` can only be derived on `struct`s with at least one field
24#[repr(transparent)]
25struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
26//~^ ERROR: lifetime parameter `'a` is never used
27//~| ERROR: type parameter `T` is never used
28
29#[derive(CoercePointee)]
30//~^ ERROR: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
31#[repr(transparent)]
32struct NoGeneric<'a>(&'a u8);
33
34#[derive(CoercePointee)]
35//~^ ERROR: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
36#[repr(transparent)]
37struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
38 a: (&'a T1, &'a T2),
39}
40
41#[derive(CoercePointee)]
42#[repr(transparent)]
43struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
44//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
45
46#[derive(CoercePointee)]
47struct NotTransparent<'a, #[pointee] T: ?Sized> {
48 //~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
49 ptr: &'a T,
50}
51
52#[derive(CoercePointee)]
53#[repr(transparent)]
54struct NoMaybeSized<'a, #[pointee] T> {
55 //~^ ERROR: `derive(CoercePointee)` requires `T` to be marked `?Sized`
56 ptr: &'a T,
57}
58
59#[derive(CoercePointee)]
60#[repr(transparent)]
61struct PointeeOnField<'a, #[pointee] T: ?Sized> {
62 #[pointee]
63 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
64 ptr: &'a T,
65}
66
67#[derive(CoercePointee)]
68#[repr(transparent)]
69struct PointeeInTypeConstBlock<
70 'a,
71 T: ?Sized = [u32; const {
72 struct UhOh<#[pointee] T>(T);
73 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
74 10
75 }],
76> {
77 ptr: &'a T,
78}
79
80#[derive(CoercePointee)]
81#[repr(transparent)]
82struct PointeeInConstConstBlock<
83 'a,
84 T: ?Sized,
85 const V: u32 = {
86 struct UhOh<#[pointee] T>(T);
87 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
88 10
89 },
90> {
91 ptr: &'a T,
92}
93
94#[derive(CoercePointee)]
95#[repr(transparent)]
96struct PointeeInAnotherTypeConstBlock<'a, #[pointee] T: ?Sized> {
97 ptr: PointeeInConstConstBlock<
98 'a,
99 T,
100 {
101 struct UhOh<#[pointee] T>(T);
102 //~^ ERROR: the `#[pointee]` attribute may only be used on generic parameters
103 0
104 },
105 >,
106}
107
108// However, reordering attributes should work nevertheless.
109#[repr(transparent)]
110#[derive(CoercePointee)]
111struct ThisIsAPossibleCoercePointee<'a, #[pointee] T: ?Sized> {
112 ptr: &'a T,
113}
114
115// Also, these paths to Sized should work
116#[derive(CoercePointee)]
117#[repr(transparent)]
118struct StdSized<'a, #[pointee] T: ?std::marker::Sized> {
119 ptr: &'a T,
120}
121#[derive(CoercePointee)]
122#[repr(transparent)]
123struct CoreSized<'a, #[pointee] T: ?core::marker::Sized> {
124 ptr: &'a T,
125}
126#[derive(CoercePointee)]
127#[repr(transparent)]
128struct GlobalStdSized<'a, #[pointee] T: ?::std::marker::Sized> {
129 ptr: &'a T,
130}
131#[derive(CoercePointee)]
132#[repr(transparent)]
133struct GlobalCoreSized<'a, #[pointee] T: ?::core::marker::Sized> {
134 ptr: &'a T,
135}
136
137#[derive(CoercePointee)]
138#[malicious_macro::norepr]
139#[repr(transparent)]
140struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
141 //~^ ERROR: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout [E0802]
142 ptr: &'a T,
143}
144
145#[repr(transparent)]
146#[derive(CoercePointee)]
147//~^ ERROR for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
148struct RcWithId<T: ?Sized> {
149 inner: std::rc::Rc<(i32, Box<T>)>,
150}
151
152#[repr(transparent)]
153#[derive(CoercePointee)]
154//~^ ERROR implementing `CoerceUnsized` does not allow multiple fields to be coerced
155struct MoreThanOneField<T: ?Sized> {
156 //~^ ERROR transparent struct needs at most one field with non-trivial size or alignment, but has 2
157 inner1: Box<T>,
158 inner2: Box<T>,
159}
160
161struct NotCoercePointeeData<T: ?Sized>(T);
162
163#[repr(transparent)]
164#[derive(CoercePointee)]
165//~^ ERROR for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
166struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
167
168fn main() {}
tests/ui/deriving/deriving-coerce-pointee-neg.stderr deleted-157
......@@ -1,157 +0,0 @@
1error[E0802]: `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
2 --> $DIR/deriving-coerce-pointee-neg.rs:9:10
3 |
4LL | #[derive(CoercePointee)]
5 | ^^^^^^^^^^^^^
6
7error[E0802]: `CoercePointee` can only be derived on `struct`s with at least one field
8 --> $DIR/deriving-coerce-pointee-neg.rs:15:10
9 |
10LL | #[derive(CoercePointee)]
11 | ^^^^^^^^^^^^^
12
13error[E0802]: `CoercePointee` can only be derived on `struct`s with at least one field
14 --> $DIR/deriving-coerce-pointee-neg.rs:22:10
15 |
16LL | #[derive(CoercePointee)]
17 | ^^^^^^^^^^^^^
18
19error[E0802]: `CoercePointee` can only be derived on `struct`s that are generic over at least one type
20 --> $DIR/deriving-coerce-pointee-neg.rs:29:10
21 |
22LL | #[derive(CoercePointee)]
23 | ^^^^^^^^^^^^^
24
25error[E0802]: exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
26 --> $DIR/deriving-coerce-pointee-neg.rs:34:10
27 |
28LL | #[derive(CoercePointee)]
29 | ^^^^^^^^^^^^^
30
31error[E0802]: only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
32 --> $DIR/deriving-coerce-pointee-neg.rs:43:39
33 |
34LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
35 | ^ - here another type parameter is marked as `#[pointee]`
36
37error[E0802]: `derive(CoercePointee)` requires `T` to be marked `?Sized`
38 --> $DIR/deriving-coerce-pointee-neg.rs:54:36
39 |
40LL | struct NoMaybeSized<'a, #[pointee] T> {
41 | ^
42
43error: the `#[pointee]` attribute may only be used on generic parameters
44 --> $DIR/deriving-coerce-pointee-neg.rs:62:5
45 |
46LL | #[pointee]
47 | ^^^^^^^^^^
48
49error: the `#[pointee]` attribute may only be used on generic parameters
50 --> $DIR/deriving-coerce-pointee-neg.rs:72:33
51 |
52LL | struct UhOh<#[pointee] T>(T);
53 | ^^^^^^^^^^
54
55error: the `#[pointee]` attribute may only be used on generic parameters
56 --> $DIR/deriving-coerce-pointee-neg.rs:86:21
57 |
58LL | struct UhOh<#[pointee] T>(T);
59 | ^^^^^^^^^^
60
61error: the `#[pointee]` attribute may only be used on generic parameters
62 --> $DIR/deriving-coerce-pointee-neg.rs:101:25
63 |
64LL | struct UhOh<#[pointee] T>(T);
65 | ^^^^^^^^^^
66
67error[E0392]: lifetime parameter `'a` is never used
68 --> $DIR/deriving-coerce-pointee-neg.rs:18:16
69 |
70LL | struct NoField<'a, #[pointee] T: ?Sized> {}
71 | ^^ unused lifetime parameter
72 |
73 = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
74
75error[E0392]: type parameter `T` is never used
76 --> $DIR/deriving-coerce-pointee-neg.rs:18:31
77 |
78LL | struct NoField<'a, #[pointee] T: ?Sized> {}
79 | ^ unused type parameter
80 |
81 = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
82
83error[E0392]: lifetime parameter `'a` is never used
84 --> $DIR/deriving-coerce-pointee-neg.rs:25:20
85 |
86LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
87 | ^^ unused lifetime parameter
88 |
89 = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
90
91error[E0392]: type parameter `T` is never used
92 --> $DIR/deriving-coerce-pointee-neg.rs:25:35
93 |
94LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
95 | ^ unused type parameter
96 |
97 = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
98
99error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
100 --> $DIR/deriving-coerce-pointee-neg.rs:47:1
101 |
102LL | struct NotTransparent<'a, #[pointee] T: ?Sized> {
103 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104
105error[E0802]: `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
106 --> $DIR/deriving-coerce-pointee-neg.rs:140:1
107 |
108LL | struct TryToWipeRepr<'a, #[pointee] T: ?Sized> {
109 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
110
111error: for `RcWithId<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `Rc<(i32, Box<T>)>`
112 --> $DIR/deriving-coerce-pointee-neg.rs:146:10
113 |
114LL | #[derive(CoercePointee)]
115 | ^^^^^^^^^^^^^
116...
117LL | inner: std::rc::Rc<(i32, Box<T>)>,
118 | --------------------------------- `Rc<(i32, Box<T>)>` must be a pointer, reference, or smart pointer that is allowed to be unsized
119
120error[E0375]: implementing `CoerceUnsized` does not allow multiple fields to be coerced
121 --> $DIR/deriving-coerce-pointee-neg.rs:153:10
122 |
123LL | #[derive(CoercePointee)]
124 | ^^^^^^^^^^^^^
125 |
126note: the trait `CoerceUnsized` may only be implemented when a single field is being coerced
127 --> $DIR/deriving-coerce-pointee-neg.rs:157:5
128 |
129LL | inner1: Box<T>,
130 | ^^^^^^^^^^^^^^
131LL | inner2: Box<T>,
132 | ^^^^^^^^^^^^^^
133
134error: for `UsingNonCoercePointeeData<T>` to have a valid implementation of `CoerceUnsized`, it must be possible to coerce the field of type `NotCoercePointeeData<T>`
135 --> $DIR/deriving-coerce-pointee-neg.rs:164:10
136 |
137LL | #[derive(CoercePointee)]
138 | ^^^^^^^^^^^^^
139LL |
140LL | struct UsingNonCoercePointeeData<T: ?Sized>(NotCoercePointeeData<T>);
141 | ----------------------- `NotCoercePointeeData<T>` must be a pointer, reference, or smart pointer that is allowed to be unsized
142
143error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
144 --> $DIR/deriving-coerce-pointee-neg.rs:155:1
145 |
146LL | struct MoreThanOneField<T: ?Sized> {
147 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
148LL |
149LL | inner1: Box<T>,
150 | -------------- this field has non-zero size or requires alignment
151LL | inner2: Box<T>,
152 | -------------- this field has non-zero size or requires alignment
153
154error: aborting due to 21 previous errors
155
156Some errors have detailed explanations: E0375, E0392, E0690, E0802.
157For more information about an error, try `rustc --explain E0375`.
tests/ui/deriving/deriving-coerce-pointee.rs deleted-56
......@@ -1,56 +0,0 @@
1//@ run-pass
2#![feature(derive_coerce_pointee, arbitrary_self_types)]
3
4use std::marker::CoercePointee;
5
6#[derive(CoercePointee)]
7#[repr(transparent)]
8struct MyPointer<'a, #[pointee] T: ?Sized> {
9 ptr: &'a T,
10}
11
12impl<T: ?Sized> Copy for MyPointer<'_, T> {}
13impl<T: ?Sized> Clone for MyPointer<'_, T> {
14 fn clone(&self) -> Self {
15 Self { ptr: self.ptr }
16 }
17}
18
19impl<'a, T: ?Sized> core::ops::Deref for MyPointer<'a, T> {
20 type Target = T;
21 fn deref(&self) -> &'a T {
22 self.ptr
23 }
24}
25
26struct MyValue(u32);
27impl MyValue {
28 fn through_pointer(self: MyPointer<'_, Self>) -> u32 {
29 self.ptr.0
30 }
31}
32
33trait MyTrait {
34 fn through_trait(&self) -> u32;
35 fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32;
36}
37
38impl MyTrait for MyValue {
39 fn through_trait(&self) -> u32 {
40 self.0
41 }
42
43 fn through_trait_and_pointer(self: MyPointer<'_, Self>) -> u32 {
44 self.ptr.0
45 }
46}
47
48pub fn main() {
49 let v = MyValue(10);
50 let ptr = MyPointer { ptr: &v };
51 assert_eq!(v.0, ptr.through_pointer());
52 assert_eq!(v.0, ptr.through_pointer());
53 let dptr = ptr as MyPointer<dyn MyTrait>;
54 assert_eq!(v.0, dptr.through_trait());
55 assert_eq!(v.0, dptr.through_trait_and_pointer());
56}
tests/ui/deriving/deriving-copyclone.rs deleted-38
......@@ -1,38 +0,0 @@
1//@ run-pass
2//! Test that #[derive(Copy, Clone)] produces a shallow copy
3//! even when a member violates RFC 1521
4
5use std::sync::atomic::{AtomicBool, Ordering};
6
7/// A struct that pretends to be Copy, but actually does something
8/// in its Clone impl
9#[derive(Copy)]
10struct Liar;
11
12/// Static cooperating with the rogue Clone impl
13static CLONED: AtomicBool = AtomicBool::new(false);
14
15impl Clone for Liar {
16 fn clone(&self) -> Self {
17 // this makes Clone vs Copy observable
18 CLONED.store(true, Ordering::SeqCst);
19
20 *self
21 }
22}
23
24/// This struct is actually Copy... at least, it thinks it is!
25#[derive(Copy, Clone)]
26struct Innocent(#[allow(dead_code)] Liar);
27
28impl Innocent {
29 fn new() -> Self {
30 Innocent(Liar)
31 }
32}
33
34fn main() {
35 let _ = Innocent::new().clone();
36 // if Innocent was byte-for-byte copied, CLONED will still be false
37 assert!(!CLONED.load(Ordering::SeqCst));
38}
tests/ui/deriving/deriving-default-box.rs deleted-13
......@@ -1,13 +0,0 @@
1//@ run-pass
2use std::default::Default;
3
4#[derive(Default)]
5struct A {
6 foo: Box<[bool]>,
7}
8
9pub fn main() {
10 let a: A = Default::default();
11 let b: Box<[_]> = Box::<[bool; 0]>::new([]);
12 assert_eq!(a.foo, b);
13}
tests/ui/deriving/deriving-default-enum.rs deleted-27
......@@ -1,27 +0,0 @@
1//@ run-pass
2
3// nb: does not impl Default
4#[derive(Debug, PartialEq)]
5struct NotDefault;
6
7#[derive(Debug, Default, PartialEq)]
8enum Foo {
9 #[default]
10 Alpha,
11 #[allow(dead_code)]
12 Beta(NotDefault),
13}
14
15// #[default] on a generic enum does not add `Default` bounds to the type params.
16#[derive(Default)]
17enum MyOption<T> {
18 #[default]
19 None,
20 #[allow(dead_code)]
21 Some(T),
22}
23
24fn main() {
25 assert!(matches!(Foo::default(), Foo::Alpha));
26 assert!(matches!(MyOption::<NotDefault>::default(), MyOption::None));
27}
tests/ui/deriving/deriving-enum-single-variant.rs deleted-11
......@@ -1,11 +0,0 @@
1//@ run-pass
2#![allow(non_camel_case_types)]
3
4pub type task_id = isize;
5
6#[derive(PartialEq)]
7pub enum Task {
8 TaskHandle(task_id)
9}
10
11pub fn main() { }
tests/ui/deriving/deriving-eq-ord-boxed-slice.rs deleted-15
......@@ -1,15 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, PartialOrd, Eq, Ord, Debug)]
3struct Foo(Box<[u8]>);
4
5pub fn main() {
6 let a = Foo(Box::new([0, 1, 2]));
7 let b = Foo(Box::new([0, 1, 2]));
8 assert_eq!(a, b);
9 println!("{}", a != b);
10 println!("{}", a < b);
11 println!("{}", a <= b);
12 println!("{}", a == b);
13 println!("{}", a > b);
14 println!("{}", a >= b);
15}
tests/ui/deriving/deriving-from-wrong-target.rs deleted-37
......@@ -1,37 +0,0 @@
1//@ check-fail
2
3#![feature(derive_from)]
4#![allow(dead_code)]
5
6use std::from::From;
7
8#[derive(From)]
9//~^ ERROR `#[derive(From)]` used on a struct with no fields
10struct S1;
11
12#[derive(From)]
13//~^ ERROR `#[derive(From)]` used on a struct with no fields
14struct S2 {}
15
16#[derive(From)]
17//~^ ERROR `#[derive(From)]` used on a struct with multiple fields
18struct S3(u32, bool);
19
20#[derive(From)]
21//~^ ERROR `#[derive(From)]` used on a struct with multiple fields
22struct S4 {
23 a: u32,
24 b: bool,
25}
26
27#[derive(From)]
28//~^ ERROR `#[derive(From)]` used on an enum
29enum E1 {}
30
31#[derive(From)]
32struct SUnsizedField<T: ?Sized> {
33 last: T,
34 //~^ ERROR the size for values of type `T` cannot be known at compilation time [E0277]
35}
36
37fn main() {}
tests/ui/deriving/deriving-from-wrong-target.stderr deleted-77
......@@ -1,77 +0,0 @@
1error: `#[derive(From)]` used on a struct with no fields
2 --> $DIR/deriving-from-wrong-target.rs:8:10
3 |
4LL | #[derive(From)]
5 | ^^^^
6LL |
7LL | struct S1;
8 | ^^
9 |
10 = note: `#[derive(From)]` can only be used on structs with exactly one field
11
12error: `#[derive(From)]` used on a struct with no fields
13 --> $DIR/deriving-from-wrong-target.rs:12:10
14 |
15LL | #[derive(From)]
16 | ^^^^
17LL |
18LL | struct S2 {}
19 | ^^
20 |
21 = note: `#[derive(From)]` can only be used on structs with exactly one field
22
23error: `#[derive(From)]` used on a struct with multiple fields
24 --> $DIR/deriving-from-wrong-target.rs:16:10
25 |
26LL | #[derive(From)]
27 | ^^^^
28LL |
29LL | struct S3(u32, bool);
30 | ^^
31 |
32 = note: `#[derive(From)]` can only be used on structs with exactly one field
33
34error: `#[derive(From)]` used on a struct with multiple fields
35 --> $DIR/deriving-from-wrong-target.rs:20:10
36 |
37LL | #[derive(From)]
38 | ^^^^
39LL |
40LL | struct S4 {
41 | ^^
42 |
43 = note: `#[derive(From)]` can only be used on structs with exactly one field
44
45error: `#[derive(From)]` used on an enum
46 --> $DIR/deriving-from-wrong-target.rs:27:10
47 |
48LL | #[derive(From)]
49 | ^^^^
50LL |
51LL | enum E1 {}
52 | ^^
53 |
54 = note: `#[derive(From)]` can only be used on structs with exactly one field
55
56error[E0277]: the size for values of type `T` cannot be known at compilation time
57 --> $DIR/deriving-from-wrong-target.rs:33:11
58 |
59LL | struct SUnsizedField<T: ?Sized> {
60 | - this type parameter needs to be `Sized`
61LL | last: T,
62 | ^ doesn't have a size known at compile-time
63 |
64 = help: unsized fn params are gated as an unstable feature
65help: consider removing the `?Sized` bound to make the type parameter `Sized`
66 |
67LL - struct SUnsizedField<T: ?Sized> {
68LL + struct SUnsizedField<T> {
69 |
70help: function arguments must have a statically known size, borrowed types always have a known size
71 |
72LL | last: &T,
73 | +
74
75error: aborting due to 6 previous errors
76
77For more information about this error, try `rustc --explain E0277`.
tests/ui/deriving/deriving-from.rs deleted-60
......@@ -1,60 +0,0 @@
1//@ edition: 2021
2//@ run-pass
3
4#![feature(derive_from)]
5
6use core::from::From;
7
8#[derive(From)]
9struct TupleSimple(u32);
10
11#[derive(From)]
12struct TupleNonPathType([u32; 4]);
13
14#[derive(From)]
15struct TupleWithRef<'a, T>(&'a T);
16
17#[derive(From)]
18struct TupleSWithBound<T: std::fmt::Debug>(T);
19
20#[derive(From)]
21struct RawIdentifier {
22 r#use: u32,
23}
24
25#[derive(From)]
26struct Field {
27 foo: bool,
28}
29
30#[derive(From)]
31struct Const<const C: usize> {
32 foo: [u32; C],
33}
34
35fn main() {
36 let a = 42u32;
37 let b: [u32; 4] = [0, 1, 2, 3];
38 let c = true;
39
40 let s1: TupleSimple = a.into();
41 assert_eq!(s1.0, a);
42
43 let s2: TupleNonPathType = b.into();
44 assert_eq!(s2.0, b);
45
46 let s3: TupleWithRef<u32> = (&a).into();
47 assert_eq!(s3.0, &a);
48
49 let s4: TupleSWithBound<u32> = a.into();
50 assert_eq!(s4.0, a);
51
52 let s5: RawIdentifier = a.into();
53 assert_eq!(s5.r#use, a);
54
55 let s6: Field = c.into();
56 assert_eq!(s6.foo, c);
57
58 let s7: Const<4> = b.into();
59 assert_eq!(s7.foo, b);
60}
tests/ui/deriving/deriving-hash.rs deleted-96
......@@ -1,96 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#![allow(unused_imports)]
4#![allow(deprecated)]
5#![allow(non_camel_case_types)]
6#![allow(non_snake_case)]
7#![allow(overflowing_literals)]
8
9use std::hash::{Hash, SipHasher, Hasher};
10use std::mem::size_of;
11
12#[derive(Hash)]
13struct Person {
14 id: usize,
15 name: String,
16 phone: usize,
17}
18
19// test for hygiene name collisions
20#[derive(Hash)] struct __H__H;
21#[derive(Hash)] enum Collision<__H> { __H { __H__H: __H } }
22
23#[derive(Hash)]
24enum E { A=1, B }
25
26fn hash<T: Hash>(t: &T) -> u64 {
27 let mut s = SipHasher::new();
28 t.hash(&mut s);
29 s.finish()
30}
31
32struct FakeHasher<'a>(&'a mut Vec<u8>);
33impl<'a> Hasher for FakeHasher<'a> {
34 fn finish(&self) -> u64 {
35 unimplemented!()
36 }
37
38 fn write(&mut self, bytes: &[u8]) {
39 self.0.extend(bytes);
40 }
41}
42
43fn fake_hash<A: Hash>(v: &mut Vec<u8>, a: A) {
44 a.hash(&mut FakeHasher(v));
45}
46
47struct OnlyOneByteHasher;
48impl Hasher for OnlyOneByteHasher {
49 fn finish(&self) -> u64 {
50 unreachable!()
51 }
52
53 fn write(&mut self, bytes: &[u8]) {
54 assert_eq!(bytes.len(), 1);
55 }
56}
57
58fn main() {
59 let person1 = Person {
60 id: 5,
61 name: "Janet".to_string(),
62 phone: 555_666_7777
63 };
64 let person2 = Person {
65 id: 5,
66 name: "Bob".to_string(),
67 phone: 555_666_7777
68 };
69 assert_eq!(hash(&person1), hash(&person1));
70 assert!(hash(&person1) != hash(&person2));
71
72 // test #21714
73 let mut va = vec![];
74 let mut vb = vec![];
75 fake_hash(&mut va, E::A);
76 fake_hash(&mut vb, E::B);
77 assert!(va != vb);
78
79 // issue #39137: single variant enum hash should not hash discriminant
80 #[derive(Hash)]
81 enum SingleVariantEnum {
82 A(u8),
83 }
84 let mut v = vec![];
85 fake_hash(&mut v, SingleVariantEnum::A(17));
86 assert_eq!(vec![17], v);
87
88 // issue #39137
89 #[repr(u8)]
90 #[derive(Hash)]
91 enum E {
92 A,
93 B,
94 }
95 E::A.hash(&mut OnlyOneByteHasher);
96}
tests/ui/deriving/deriving-in-fn.rs deleted-13
......@@ -1,13 +0,0 @@
1//@ run-pass
2
3#![allow(dead_code)]
4
5pub fn main() {
6 #[derive(Debug)]
7 struct Foo {
8 foo: isize,
9 }
10
11 let f = Foo { foo: 10 };
12 let _ = format!("{:?}", f);
13}
tests/ui/deriving/deriving-in-macro.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ check-pass
2#![allow(non_camel_case_types)]
3#![allow(dead_code)]
4
5macro_rules! define_vec {
6 () => (
7 mod foo {
8 #[derive(PartialEq)]
9 pub struct bar;
10 }
11 )
12}
13
14define_vec![];
15
16pub fn main() {}
tests/ui/deriving/deriving-meta-multiple.rs deleted-25
......@@ -1,25 +0,0 @@
1//@ run-pass
2#![allow(unused_must_use)]
3#![allow(unused_imports)]
4#![allow(deprecated)]
5
6use std::hash::{Hash, SipHasher};
7
8// testing multiple separate deriving attributes
9#[derive(PartialEq)]
10#[derive(Clone)]
11#[derive(Hash)]
12struct Foo {
13 bar: usize,
14 baz: isize
15}
16
17fn hash<T: Hash>(_t: &T) {}
18
19pub fn main() {
20 let a = Foo {bar: 4, baz: -3};
21
22 a == a; // check for PartialEq impl w/o testing its correctness
23 a.clone(); // check for Clone impl w/o testing its correctness
24 hash(&a); // check for Hash impl w/o testing its correctness
25}
tests/ui/deriving/deriving-meta.rs deleted-22
......@@ -1,22 +0,0 @@
1//@ run-pass
2#![allow(unused_must_use)]
3#![allow(unused_imports)]
4#![allow(deprecated)]
5
6use std::hash::{Hash, SipHasher};
7
8#[derive(PartialEq, Clone, Hash)]
9struct Foo {
10 bar: usize,
11 baz: isize
12}
13
14fn hash<T: Hash>(_t: &T) {}
15
16pub fn main() {
17 let a = Foo {bar: 4, baz: -3};
18
19 a == a; // check for PartialEq impl w/o testing its correctness
20 a.clone(); // check for Clone impl w/o testing its correctness
21 hash(&a); // check for Hash impl w/o testing its correctness
22}
tests/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ run-pass
2use std::cmp::Ordering::{Less,Equal,Greater};
3
4#[derive(PartialEq, Eq, PartialOrd, Ord)]
5struct A<'a> {
6 x: &'a isize
7}
8pub fn main() {
9 let (a, b) = (A { x: &1 }, A { x: &2 });
10
11 assert_eq!(a.cmp(&a), Equal);
12 assert_eq!(b.cmp(&b), Equal);
13
14 assert_eq!(a.cmp(&b), Less);
15 assert_eq!(b.cmp(&a), Greater);
16}
tests/ui/deriving/deriving-show-2.rs deleted-54
......@@ -1,54 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3use std::fmt;
4
5#[derive(Debug)]
6enum A {}
7#[derive(Debug)]
8enum B { B1, B2, B3 }
9#[derive(Debug)]
10enum C { C1(isize), C2(B), C3(String) }
11#[derive(Debug)]
12enum D { D1{ a: isize } }
13#[derive(Debug)]
14struct E;
15#[derive(Debug)]
16struct F(isize);
17#[derive(Debug)]
18struct G(isize, isize);
19#[derive(Debug)]
20struct H { a: isize }
21#[derive(Debug)]
22struct I { a: isize, b: isize }
23#[derive(Debug)]
24struct J(Custom);
25
26struct Custom;
27impl fmt::Debug for Custom {
28 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29 write!(f, "yay")
30 }
31}
32
33trait ToDebug {
34 fn to_show(&self) -> String;
35}
36
37impl<T: fmt::Debug> ToDebug for T {
38 fn to_show(&self) -> String {
39 format!("{:?}", self)
40 }
41}
42
43pub fn main() {
44 assert_eq!(B::B1.to_show(), "B1".to_string());
45 assert_eq!(B::B2.to_show(), "B2".to_string());
46 assert_eq!(C::C1(3).to_show(), "C1(3)".to_string());
47 assert_eq!(C::C2(B::B2).to_show(), "C2(B2)".to_string());
48 assert_eq!(D::D1{ a: 2 }.to_show(), "D1 { a: 2 }".to_string());
49 assert_eq!(E.to_show(), "E".to_string());
50 assert_eq!(F(3).to_show(), "F(3)".to_string());
51 assert_eq!(G(3, 4).to_show(), "G(3, 4)".to_string());
52 assert_eq!(I{ a: 2, b: 4 }.to_show(), "I { a: 2, b: 4 }".to_string());
53 assert_eq!(J(Custom).to_show(), "J(yay)".to_string());
54}
tests/ui/deriving/deriving-show.rs deleted-35
......@@ -1,35 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#[derive(Debug)]
4struct Unit;
5
6#[derive(Debug)]
7struct Tuple(isize, usize);
8
9#[derive(Debug)]
10struct Struct { x: isize, y: usize }
11
12#[derive(Debug)]
13enum Enum {
14 Nullary,
15 Variant(isize, usize),
16 StructVariant { x: isize, y : usize }
17}
18
19#[derive(Debug)]
20struct Pointers(*const dyn Send, *mut dyn Sync);
21
22macro_rules! t {
23 ($x:expr, $expected:expr) => {
24 assert_eq!(format!("{:?}", $x), $expected.to_string())
25 }
26}
27
28pub fn main() {
29 t!(Unit, "Unit");
30 t!(Tuple(1, 2), "Tuple(1, 2)");
31 t!(Struct { x: 1, y: 2 }, "Struct { x: 1, y: 2 }");
32 t!(Enum::Nullary, "Nullary");
33 t!(Enum::Variant(1, 2), "Variant(1, 2)");
34 t!(Enum::StructVariant { x: 1, y: 2 }, "StructVariant { x: 1, y: 2 }");
35}
tests/ui/deriving/deriving-via-extension-c-enum.rs deleted-17
......@@ -1,17 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#[derive(PartialEq, Debug)]
4enum Foo {
5 Bar,
6 Baz,
7 Boo
8}
9
10pub fn main() {
11 let a = Foo::Bar;
12 let b = Foo::Bar;
13 assert_eq!(a, b);
14 assert!(!(a != b));
15 assert!(a.eq(&b));
16 assert!(!a.ne(&b));
17}
tests/ui/deriving/deriving-via-extension-enum.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#[derive(PartialEq, Debug)]
4enum Foo {
5 Bar(isize, isize),
6 Baz(f64, f64)
7}
8
9pub fn main() {
10 let a = Foo::Bar(1, 2);
11 let b = Foo::Bar(1, 2);
12 assert_eq!(a, b);
13 assert!(!(a != b));
14 assert!(a.eq(&b));
15 assert!(!a.ne(&b));
16}
tests/ui/deriving/deriving-via-extension-hash-enum.rs deleted-17
......@@ -1,17 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#[derive(Hash)]
4enum Foo {
5 Bar(isize, char),
6 Baz(char, isize)
7}
8
9#[derive(Hash)]
10enum A {
11 B,
12 C,
13 D,
14 E
15}
16
17pub fn main(){}
tests/ui/deriving/deriving-via-extension-hash-struct.rs deleted-11
......@@ -1,11 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3
4#[derive(Hash)]
5struct Foo {
6 x: isize,
7 y: isize,
8 z: isize
9}
10
11pub fn main() {}
tests/ui/deriving/deriving-via-extension-struct-empty.rs deleted-8
......@@ -1,8 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Debug)]
3struct Foo;
4
5pub fn main() {
6 assert_eq!(Foo, Foo);
7 assert!(!(Foo != Foo));
8}
tests/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs deleted-13
......@@ -1,13 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#[derive(PartialEq, Debug)]
4enum S {
5 X { x: isize, y: isize },
6 Y
7}
8
9pub fn main() {
10 let x = S::X { x: 1, y: 2 };
11 assert_eq!(x, x);
12 assert!(!(x != x));
13}
tests/ui/deriving/deriving-via-extension-struct-tuple.rs deleted-17
......@@ -1,17 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Debug)]
3struct Foo(isize, isize, String);
4
5pub fn main() {
6 let a1 = Foo(5, 6, "abc".to_string());
7 let a2 = Foo(5, 6, "abc".to_string());
8 let b = Foo(5, 7, "def".to_string());
9
10 assert_eq!(a1, a1);
11 assert_eq!(a2, a1);
12 assert!(!(a1 == b));
13
14 assert!(a1 != b);
15 assert!(!(a1 != a1));
16 assert!(!(a2 != a1));
17}
tests/ui/deriving/deriving-via-extension-struct.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Debug)]
3struct Foo {
4 x: isize,
5 y: isize,
6 z: isize,
7}
8
9pub fn main() {
10 let a = Foo { x: 1, y: 2, z: 3 };
11 let b = Foo { x: 1, y: 2, z: 3 };
12 assert_eq!(a, b);
13 assert!(!(a != b));
14 assert!(a.eq(&b));
15 assert!(!a.ne(&b));
16}
tests/ui/deriving/deriving-via-extension-type-params.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ run-pass
2#[derive(PartialEq, Hash, Debug)]
3struct Foo<T> {
4 x: isize,
5 y: T,
6 z: isize
7}
8
9pub fn main() {
10 let a = Foo { x: 1, y: 2.0f64, z: 3 };
11 let b = Foo { x: 1, y: 2.0f64, z: 3 };
12 assert_eq!(a, b);
13 assert!(!(a != b));
14 assert!(a.eq(&b));
15 assert!(!a.ne(&b));
16}
tests/ui/deriving/deriving-with-helper.rs deleted-37
......@@ -1,37 +0,0 @@
1//@ add-minicore
2//@ check-pass
3//@ compile-flags: --crate-type=lib
4
5#![feature(decl_macro)]
6#![feature(lang_items)]
7#![feature(no_core)]
8#![feature(rustc_attrs)]
9
10#![no_core]
11
12extern crate minicore;
13use minicore::*;
14
15#[rustc_builtin_macro]
16macro derive() {}
17
18#[rustc_builtin_macro(Default, attributes(default))]
19macro Default() {}
20
21mod default {
22 pub trait Default {
23 fn default() -> Self;
24 }
25
26 impl Default for u8 {
27 fn default() -> u8 {
28 0
29 }
30 }
31}
32
33#[derive(Default)]
34enum S {
35 #[default] // OK
36 Foo,
37}
tests/ui/deriving/deriving-with-repr-packed.rs deleted-36
......@@ -1,36 +0,0 @@
1//@ run-pass
2// check that derive on a packed struct does not call field
3// methods with a misaligned field.
4
5use std::mem;
6
7#[derive(Copy, Clone)]
8struct Aligned(usize);
9
10#[inline(never)]
11fn check_align(ptr: *const Aligned) {
12 assert_eq!(ptr as usize % mem::align_of::<Aligned>(),
13 0);
14}
15
16impl PartialEq for Aligned {
17 fn eq(&self, other: &Self) -> bool {
18 check_align(self);
19 check_align(other);
20 self.0 == other.0
21 }
22}
23
24#[repr(packed)]
25#[derive(Copy, Clone, PartialEq)]
26struct Packed(Aligned, Aligned);
27
28#[derive(PartialEq)]
29#[repr(C)]
30struct Dealigned<T>(u8, T);
31
32fn main() {
33 let d1 = Dealigned(0, Packed(Aligned(1), Aligned(2)));
34 let ck = d1 == d1;
35 assert!(ck);
36}
tests/ui/deriving/do-not-suggest-calling-fn-in-derive-macro.rs deleted-8
......@@ -1,8 +0,0 @@
1use std::rc::Rc;
2
3#[derive(PartialEq)] //~ NOTE in this expansion
4pub struct Function {
5 callback: Rc<dyn Fn()>, //~ ERROR binary operation `==` cannot be applied to type `Rc<dyn Fn()>`
6}
7
8fn main() {}
tests/ui/deriving/do-not-suggest-calling-fn-in-derive-macro.stderr deleted-12
......@@ -1,12 +0,0 @@
1error[E0369]: binary operation `==` cannot be applied to type `Rc<dyn Fn()>`
2 --> $DIR/do-not-suggest-calling-fn-in-derive-macro.rs:5:5
3 |
4LL | #[derive(PartialEq)]
5 | --------- in this derive macro expansion
6LL | pub struct Function {
7LL | callback: Rc<dyn Fn()>,
8 | ^^^^^^^^^^^^^^^^^^^^^^
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0369`.
tests/ui/deriving/internal_eq_trait_method_impls.rs deleted-48
......@@ -1,48 +0,0 @@
1#![deny(deprecated, internal_eq_trait_method_impls)]
2pub struct Bad;
3
4impl PartialEq for Bad {
5 fn eq(&self, _: &Self) -> bool {
6 true
7 }
8}
9
10impl Eq for Bad {
11 fn assert_receiver_is_total_eq(&self) {}
12 //~^ ERROR: `Eq::assert_receiver_is_total_eq` should never be implemented by hand [internal_eq_trait_method_impls]
13 //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
14}
15
16#[derive(PartialEq, Eq)]
17pub struct Good;
18
19#[derive(PartialEq)]
20pub struct Good2;
21
22impl Eq for Good2 {}
23
24pub struct Foo;
25
26pub trait SameName {
27 fn assert_receiver_is_total_eq(&self) {}
28}
29
30impl SameName for Foo {
31 fn assert_receiver_is_total_eq(&self) {}
32}
33
34pub fn main() {
35 Foo.assert_receiver_is_total_eq();
36 Good2.assert_receiver_is_total_eq();
37 //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated]
38 Good.assert_receiver_is_total_eq();
39 //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated]
40 Bad.assert_receiver_is_total_eq();
41 //~^ ERROR: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]` [deprecated]
42}
43
44#[forbid(internal_eq_trait_method_impls)]
45mod forbid {
46 #[derive(PartialEq, Eq)]
47 pub struct Foo;
48}
tests/ui/deriving/internal_eq_trait_method_impls.stderr deleted-41
......@@ -1,41 +0,0 @@
1error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]`
2 --> $DIR/internal_eq_trait_method_impls.rs:36:11
3 |
4LL | Good2.assert_receiver_is_total_eq();
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7note: the lint level is defined here
8 --> $DIR/internal_eq_trait_method_impls.rs:1:9
9 |
10LL | #![deny(deprecated, internal_eq_trait_method_impls)]
11 | ^^^^^^^^^^
12
13error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]`
14 --> $DIR/internal_eq_trait_method_impls.rs:38:10
15 |
16LL | Good.assert_receiver_is_total_eq();
17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
18
19error: use of deprecated method `std::cmp::Eq::assert_receiver_is_total_eq`: implementation detail of `#[derive(Eq)]`
20 --> $DIR/internal_eq_trait_method_impls.rs:40:9
21 |
22LL | Bad.assert_receiver_is_total_eq();
23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
24
25error: `Eq::assert_receiver_is_total_eq` should never be implemented by hand
26 --> $DIR/internal_eq_trait_method_impls.rs:11:5
27 |
28LL | fn assert_receiver_is_total_eq(&self) {}
29 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30 |
31 = note: this method was used to add checks to the `Eq` derive macro
32 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
33 = note: for more information, see issue #152336 <https://github.com/rust-lang/rust/issues/152336>
34note: the lint level is defined here
35 --> $DIR/internal_eq_trait_method_impls.rs:1:21
36 |
37LL | #![deny(deprecated, internal_eq_trait_method_impls)]
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39
40error: aborting due to 4 previous errors
41
tests/ui/deriving/multiple-defaults.rs deleted-41
......@@ -1,41 +0,0 @@
1//@ compile-flags: --crate-type=lib
2
3// When we get multiple `#[default]` variants, we emit several tool-only suggestions
4// to remove all except one of the `#[default]`s.
5
6#[derive(Default)] //~ ERROR multiple declared defaults
7enum A {
8 #[default] //~ HELP make `B` default
9 #[default] //~ HELP make `A` default
10 A,
11 #[default] // also "HELP make `A` default", but compiletest can't handle multispans
12 B,
13}
14
15// Originally, we took each defaulted variant and emitted the suggestion for every variant
16// with a different identifier, causing an ICE when multiple variants have the same identifier:
17// https://github.com/rust-lang/rust/pull/105106
18#[derive(Default)] //~ ERROR multiple declared defaults
19enum E {
20 #[default] //~ HELP make `A` default
21 A,
22 #[default] //~ HELP make `A` default
23 A, //~ ERROR defined multiple times
24}
25
26// Then, we took each defaulted variant and emitted the suggestion for every variant
27// with a different span, causing an ICE when multiple variants have the same span:
28// https://github.com/rust-lang/rust/issues/118119
29macro_rules! m {
30 { $($id:ident)* } => {
31 #[derive(Default)] //~ ERROR multiple declared defaults
32 enum F {
33 $(
34 #[default]
35 $id,
36 )*
37 }
38 }
39}
40
41m! { A B }
tests/ui/deriving/multiple-defaults.stderr deleted-60
......@@ -1,60 +0,0 @@
1error: multiple declared defaults
2 --> $DIR/multiple-defaults.rs:6:10
3 |
4LL | #[derive(Default)]
5 | ^^^^^^^
6...
7LL | A,
8 | - first default
9LL | #[default] // also "HELP make `A` default", but compiletest can't handle multispans
10LL | B,
11 | - additional default
12 |
13 = note: only one variant can be default
14
15error: multiple declared defaults
16 --> $DIR/multiple-defaults.rs:18:10
17 |
18LL | #[derive(Default)]
19 | ^^^^^^^
20...
21LL | A,
22 | - first default
23LL | #[default]
24LL | A,
25 | - additional default
26 |
27 = note: only one variant can be default
28
29error[E0428]: the name `A` is defined multiple times
30 --> $DIR/multiple-defaults.rs:23:5
31 |
32LL | A,
33 | - previous definition of the type `A` here
34LL | #[default]
35LL | A,
36 | ^ `A` redefined here
37 |
38 = note: `A` must be defined only once in the type namespace of this enum
39
40error: multiple declared defaults
41 --> $DIR/multiple-defaults.rs:31:18
42 |
43LL | #[derive(Default)]
44 | ^^^^^^^
45...
46LL | $id,
47 | ---
48 | |
49 | first default
50 | additional default
51...
52LL | m! { A B }
53 | ---------- in this macro invocation
54 |
55 = note: only one variant can be default
56 = note: this error originates in the derive macro `Default` which comes from the expansion of the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
57
58error: aborting due to 4 previous errors
59
60For more information about this error, try `rustc --explain E0428`.
tests/ui/deriving/proc-macro-attribute-mixing.rs deleted-21
......@@ -1,21 +0,0 @@
1// This test certify that we can mix attribute macros from Rust and external proc-macros.
2// For instance, `#[derive(Default)]` uses `#[default]` and `#[derive(CoercePointee)]` uses
3// `#[pointee]`.
4// The scoping rule should allow the use of the said two attributes when external proc-macros
5// are in scope.
6
7//@ check-pass
8//@ proc-macro: another-proc-macro.rs
9//@ compile-flags: -Zunpretty=expanded
10//@ edition: 2015
11
12#![feature(derive_coerce_pointee)]
13
14#[macro_use]
15extern crate another_proc_macro;
16
17#[pointee]
18fn f() {}
19
20#[default]
21fn g() {}
tests/ui/deriving/proc-macro-attribute-mixing.stdout deleted-30
......@@ -1,30 +0,0 @@
1#![feature(prelude_import)]
2#![no_std]
3// This test certify that we can mix attribute macros from Rust and external proc-macros.
4// For instance, `#[derive(Default)]` uses `#[default]` and `#[derive(CoercePointee)]` uses
5// `#[pointee]`.
6// The scoping rule should allow the use of the said two attributes when external proc-macros
7// are in scope.
8
9//@ check-pass
10//@ proc-macro: another-proc-macro.rs
11//@ compile-flags: -Zunpretty=expanded
12//@ edition: 2015
13
14#![feature(derive_coerce_pointee)]
15extern crate std;
16#[prelude_import]
17use ::std::prelude::rust_2015::*;
18
19#[macro_use]
20extern crate another_proc_macro;
21
22
23const _: () =
24 {
25 const POINTEE_MACRO_ATTR_DERIVED: () = ();
26 };
27const _: () =
28 {
29 const DEFAULT_MACRO_ATTR_DERIVED: () = ();
30 };
tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs+13-13
......@@ -74,7 +74,7 @@
7474//~| WARN previously accepted
7575//~| HELP can be applied to
7676//~| HELP remove the attribute
77#![link_section = "1800"]
77#![link_section = ",1800"]
7878//~^ WARN attribute cannot be used on
7979//~| WARN previously accepted
8080//~| HELP can be applied to
......@@ -616,66 +616,66 @@ mod link_name {
616616 //~| HELP remove the attribute
617617}
618618
619#[link_section = "1800"]
619#[link_section = ",1800"]
620620//~^ WARN attribute cannot be used on
621621//~| WARN previously accepted
622622//~| HELP can be applied to
623623//~| HELP remove the attribute
624624mod link_section {
625 mod inner { #![link_section="1800"] }
625 mod inner { #![link_section=",1800"] }
626626 //~^ WARN attribute cannot be used on
627627 //~| WARN previously accepted
628628 //~| HELP can be applied to
629629 //~| HELP remove the attribute
630630
631 #[link_section = "1800"] fn f() { }
631 #[link_section = ",1800"] fn f() { }
632632
633 #[link_section = "1800"] struct S;
633 #[link_section = ",1800"] struct S;
634634 //~^ WARN attribute cannot be used on
635635 //~| WARN previously accepted
636636 //~| HELP can be applied to
637637 //~| HELP remove the attribute
638638
639 #[link_section = "1800"] type T = S;
639 #[link_section = ",1800"] type T = S;
640640 //~^ WARN attribute cannot be used on
641641 //~| WARN previously accepted
642642 //~| HELP can be applied to
643643 //~| HELP remove the attribute
644644
645 #[link_section = "1800"] impl S { }
645 #[link_section = ",1800"] impl S { }
646646 //~^ WARN attribute cannot be used on
647647 //~| WARN previously accepted
648648 //~| HELP can be applied to
649649 //~| HELP remove the attribute
650650
651 #[link_section = "1800"]
651 #[link_section = ",1800"]
652652 //~^ WARN attribute cannot be used on
653653 //~| WARN previously accepted
654654 //~| HELP can be applied to
655655 //~| HELP remove the attribute
656656 trait Tr {
657 #[link_section = "1800"]
657 #[link_section = ",1800"]
658658 //~^ WARN attribute cannot be used on
659659 //~| WARN previously accepted
660660 //~| HELP can be applied to
661661 //~| HELP remove the attribute
662662 fn inside_tr_no_default(&self);
663663
664 #[link_section = "1800"]
664 #[link_section = ",1800"]
665665 fn inside_tr_default(&self) { }
666666 }
667667
668668 impl S {
669 #[link_section = "1800"]
669 #[link_section = ",1800"]
670670 fn inside_abc_123(&self) { }
671671 }
672672
673673 impl Tr for S {
674 #[link_section = "1800"]
674 #[link_section = ",1800"]
675675 fn inside_tr_no_default(&self) { }
676676 }
677677
678 #[link_section = "1800"]
678 #[link_section = ",1800"]
679679 fn should_always_link() { }
680680}
681681
tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr+16-16
......@@ -866,8 +866,8 @@ LL | #[link_name = "1900"] impl S { }
866866warning: `#[link_section]` attribute cannot be used on modules
867867 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:619:1
868868 |
869LL | #[link_section = "1800"]
870 | ^^^^^^^^^^^^^^^^^^^^^^^^
869LL | #[link_section = ",1800"]
870 | ^^^^^^^^^^^^^^^^^^^^^^^^^
871871 |
872872 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
873873 = help: `#[link_section]` can be applied to functions and statics
......@@ -875,8 +875,8 @@ LL | #[link_section = "1800"]
875875warning: `#[link_section]` attribute cannot be used on modules
876876 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:625:17
877877 |
878LL | mod inner { #![link_section="1800"] }
879 | ^^^^^^^^^^^^^^^^^^^^^^^
878LL | mod inner { #![link_section=",1800"] }
879 | ^^^^^^^^^^^^^^^^^^^^^^^^
880880 |
881881 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
882882 = help: `#[link_section]` can be applied to functions and statics
......@@ -884,8 +884,8 @@ LL | mod inner { #![link_section="1800"] }
884884warning: `#[link_section]` attribute cannot be used on structs
885885 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:633:5
886886 |
887LL | #[link_section = "1800"] struct S;
888 | ^^^^^^^^^^^^^^^^^^^^^^^^
887LL | #[link_section = ",1800"] struct S;
888 | ^^^^^^^^^^^^^^^^^^^^^^^^^
889889 |
890890 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
891891 = help: `#[link_section]` can be applied to functions and statics
......@@ -893,8 +893,8 @@ LL | #[link_section = "1800"] struct S;
893893warning: `#[link_section]` attribute cannot be used on type aliases
894894 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639:5
895895 |
896LL | #[link_section = "1800"] type T = S;
897 | ^^^^^^^^^^^^^^^^^^^^^^^^
896LL | #[link_section = ",1800"] type T = S;
897 | ^^^^^^^^^^^^^^^^^^^^^^^^^
898898 |
899899 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
900900 = help: `#[link_section]` can be applied to functions and statics
......@@ -902,8 +902,8 @@ LL | #[link_section = "1800"] type T = S;
902902warning: `#[link_section]` attribute cannot be used on inherent impl blocks
903903 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:645:5
904904 |
905LL | #[link_section = "1800"] impl S { }
906 | ^^^^^^^^^^^^^^^^^^^^^^^^
905LL | #[link_section = ",1800"] impl S { }
906 | ^^^^^^^^^^^^^^^^^^^^^^^^^
907907 |
908908 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
909909 = help: `#[link_section]` can be applied to functions and statics
......@@ -911,8 +911,8 @@ LL | #[link_section = "1800"] impl S { }
911911warning: `#[link_section]` attribute cannot be used on traits
912912 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:5
913913 |
914LL | #[link_section = "1800"]
915 | ^^^^^^^^^^^^^^^^^^^^^^^^
914LL | #[link_section = ",1800"]
915 | ^^^^^^^^^^^^^^^^^^^^^^^^^
916916 |
917917 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
918918 = help: `#[link_section]` can be applied to functions and statics
......@@ -920,8 +920,8 @@ LL | #[link_section = "1800"]
920920warning: `#[link_section]` attribute cannot be used on required trait methods
921921 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:9
922922 |
923LL | #[link_section = "1800"]
924 | ^^^^^^^^^^^^^^^^^^^^^^^^
923LL | #[link_section = ",1800"]
924 | ^^^^^^^^^^^^^^^^^^^^^^^^^
925925 |
926926 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
927927 = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
......@@ -1570,8 +1570,8 @@ LL | #![link_name = "1900"]
15701570warning: `#[link_section]` attribute cannot be used on crates
15711571 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:77:1
15721572 |
1573LL | #![link_section = "1800"]
1574 | ^^^^^^^^^^^^^^^^^^^^^^^^^
1573LL | #![link_section = ",1800"]
1574 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
15751575 |
15761576 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15771577 = help: `#[link_section]` can be applied to functions and statics
tests/ui/linkage-attr/link-section-macho.rs created+58
......@@ -0,0 +1,58 @@
1//@ add-minicore
2//@ compile-flags: --target aarch64-apple-darwin
3//@ needs-llvm-components: aarch64
4//@ ignore-backends: gcc
5#![feature(no_core, rustc_attrs, lang_items)]
6#![no_core]
7#![crate_type = "lib"]
8
9extern crate minicore;
10use minicore::*;
11
12#[unsafe(link_section = "foo")]
13//~^ ERROR invalid Mach-O section specifier
14#[unsafe(no_mangle)]
15fn missing_section() {}
16
17#[unsafe(link_section = "foo,")]
18//~^ ERROR invalid Mach-O section specifier
19#[unsafe(no_mangle)]
20fn empty_section() {}
21
22#[unsafe(link_section = "foo, ")]
23//~^ ERROR invalid Mach-O section specifier
24#[unsafe(no_mangle)]
25fn whitespace_section() {}
26
27#[unsafe(link_section = "foo,somelongwindedthing")]
28//~^ ERROR invalid Mach-O section specifier
29#[unsafe(no_mangle)]
30fn section_too_long() {}
31
32#[unsafe(link_section = "foo,bar")]
33#[unsafe(no_mangle)]
34fn segment_and_section() {}
35
36#[unsafe(link_section = "foo,bar,")]
37#[unsafe(no_mangle)]
38fn segment_and_section_and_comma() {}
39
40#[unsafe(link_section = ",foo")]
41#[unsafe(no_mangle)]
42fn missing_segment_is_fine() {}
43
44#[unsafe(link_section = "__TEXT,__stubs,symbol_stubs,none,16")]
45#[unsafe(no_mangle)]
46fn stub_size_decimal() {}
47
48#[unsafe(link_section = "__TEXT,__stubs,symbol_stubs,none,0x10")]
49#[unsafe(no_mangle)]
50fn stub_size_hex() {}
51
52#[unsafe(link_section = "__TEXT,__stubs,symbol_stubs,none,020")]
53#[unsafe(no_mangle)]
54fn stub_size_oct() {}
55
56#[unsafe(link_section = "__TEXT,__stubs,symbol_stubs,none,020,rest,is,ignored")]
57#[unsafe(no_mangle)]
58fn rest_is_ignored() {}
tests/ui/linkage-attr/link-section-macho.stderr created+37
......@@ -0,0 +1,37 @@
1error: invalid Mach-O section specifier
2 --> $DIR/link-section-macho.rs:12:25
3 |
4LL | #[unsafe(link_section = "foo")]
5 | ^^^^^ not a valid Mach-O section specifier
6 |
7 = note: a Mach-O section specifier requires a segment and a section, separated by a comma
8 = help: an example of a valid Mach-O section specifier is `__TEXT,__cstring`
9
10error: invalid Mach-O section specifier
11 --> $DIR/link-section-macho.rs:17:25
12 |
13LL | #[unsafe(link_section = "foo,")]
14 | ^^^^^^ not a valid Mach-O section specifier
15 |
16 = note: a Mach-O section specifier requires a segment and a section, separated by a comma
17 = help: an example of a valid Mach-O section specifier is `__TEXT,__cstring`
18
19error: invalid Mach-O section specifier
20 --> $DIR/link-section-macho.rs:22:25
21 |
22LL | #[unsafe(link_section = "foo, ")]
23 | ^^^^^^^ not a valid Mach-O section specifier
24 |
25 = note: a Mach-O section specifier requires a segment and a section, separated by a comma
26 = help: an example of a valid Mach-O section specifier is `__TEXT,__cstring`
27
28error: invalid Mach-O section specifier
29 --> $DIR/link-section-macho.rs:27:25
30 |
31LL | #[unsafe(link_section = "foo,somelongwindedthing")]
32 | ^^^^^^^^^^^^^^^^^^^^^^^^^ not a valid Mach-O section specifier
33 |
34 = note: section name `somelongwindedthing` is longer than 16 bytes
35
36error: aborting due to 4 previous errors
37
tests/ui/linkage-attr/link-section-placement.rs+23-22
......@@ -2,36 +2,37 @@
22
33//@ run-pass
44
5#![feature(cfg_target_object_format)]
56// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
67#![allow(static_mut_refs)]
78#![allow(non_upper_case_globals)]
8#[cfg(not(target_vendor = "apple"))]
9#[link_section = ".moretext"]
10fn i_live_in_more_text() -> &'static str {
11 "knock knock"
12}
139
14#[cfg(not(target_vendor = "apple"))]
15#[link_section = ".imm"]
16static magic: usize = 42;
10cfg_select! {
11 target_object_format = "mach-o" => {
12 #[link_section = "__TEXT,__moretext"]
13 fn i_live_in_more_text() -> &'static str {
14 "knock knock"
15 }
1716
18#[cfg(not(target_vendor = "apple"))]
19#[link_section = ".mut"]
20static mut frobulator: usize = 0xdeadbeef;
17 #[link_section = "__RODATA,__imm"]
18 static magic: usize = 42;
2119
22#[cfg(target_vendor = "apple")]
23#[link_section = "__TEXT,__moretext"]
24fn i_live_in_more_text() -> &'static str {
25 "knock knock"
26}
20 #[link_section = "__DATA,__mut"]
21 static mut frobulator: usize = 0xdeadbeef;
22 }
23 _ => {
24 #[link_section = ".moretext"]
25 fn i_live_in_more_text() -> &'static str {
26 "knock knock"
27 }
2728
28#[cfg(target_vendor = "apple")]
29#[link_section = "__RODATA,__imm"]
30static magic: usize = 42;
29 #[link_section = ".imm"]
30 static magic: usize = 42;
3131
32#[cfg(target_vendor = "apple")]
33#[link_section = "__DATA,__mut"]
34static mut frobulator: usize = 0xdeadbeef;
32 #[link_section = ".mut"]
33 static mut frobulator: usize = 0xdeadbeef;
34 }
35}
3536
3637pub fn main() {
3738 unsafe {
tests/ui/lint/lint-unsafe-code.rs+2-2
......@@ -48,8 +48,8 @@ impl AssocFnTrait for AssocFnFoo {
4848#[export_name = "bar"] fn bar() {} //~ ERROR: declaration of a function with `export_name`
4949#[export_name = "BAR"] static BAR: u32 = 5; //~ ERROR: declaration of a static with `export_name`
5050
51#[link_section = ".example_section"] fn uwu() {} //~ ERROR: declaration of a function with `link_section`
52#[link_section = ".example_section"] static UWU: u32 = 5; //~ ERROR: declaration of a static with `link_section`
51#[link_section = "__TEXT,__text"] fn uwu() {} //~ ERROR: declaration of a function with `link_section`
52#[link_section = "__TEXT,__text"] static UWU: u32 = 5; //~ ERROR: declaration of a static with `link_section`
5353
5454struct AssocFnBar;
5555
tests/ui/lint/lint-unsafe-code.stderr+4-4
......@@ -54,16 +54,16 @@ LL | #[export_name = "BAR"] static BAR: u32 = 5;
5454error: declaration of a function with `link_section`
5555 --> $DIR/lint-unsafe-code.rs:51:1
5656 |
57LL | #[link_section = ".example_section"] fn uwu() {}
58 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57LL | #[link_section = "__TEXT,__text"] fn uwu() {}
58 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959 |
6060 = note: the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
6161
6262error: declaration of a static with `link_section`
6363 --> $DIR/lint-unsafe-code.rs:52:1
6464 |
65LL | #[link_section = ".example_section"] static UWU: u32 = 5;
66 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65LL | #[link_section = "__TEXT,__text"] static UWU: u32 = 5;
66 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6767 |
6868 = note: the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
6969
tests/ui/lint/unused/unused-attr-duplicate.rs+6-5
......@@ -61,8 +61,9 @@ pub mod from_path;
6161fn t1() {}
6262
6363#[must_use]
64#[must_use = "some message"] //~ ERROR unused attribute
65//~^ WARN this was previously accepted
64#[must_use = "some message"]
65//~^ ERROR unused attribute
66//~| WARN this was previously accepted
6667// No warnings for #[repr], would require more logic.
6768#[repr(C)]
6869#[repr(C)]
......@@ -96,7 +97,7 @@ extern "C" {
9697}
9798
9899#[export_name = "exported_symbol_name"]
99#[export_name = "exported_symbol_name2"] //~ ERROR unused attribute
100#[export_name = "exported_symbol_name2"] //~ ERROR unused attribute
100101//~^ WARN this was previously accepted
101102pub fn export_test() {}
102103
......@@ -108,8 +109,8 @@ pub fn no_mangle_test() {}
108109#[used] //~ ERROR unused attribute
109110static FOO: u32 = 0;
110111
111#[link_section = ".text"]
112#[link_section = ".bss"]
112#[link_section = "__TEXT,__text"]
113#[link_section = "__DATA,__mod_init_func"]
113114//~^ ERROR unused attribute
114115//~| WARN this was previously accepted
115116pub extern "C" fn example() {}
tests/ui/lint/unused/unused-attr-duplicate.stderr+24-24
......@@ -104,127 +104,127 @@ LL | #[must_use]
104104 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
105105
106106error: unused attribute
107 --> $DIR/unused-attr-duplicate.rs:70:1
107 --> $DIR/unused-attr-duplicate.rs:71:1
108108 |
109109LL | #[non_exhaustive]
110110 | ^^^^^^^^^^^^^^^^^ help: remove this attribute
111111 |
112112note: attribute also specified here
113 --> $DIR/unused-attr-duplicate.rs:69:1
113 --> $DIR/unused-attr-duplicate.rs:70:1
114114 |
115115LL | #[non_exhaustive]
116116 | ^^^^^^^^^^^^^^^^^
117117
118118error: unused attribute
119 --> $DIR/unused-attr-duplicate.rs:76:1
119 --> $DIR/unused-attr-duplicate.rs:77:1
120120 |
121121LL | #[automatically_derived]
122122 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
123123 |
124124note: attribute also specified here
125 --> $DIR/unused-attr-duplicate.rs:75:1
125 --> $DIR/unused-attr-duplicate.rs:76:1
126126 |
127127LL | #[automatically_derived]
128128 | ^^^^^^^^^^^^^^^^^^^^^^^^
129129
130130error: unused attribute
131 --> $DIR/unused-attr-duplicate.rs:80:1
131 --> $DIR/unused-attr-duplicate.rs:81:1
132132 |
133133LL | #[inline(never)]
134134 | ^^^^^^^^^^^^^^^^ help: remove this attribute
135135 |
136136note: attribute also specified here
137 --> $DIR/unused-attr-duplicate.rs:79:1
137 --> $DIR/unused-attr-duplicate.rs:80:1
138138 |
139139LL | #[inline(always)]
140140 | ^^^^^^^^^^^^^^^^^
141141 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
142142
143143error: unused attribute
144 --> $DIR/unused-attr-duplicate.rs:83:1
144 --> $DIR/unused-attr-duplicate.rs:84:1
145145 |
146146LL | #[cold]
147147 | ^^^^^^^ help: remove this attribute
148148 |
149149note: attribute also specified here
150 --> $DIR/unused-attr-duplicate.rs:82:1
150 --> $DIR/unused-attr-duplicate.rs:83:1
151151 |
152152LL | #[cold]
153153 | ^^^^^^^
154154
155155error: unused attribute
156 --> $DIR/unused-attr-duplicate.rs:85:1
156 --> $DIR/unused-attr-duplicate.rs:86:1
157157 |
158158LL | #[track_caller]
159159 | ^^^^^^^^^^^^^^^ help: remove this attribute
160160 |
161161note: attribute also specified here
162 --> $DIR/unused-attr-duplicate.rs:84:1
162 --> $DIR/unused-attr-duplicate.rs:85:1
163163 |
164164LL | #[track_caller]
165165 | ^^^^^^^^^^^^^^^
166166
167167error: unused attribute
168 --> $DIR/unused-attr-duplicate.rs:93:5
168 --> $DIR/unused-attr-duplicate.rs:94:5
169169 |
170170LL | #[link_name = "rust_dbg_extern_identity_u32"]
171171 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
172172 |
173173note: attribute also specified here
174 --> $DIR/unused-attr-duplicate.rs:92:5
174 --> $DIR/unused-attr-duplicate.rs:93:5
175175 |
176176LL | #[link_name = "this_does_not_exist"]
177177 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
178178 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
179179
180180error: unused attribute
181 --> $DIR/unused-attr-duplicate.rs:99:1
181 --> $DIR/unused-attr-duplicate.rs:100:1
182182 |
183183LL | #[export_name = "exported_symbol_name2"]
184184 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
185185 |
186186note: attribute also specified here
187 --> $DIR/unused-attr-duplicate.rs:98:1
187 --> $DIR/unused-attr-duplicate.rs:99:1
188188 |
189189LL | #[export_name = "exported_symbol_name"]
190190 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
191191 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
192192
193193error: unused attribute
194 --> $DIR/unused-attr-duplicate.rs:104:1
194 --> $DIR/unused-attr-duplicate.rs:105:1
195195 |
196196LL | #[no_mangle]
197197 | ^^^^^^^^^^^^ help: remove this attribute
198198 |
199199note: attribute also specified here
200 --> $DIR/unused-attr-duplicate.rs:103:1
200 --> $DIR/unused-attr-duplicate.rs:104:1
201201 |
202202LL | #[no_mangle]
203203 | ^^^^^^^^^^^^
204204
205205error: unused attribute
206 --> $DIR/unused-attr-duplicate.rs:108:1
206 --> $DIR/unused-attr-duplicate.rs:109:1
207207 |
208208LL | #[used]
209209 | ^^^^^^^ help: remove this attribute
210210 |
211211note: attribute also specified here
212 --> $DIR/unused-attr-duplicate.rs:107:1
212 --> $DIR/unused-attr-duplicate.rs:108:1
213213 |
214214LL | #[used]
215215 | ^^^^^^^
216216
217217error: unused attribute
218 --> $DIR/unused-attr-duplicate.rs:112:1
218 --> $DIR/unused-attr-duplicate.rs:113:1
219219 |
220LL | #[link_section = ".bss"]
221 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
220LL | #[link_section = "__DATA,__mod_init_func"]
221 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
222222 |
223223note: attribute also specified here
224 --> $DIR/unused-attr-duplicate.rs:111:1
224 --> $DIR/unused-attr-duplicate.rs:112:1
225225 |
226LL | #[link_section = ".text"]
227 | ^^^^^^^^^^^^^^^^^^^^^^^^^
226LL | #[link_section = "__TEXT,__text"]
227 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
228228 = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
229229
230230error: unused attribute
tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed+5-5
......@@ -15,7 +15,7 @@ macro_rules! ident {
1515 //~^ ERROR: unsafe attribute used without unsafe
1616 //~| WARN this is accepted in the current edition
1717 extern "C" fn bar() {}
18 }
18 };
1919}
2020
2121macro_rules! ident2 {
......@@ -24,26 +24,26 @@ macro_rules! ident2 {
2424 //~^ ERROR: unsafe attribute used without unsafe
2525 //~| WARN this is accepted in the current edition
2626 extern "C" fn bars() {}
27 }
27 };
2828}
2929
3030macro_rules! meta {
3131 ($m:meta) => {
3232 #[$m]
3333 extern "C" fn baz() {}
34 }
34 };
3535}
3636
3737macro_rules! meta2 {
3838 ($m:meta) => {
3939 #[$m]
4040 extern "C" fn baw() {}
41 }
41 };
4242}
4343
4444macro_rules! with_cfg_attr {
4545 () => {
46 #[cfg_attr(true, unsafe(link_section = ".custom_section"))]
46 #[cfg_attr(true, unsafe(link_section = "__TEXT,__custom"))]
4747 //~^ ERROR: unsafe attribute used without unsafe
4848 //~| WARN this is accepted in the current edition
4949 pub extern "C" fn abc() {}
tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs+5-5
......@@ -15,7 +15,7 @@ macro_rules! ident {
1515 //~^ ERROR: unsafe attribute used without unsafe
1616 //~| WARN this is accepted in the current edition
1717 extern "C" fn bar() {}
18 }
18 };
1919}
2020
2121macro_rules! ident2 {
......@@ -24,26 +24,26 @@ macro_rules! ident2 {
2424 //~^ ERROR: unsafe attribute used without unsafe
2525 //~| WARN this is accepted in the current edition
2626 extern "C" fn bars() {}
27 }
27 };
2828}
2929
3030macro_rules! meta {
3131 ($m:meta) => {
3232 #[$m]
3333 extern "C" fn baz() {}
34 }
34 };
3535}
3636
3737macro_rules! meta2 {
3838 ($m:meta) => {
3939 #[$m]
4040 extern "C" fn baw() {}
41 }
41 };
4242}
4343
4444macro_rules! with_cfg_attr {
4545 () => {
46 #[cfg_attr(true, link_section = ".custom_section")]
46 #[cfg_attr(true, link_section = "__TEXT,__custom")]
4747 //~^ ERROR: unsafe attribute used without unsafe
4848 //~| WARN this is accepted in the current edition
4949 pub extern "C" fn abc() {}
tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr+2-2
......@@ -79,7 +79,7 @@ LL | #[unsafe($e = $l)]
7979error: unsafe attribute used without unsafe
8080 --> $DIR/unsafe-attributes-fix.rs:46:26
8181 |
82LL | #[cfg_attr(true, link_section = ".custom_section")]
82LL | #[cfg_attr(true, link_section = "__TEXT,__custom")]
8383 | ^^^^^^^^^^^^ usage of unsafe attribute
8484...
8585LL | with_cfg_attr!();
......@@ -90,7 +90,7 @@ LL | with_cfg_attr!();
9090 = note: this error originates in the macro `with_cfg_attr` (in Nightly builds, run with -Z macro-backtrace for more info)
9191help: wrap the attribute in `unsafe(...)`
9292 |
93LL | #[cfg_attr(true, unsafe(link_section = ".custom_section"))]
93LL | #[cfg_attr(true, unsafe(link_section = "__TEXT,__custom"))]
9494 | +++++++ +
9595
9696error: unsafe attribute used without unsafe
tests/ui/suggestions/attribute-typos.rs+7
......@@ -8,4 +8,11 @@ fn bar() {}
88//~^ ERROR cannot find attribute `rustc_dumm` in this scope
99//~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
1010
11// Regression test for https://github.com/rust-lang/rust/issues/150566.
12#[cfg_trace] //~ ERROR cannot find attribute `cfg_trace` in this scope
13fn cfg_trace_attr() {}
14
15#[cfg_attr_trace] //~ ERROR cannot find attribute `cfg_attr_trace` in this scope
16fn cfg_attr_trace_attr() {}
17
1118fn main() {}
tests/ui/suggestions/attribute-typos.stderr+13-1
......@@ -4,6 +4,12 @@ error: attributes starting with `rustc` are reserved for use by the `rustc` comp
44LL | #[rustc_dumm]
55 | ^^^^^^^^^^
66
7error: cannot find attribute `cfg_attr_trace` in this scope
8 --> $DIR/attribute-typos.rs:15:3
9 |
10LL | #[cfg_attr_trace]
11 | ^^^^^^^^^^^^^^
12
713error: cannot find attribute `rustc_dumm` in this scope
814 --> $DIR/attribute-typos.rs:7:3
915 |
......@@ -15,6 +21,12 @@ help: a built-in attribute with a similar name exists
1521LL | #[rustc_dummy]
1622 | +
1723
24error: cannot find attribute `cfg_trace` in this scope
25 --> $DIR/attribute-typos.rs:12:3
26 |
27LL | #[cfg_trace]
28 | ^^^^^^^^^
29
1830error: cannot find attribute `tests` in this scope
1931 --> $DIR/attribute-typos.rs:4:3
2032 |
......@@ -41,5 +53,5 @@ help: a built-in attribute with a similar name exists
4153LL | #[deprecated]
4254 | +
4355
44error: aborting due to 4 previous errors
56error: aborting due to 6 previous errors
4557
tests/ui/traits/const-traits/const-drop-fail.new_precise.stderr+19-6
......@@ -1,5 +1,17 @@
1error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
2 --> $DIR/const-drop-fail.rs:19:30
3 |
4LL | struct ConstImplWithDropGlue(NonTrivialDrop);
5 | ^^^^^^^^^^^^^^
6 |
7note: required for this `Drop` impl
8 --> $DIR/const-drop-fail.rs:22:1
9 |
10LL | impl const Drop for ConstImplWithDropGlue {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
113error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
2 --> $DIR/const-drop-fail.rs:34:5
14 --> $DIR/const-drop-fail.rs:35:5
315 |
416LL | const _: () = check($exp);
517 | ----- required by a bound introduced by this call
......@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
820 | ^^^^^^^^^^^^^^
921 |
1022note: required by a bound in `check`
11 --> $DIR/const-drop-fail.rs:25:19
23 --> $DIR/const-drop-fail.rs:26:19
1224 |
1325LL | const fn check<T: [const] Destruct>(_: T) {}
1426 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
1527
1628error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
17 --> $DIR/const-drop-fail.rs:36:5
29 --> $DIR/const-drop-fail.rs:37:5
1830 |
1931LL | const _: () = check($exp);
2032 | ----- required by a bound introduced by this call
......@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
2335 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2436 |
2537note: required by a bound in `check`
26 --> $DIR/const-drop-fail.rs:25:19
38 --> $DIR/const-drop-fail.rs:26:19
2739 |
2840LL | const fn check<T: [const] Destruct>(_: T) {}
2941 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
3042
31error: aborting due to 2 previous errors
43error: aborting due to 3 previous errors
3244
33For more information about this error, try `rustc --explain E0277`.
45Some errors have detailed explanations: E0277, E0367.
46For more information about an error, try `rustc --explain E0277`.
tests/ui/traits/const-traits/const-drop-fail.new_stock.stderr+19-6
......@@ -1,5 +1,17 @@
1error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
2 --> $DIR/const-drop-fail.rs:19:30
3 |
4LL | struct ConstImplWithDropGlue(NonTrivialDrop);
5 | ^^^^^^^^^^^^^^
6 |
7note: required for this `Drop` impl
8 --> $DIR/const-drop-fail.rs:22:1
9 |
10LL | impl const Drop for ConstImplWithDropGlue {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
113error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
2 --> $DIR/const-drop-fail.rs:34:5
14 --> $DIR/const-drop-fail.rs:35:5
315 |
416LL | const _: () = check($exp);
517 | ----- required by a bound introduced by this call
......@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
820 | ^^^^^^^^^^^^^^
921 |
1022note: required by a bound in `check`
11 --> $DIR/const-drop-fail.rs:25:19
23 --> $DIR/const-drop-fail.rs:26:19
1224 |
1325LL | const fn check<T: [const] Destruct>(_: T) {}
1426 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
1527
1628error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
17 --> $DIR/const-drop-fail.rs:36:5
29 --> $DIR/const-drop-fail.rs:37:5
1830 |
1931LL | const _: () = check($exp);
2032 | ----- required by a bound introduced by this call
......@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
2335 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2436 |
2537note: required by a bound in `check`
26 --> $DIR/const-drop-fail.rs:25:19
38 --> $DIR/const-drop-fail.rs:26:19
2739 |
2840LL | const fn check<T: [const] Destruct>(_: T) {}
2941 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
3042
31error: aborting due to 2 previous errors
43error: aborting due to 3 previous errors
3244
33For more information about this error, try `rustc --explain E0277`.
45Some errors have detailed explanations: E0277, E0367.
46For more information about an error, try `rustc --explain E0277`.
tests/ui/traits/const-traits/const-drop-fail.old_precise.stderr+19-6
......@@ -1,5 +1,17 @@
1error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
2 --> $DIR/const-drop-fail.rs:19:30
3 |
4LL | struct ConstImplWithDropGlue(NonTrivialDrop);
5 | ^^^^^^^^^^^^^^
6 |
7note: required for this `Drop` impl
8 --> $DIR/const-drop-fail.rs:22:1
9 |
10LL | impl const Drop for ConstImplWithDropGlue {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
113error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
2 --> $DIR/const-drop-fail.rs:34:5
14 --> $DIR/const-drop-fail.rs:35:5
315 |
416LL | const _: () = check($exp);
517 | ----- required by a bound introduced by this call
......@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
820 | ^^^^^^^^^^^^^^
921 |
1022note: required by a bound in `check`
11 --> $DIR/const-drop-fail.rs:25:19
23 --> $DIR/const-drop-fail.rs:26:19
1224 |
1325LL | const fn check<T: [const] Destruct>(_: T) {}
1426 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
1527
1628error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
17 --> $DIR/const-drop-fail.rs:36:5
29 --> $DIR/const-drop-fail.rs:37:5
1830 |
1931LL | const _: () = check($exp);
2032 | ----- required by a bound introduced by this call
......@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
2335 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2436 |
2537note: required by a bound in `check`
26 --> $DIR/const-drop-fail.rs:25:19
38 --> $DIR/const-drop-fail.rs:26:19
2739 |
2840LL | const fn check<T: [const] Destruct>(_: T) {}
2941 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
3042
31error: aborting due to 2 previous errors
43error: aborting due to 3 previous errors
3244
33For more information about this error, try `rustc --explain E0277`.
45Some errors have detailed explanations: E0277, E0367.
46For more information about an error, try `rustc --explain E0277`.
tests/ui/traits/const-traits/const-drop-fail.old_stock.stderr+19-6
......@@ -1,5 +1,17 @@
1error[E0367]: `NonTrivialDrop` does not implement `[const] Destruct`
2 --> $DIR/const-drop-fail.rs:19:30
3 |
4LL | struct ConstImplWithDropGlue(NonTrivialDrop);
5 | ^^^^^^^^^^^^^^
6 |
7note: required for this `Drop` impl
8 --> $DIR/const-drop-fail.rs:22:1
9 |
10LL | impl const Drop for ConstImplWithDropGlue {
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12
113error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
2 --> $DIR/const-drop-fail.rs:34:5
14 --> $DIR/const-drop-fail.rs:35:5
315 |
416LL | const _: () = check($exp);
517 | ----- required by a bound introduced by this call
......@@ -8,13 +20,13 @@ LL | NonTrivialDrop,
820 | ^^^^^^^^^^^^^^
921 |
1022note: required by a bound in `check`
11 --> $DIR/const-drop-fail.rs:25:19
23 --> $DIR/const-drop-fail.rs:26:19
1224 |
1325LL | const fn check<T: [const] Destruct>(_: T) {}
1426 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
1527
1628error[E0277]: the trait bound `NonTrivialDrop: const Destruct` is not satisfied
17 --> $DIR/const-drop-fail.rs:36:5
29 --> $DIR/const-drop-fail.rs:37:5
1830 |
1931LL | const _: () = check($exp);
2032 | ----- required by a bound introduced by this call
......@@ -23,11 +35,12 @@ LL | ConstImplWithDropGlue(NonTrivialDrop),
2335 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2436 |
2537note: required by a bound in `check`
26 --> $DIR/const-drop-fail.rs:25:19
38 --> $DIR/const-drop-fail.rs:26:19
2739 |
2840LL | const fn check<T: [const] Destruct>(_: T) {}
2941 | ^^^^^^^^^^^^^^^^ required by this bound in `check`
3042
31error: aborting due to 2 previous errors
43error: aborting due to 3 previous errors
3244
33For more information about this error, try `rustc --explain E0277`.
45Some errors have detailed explanations: E0277, E0367.
46For more information about an error, try `rustc --explain E0277`.
tests/ui/traits/const-traits/const-drop-fail.rs+1
......@@ -17,6 +17,7 @@ impl Drop for NonTrivialDrop {
1717}
1818
1919struct ConstImplWithDropGlue(NonTrivialDrop);
20//~^ ERROR: `NonTrivialDrop` does not implement `[const] Destruct`
2021
2122impl const Drop for ConstImplWithDropGlue {
2223 fn drop(&mut self) {}
tests/ui/traits/const-traits/minicore-drop-fail.rs+1-1
......@@ -19,7 +19,7 @@ const trait Foo {}
1919impl Foo for () {}
2020
2121struct Conditional<T: Foo>(T);
22impl<T> const Drop for Conditional<T> where T: [const] Foo {
22impl<T> const Drop for Conditional<T> where T: [const] Foo + [const] Destruct {
2323 fn drop(&mut self) {}
2424}
2525
triagebot.toml+4-1
......@@ -1283,7 +1283,7 @@ Please ensure that if you've changed the output:
12831283"""
12841284cc = ["@aDotInTheVoid", "@obi1kenobi"]
12851285
1286[mentions."tests/ui/deriving/deriving-all-codegen.stdout"]
1286[mentions."tests/ui/derives/deriving-all-codegen.stdout"]
12871287message = "Changes to the code generated for builtin derived traits."
12881288cc = ["@nnethercote"]
12891289
......@@ -1345,6 +1345,9 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
13451345[mentions."tests/codegen-llvm/stack-protector.rs"]
13461346cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]
13471347
1348[mentions."tests/debuginfo/basic-stepping.rs"]
1349cc = ["@Enselic"]
1350
13481351[mentions."tests/ui/sanitizer"]
13491352cc = ["@rcvalle"]
13501353