From 321cd2aa25318eb2f565b06d26ced5111e1fd15f Mon Sep 17 00:00:00 2001 From: cyrgani Date: Mon, 22 Sep 2025 22:55:22 +0200 Subject: [PATCH 01/15] remove duplicated columns from `rustc_error_code::error_codes!` --- .../src/error_codes/E0773.md | 2 +- compiler/rustc_error_codes/src/lib.rs | 1040 ++++++++--------- compiler/rustc_errors/src/codes.rs | 8 +- compiler/rustc_errors/src/lib.rs | 1 + src/tools/tidy/src/error_codes.rs | 46 +- 5 files changed, 535 insertions(+), 562 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md index 5ebb43c6683e5..91cf005d5471b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0773.md +++ b/compiler/rustc_error_codes/src/error_codes/E0773.md @@ -1,4 +1,4 @@ -#### this error code is no longer emitted by the compiler. +#### Note: this error code is no longer emitted by the compiler. This was triggered when multiple macro definitions used the same `#[rustc_builtin_macro(..)]`. This is no longer an error. diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index 0aff1c06e0a8c..a7bcab4447888 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -21,533 +21,531 @@ // Also, the contents of this macro is checked by tidy (in `check_error_codes_docs`). If you change // the macro syntax you will need to change tidy as well. // -// Both columns are necessary because it's not possible in Rust to create a new identifier such as -// `E0123` from an integer literal such as `0123`, unfortunately. -// -// Do *not* remove entries from this list. Instead, just add a note th the corresponding markdown +// Do *not* remove entries from this list. Instead, just add a note to the corresponding markdown // file saying that this error is not emitted by the compiler any more (see E0001.md for an // example), and remove all code examples that do not build any more. #[macro_export] +#[rustfmt::skip] macro_rules! error_codes { ($macro:path) => ( $macro!( -E0001: 0001, -E0002: 0002, -E0004: 0004, -E0005: 0005, -E0007: 0007, -E0009: 0009, -E0010: 0010, -E0013: 0013, -E0014: 0014, -E0015: 0015, -E0023: 0023, -E0025: 0025, -E0026: 0026, -E0027: 0027, -E0029: 0029, -E0030: 0030, -E0033: 0033, -E0034: 0034, -E0038: 0038, -E0040: 0040, -E0044: 0044, -E0045: 0045, -E0046: 0046, -E0049: 0049, -E0050: 0050, -E0053: 0053, -E0054: 0054, -E0055: 0055, -E0057: 0057, -E0059: 0059, -E0060: 0060, -E0061: 0061, -E0062: 0062, -E0063: 0063, -E0067: 0067, -E0069: 0069, -E0070: 0070, -E0071: 0071, -E0072: 0072, -E0073: 0073, -E0074: 0074, -E0075: 0075, -E0076: 0076, -E0077: 0077, -E0080: 0080, -E0081: 0081, -E0084: 0084, -E0087: 0087, -E0088: 0088, -E0089: 0089, -E0090: 0090, -E0091: 0091, -E0092: 0092, -E0093: 0093, -E0094: 0094, -E0106: 0106, -E0107: 0107, -E0109: 0109, -E0110: 0110, -E0116: 0116, -E0117: 0117, -E0118: 0118, -E0119: 0119, -E0120: 0120, -E0121: 0121, -E0124: 0124, -E0128: 0128, -E0130: 0130, -E0131: 0131, -E0132: 0132, -E0133: 0133, -E0136: 0136, -E0137: 0137, -E0138: 0138, -E0139: 0139, -E0152: 0152, -E0154: 0154, -E0158: 0158, -E0161: 0161, -E0162: 0162, -E0164: 0164, -E0165: 0165, -E0170: 0170, -E0178: 0178, -E0183: 0183, -E0184: 0184, -E0185: 0185, -E0186: 0186, -E0191: 0191, -E0192: 0192, -E0193: 0193, -E0195: 0195, -E0197: 0197, -E0198: 0198, -E0199: 0199, -E0200: 0200, -E0201: 0201, -E0203: 0203, -E0204: 0204, -E0205: 0205, -E0206: 0206, -E0207: 0207, -E0208: 0208, -E0210: 0210, -E0211: 0211, -E0212: 0212, -E0214: 0214, -E0220: 0220, -E0221: 0221, -E0222: 0222, -E0223: 0223, -E0224: 0224, -E0225: 0225, -E0226: 0226, -E0227: 0227, -E0228: 0228, -E0229: 0229, -E0230: 0230, -E0231: 0231, -E0232: 0232, -E0243: 0243, -E0244: 0244, -E0251: 0251, -E0252: 0252, -E0253: 0253, -E0254: 0254, -E0255: 0255, -E0256: 0256, -E0259: 0259, -E0260: 0260, -E0261: 0261, -E0262: 0262, -E0263: 0263, -E0264: 0264, -E0267: 0267, -E0268: 0268, -E0271: 0271, -E0275: 0275, -E0276: 0276, -E0277: 0277, -E0281: 0281, -E0282: 0282, -E0283: 0283, -E0284: 0284, -E0297: 0297, -E0301: 0301, -E0302: 0302, -E0303: 0303, -E0307: 0307, -E0308: 0308, -E0309: 0309, -E0310: 0310, -E0311: 0311, -E0312: 0312, -E0316: 0316, -E0317: 0317, -E0320: 0320, -E0321: 0321, -E0322: 0322, -E0323: 0323, -E0324: 0324, -E0325: 0325, -E0326: 0326, -E0328: 0328, -E0329: 0329, -E0364: 0364, -E0365: 0365, -E0366: 0366, -E0367: 0367, -E0368: 0368, -E0369: 0369, -E0370: 0370, -E0371: 0371, -E0373: 0373, -E0374: 0374, -E0375: 0375, -E0376: 0376, -E0377: 0377, -E0378: 0378, -E0379: 0379, -E0380: 0380, -E0381: 0381, -E0382: 0382, -E0383: 0383, -E0384: 0384, -E0386: 0386, -E0387: 0387, -E0388: 0388, -E0389: 0389, -E0390: 0390, -E0391: 0391, -E0392: 0392, -E0393: 0393, -E0398: 0398, -E0399: 0399, -E0401: 0401, -E0403: 0403, -E0404: 0404, -E0405: 0405, -E0407: 0407, -E0408: 0408, -E0409: 0409, -E0411: 0411, -E0412: 0412, -E0415: 0415, -E0416: 0416, -E0422: 0422, -E0423: 0423, -E0424: 0424, -E0425: 0425, -E0426: 0426, -E0428: 0428, -E0429: 0429, -E0430: 0430, -E0431: 0431, -E0432: 0432, -E0433: 0433, -E0434: 0434, -E0435: 0435, -E0436: 0436, -E0437: 0437, -E0438: 0438, -E0439: 0439, -E0445: 0445, -E0446: 0446, -E0447: 0447, -E0448: 0448, -E0449: 0449, -E0451: 0451, -E0452: 0452, -E0453: 0453, -E0454: 0454, -E0455: 0455, -E0457: 0457, -E0458: 0458, -E0459: 0459, -E0460: 0460, -E0461: 0461, -E0462: 0462, -E0463: 0463, -E0464: 0464, -E0466: 0466, -E0468: 0468, -E0469: 0469, -E0472: 0472, -E0476: 0476, -E0477: 0477, -E0478: 0478, -E0482: 0482, -E0491: 0491, -E0492: 0492, -E0493: 0493, -E0495: 0495, -E0496: 0496, -E0497: 0497, -E0498: 0498, -E0499: 0499, -E0500: 0500, -E0501: 0501, -E0502: 0502, -E0503: 0503, -E0504: 0504, -E0505: 0505, -E0506: 0506, -E0507: 0507, -E0508: 0508, -E0509: 0509, -E0510: 0510, -E0511: 0511, -E0512: 0512, -E0514: 0514, -E0515: 0515, -E0516: 0516, -E0517: 0517, -E0518: 0518, -E0519: 0519, -E0520: 0520, -E0521: 0521, -E0522: 0522, -E0523: 0523, -E0524: 0524, -E0525: 0525, -E0527: 0527, -E0528: 0528, -E0529: 0529, -E0530: 0530, -E0531: 0531, -E0532: 0532, -E0533: 0533, -E0534: 0534, -E0535: 0535, -E0536: 0536, -E0537: 0537, -E0538: 0538, -E0539: 0539, -E0541: 0541, -E0542: 0542, -E0543: 0543, -E0544: 0544, -E0545: 0545, -E0546: 0546, -E0547: 0547, -E0549: 0549, -E0550: 0550, -E0551: 0551, -E0552: 0552, -E0554: 0554, -E0556: 0556, -E0557: 0557, -E0559: 0559, -E0560: 0560, -E0561: 0561, -E0562: 0562, -E0565: 0565, -E0566: 0566, -E0567: 0567, -E0568: 0568, -E0569: 0569, -E0570: 0570, -E0571: 0571, -E0572: 0572, -E0573: 0573, -E0574: 0574, -E0575: 0575, -E0576: 0576, -E0577: 0577, -E0578: 0578, -E0579: 0579, -E0580: 0580, -E0581: 0581, -E0582: 0582, -E0583: 0583, -E0584: 0584, -E0585: 0585, -E0586: 0586, -E0587: 0587, -E0588: 0588, -E0589: 0589, -E0590: 0590, -E0591: 0591, -E0592: 0592, -E0593: 0593, -E0594: 0594, -E0595: 0595, -E0596: 0596, -E0597: 0597, -E0599: 0599, -E0600: 0600, -E0601: 0601, -E0602: 0602, -E0603: 0603, -E0604: 0604, -E0605: 0605, -E0606: 0606, -E0607: 0607, -E0608: 0608, -E0609: 0609, -E0610: 0610, -E0614: 0614, -E0615: 0615, -E0616: 0616, -E0617: 0617, -E0618: 0618, -E0619: 0619, -E0620: 0620, -E0621: 0621, -E0622: 0622, // REMOVED: rustc-intrinsic ABI was removed -E0623: 0623, -E0624: 0624, -E0625: 0625, -E0626: 0626, -E0627: 0627, -E0628: 0628, -E0631: 0631, -E0632: 0632, -E0633: 0633, -E0634: 0634, -E0635: 0635, -E0636: 0636, -E0637: 0637, -E0638: 0638, -E0639: 0639, -E0640: 0640, -E0641: 0641, -E0642: 0642, -E0643: 0643, -E0644: 0644, -E0646: 0646, -E0647: 0647, -E0648: 0648, -E0657: 0657, -E0658: 0658, -E0659: 0659, -E0660: 0660, -E0661: 0661, -E0662: 0662, -E0663: 0663, -E0664: 0664, -E0665: 0665, -E0666: 0666, -E0667: 0667, -E0668: 0668, -E0669: 0669, -E0670: 0670, -E0671: 0671, -E0687: 0687, -E0688: 0688, -E0689: 0689, -E0690: 0690, -E0691: 0691, -E0692: 0692, -E0693: 0693, -E0695: 0695, -E0696: 0696, -E0697: 0697, -E0698: 0698, -E0699: 0699, // REMOVED: merged into generic inference var error -E0700: 0700, -E0701: 0701, -E0703: 0703, -E0704: 0704, -E0705: 0705, -E0706: 0706, -E0708: 0708, -E0710: 0710, -E0712: 0712, -E0713: 0713, -E0714: 0714, -E0715: 0715, -E0716: 0716, -E0711: 0711, -E0717: 0717, -E0718: 0718, -E0719: 0719, -E0720: 0720, -E0722: 0722, -E0724: 0724, -E0725: 0725, -E0726: 0726, -E0727: 0727, -E0728: 0728, -E0729: 0729, -E0730: 0730, -E0731: 0731, -E0732: 0732, -E0733: 0733, -E0734: 0734, -E0735: 0735, -E0736: 0736, -E0737: 0737, -E0739: 0739, -E0740: 0740, -E0741: 0741, -E0742: 0742, -E0743: 0743, -E0744: 0744, -E0745: 0745, -E0746: 0746, -E0747: 0747, -E0748: 0748, -E0749: 0749, -E0750: 0750, -E0751: 0751, -E0752: 0752, -E0753: 0753, -E0754: 0754, -E0755: 0755, -E0756: 0756, -E0757: 0757, -E0758: 0758, -E0759: 0759, -E0760: 0760, -E0761: 0761, -E0762: 0762, -E0763: 0763, -E0764: 0764, -E0765: 0765, -E0766: 0766, -E0767: 0767, -E0768: 0768, -E0769: 0769, -E0770: 0770, -E0771: 0771, -E0772: 0772, -E0773: 0773, -E0774: 0774, -E0775: 0775, -E0776: 0776, -E0777: 0777, -E0778: 0778, -E0779: 0779, -E0780: 0780, -E0781: 0781, -E0782: 0782, -E0783: 0783, -E0784: 0784, -E0785: 0785, -E0786: 0786, -E0787: 0787, -E0788: 0788, -E0789: 0789, -E0790: 0790, -E0791: 0791, -E0792: 0792, -E0793: 0793, -E0794: 0794, -E0795: 0795, -E0796: 0796, -E0797: 0797, -E0798: 0798, -E0799: 0799, -E0800: 0800, -E0801: 0801, -E0802: 0802, -E0803: 0803, -E0804: 0804, -E0805: 0805, +0001, +0002, +0004, +0005, +0007, +0009, +0010, +0013, +0014, +0015, +0023, +0025, +0026, +0027, +0029, +0030, +0033, +0034, +0038, +0040, +0044, +0045, +0046, +0049, +0050, +0053, +0054, +0055, +0057, +0059, +0060, +0061, +0062, +0063, +0067, +0069, +0070, +0071, +0072, +0073, +0074, +0075, +0076, +0077, +0080, +0081, +0084, +0087, +0088, +0089, +0090, +0091, +0092, +0093, +0094, +0106, +0107, +0109, +0110, +0116, +0117, +0118, +0119, +0120, +0121, +0124, +0128, +0130, +0131, +0132, +0133, +0136, +0137, +0138, +0139, +0152, +0154, +0158, +0161, +0162, +0164, +0165, +0170, +0178, +0183, +0184, +0185, +0186, +0191, +0192, +0193, +0195, +0197, +0198, +0199, +0200, +0201, +0203, +0204, +0205, +0206, +0207, +0208, +0210, +0211, +0212, +0214, +0220, +0221, +0222, +0223, +0224, +0225, +0226, +0227, +0228, +0229, +0230, +0231, +0232, +0243, +0244, +0251, +0252, +0253, +0254, +0255, +0256, +0259, +0260, +0261, +0262, +0263, +0264, +0267, +0268, +0271, +0275, +0276, +0277, +0281, +0282, +0283, +0284, +0297, +0301, +0302, +0303, +0307, +0308, +0309, +0310, +0311, +0312, +0316, +0317, +0320, +0321, +0322, +0323, +0324, +0325, +0326, +0328, +0329, +0364, +0365, +0366, +0367, +0368, +0369, +0370, +0371, +0373, +0374, +0375, +0376, +0377, +0378, +0379, +0380, +0381, +0382, +0383, +0384, +0386, +0387, +0388, +0389, +0390, +0391, +0392, +0393, +0398, +0399, +0401, +0403, +0404, +0405, +0407, +0408, +0409, +0411, +0412, +0415, +0416, +0422, +0423, +0424, +0425, +0426, +0428, +0429, +0430, +0431, +0432, +0433, +0434, +0435, +0436, +0437, +0438, +0439, +0445, +0446, +0447, +0448, +0449, +0451, +0452, +0453, +0454, +0455, +0457, +0458, +0459, +0460, +0461, +0462, +0463, +0464, +0466, +0468, +0469, +0472, +0476, +0477, +0478, +0482, +0491, +0492, +0493, +0495, +0496, +0497, +0498, +0499, +0500, +0501, +0502, +0503, +0504, +0505, +0506, +0507, +0508, +0509, +0510, +0511, +0512, +0514, +0515, +0516, +0517, +0518, +0519, +0520, +0521, +0522, +0523, +0524, +0525, +0527, +0528, +0529, +0530, +0531, +0532, +0533, +0534, +0535, +0536, +0537, +0538, +0539, +0541, +0542, +0543, +0544, +0545, +0546, +0547, +0549, +0550, +0551, +0552, +0554, +0556, +0557, +0559, +0560, +0561, +0562, +0565, +0566, +0567, +0568, +0569, +0570, +0571, +0572, +0573, +0574, +0575, +0576, +0577, +0578, +0579, +0580, +0581, +0582, +0583, +0584, +0585, +0586, +0587, +0588, +0589, +0590, +0591, +0592, +0593, +0594, +0595, +0596, +0597, +0599, +0600, +0601, +0602, +0603, +0604, +0605, +0606, +0607, +0608, +0609, +0610, +0614, +0615, +0616, +0617, +0618, +0619, +0620, +0621, +0622, // REMOVED: rustc-intrinsic ABI was removed +0623, +0624, +0625, +0626, +0627, +0628, +0631, +0632, +0633, +0634, +0635, +0636, +0637, +0638, +0639, +0640, +0641, +0642, +0643, +0644, +0646, +0647, +0648, +0657, +0658, +0659, +0660, +0661, +0662, +0663, +0664, +0665, +0666, +0667, +0668, +0669, +0670, +0671, +0687, +0688, +0689, +0690, +0691, +0692, +0693, +0695, +0696, +0697, +0698, +0699, // REMOVED: merged into generic inference var error +0700, +0701, +0703, +0704, +0705, +0706, +0708, +0710, +0712, +0713, +0714, +0715, +0716, +0711, +0717, +0718, +0719, +0720, +0722, +0724, +0725, +0726, +0727, +0728, +0729, +0730, +0731, +0732, +0733, +0734, +0735, +0736, +0737, +0739, +0740, +0741, +0742, +0743, +0744, +0745, +0746, +0747, +0748, +0749, +0750, +0751, +0752, +0753, +0754, +0755, +0756, +0757, +0758, +0759, +0760, +0761, +0762, +0763, +0764, +0765, +0766, +0767, +0768, +0769, +0770, +0771, +0772, +0773, // REMOVED: no longer an error +0774, +0775, +0776, +0777, +0778, +0779, +0780, +0781, +0782, +0783, +0784, +0785, +0786, +0787, +0788, +0789, +0790, +0791, +0792, +0793, +0794, +0795, +0796, +0797, +0798, +0799, +0800, +0801, +0802, +0803, +0804, +0805, ); ) } diff --git a/compiler/rustc_errors/src/codes.rs b/compiler/rustc_errors/src/codes.rs index 787a8af99b1fb..924924f285eb4 100644 --- a/compiler/rustc_errors/src/codes.rs +++ b/compiler/rustc_errors/src/codes.rs @@ -23,15 +23,15 @@ impl fmt::Display for ErrCode { rustc_error_messages::into_diag_arg_using_display!(ErrCode); macro_rules! define_error_code_constants_and_diagnostics_table { - ($($name:ident: $num:literal,)*) => ( + ($($num:literal,)*) => ( $( - pub const $name: $crate::ErrCode = $crate::ErrCode::from_u32($num); + pub const ${concat(E, $num)}: $crate::ErrCode = $crate::ErrCode::from_u32($num); )* pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[ $( ( - $name, + ${concat(E, $num)}, include_str!( - concat!("../../rustc_error_codes/src/error_codes/", stringify!($name), ".md") + concat!("../../rustc_error_codes/src/error_codes/E", stringify!($num), ".md") ) ), )* ]; diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8869799ce90d9..ad2b3c74270aa 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(default_field_values)] #![feature(error_reporter)] +#![feature(macro_metavar_expr_concat)] #![feature(negative_impls)] #![feature(never_type)] #![feature(rustc_attrs)] diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 83fbefa43d975..240ac839e3e36 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -91,20 +91,16 @@ fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec(); + if chars.next() != Some(',') { check.error(format!( - "{path}:{line_index}: Expected a line with the format `Eabcd: abcd, \ - but got \"{line}\" without a `:` delimiter", + "{path}:{line_index}: Expected a line with the format `abcd,` \ + but got \"{line}\" without a `,` delimiter", )); continue; - }; - - let err_code = split_line.0.to_owned(); + } // If this is a duplicate of another error code, emit a fatal error. if error_codes.contains(&err_code) { @@ -114,35 +110,13 @@ fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec Date: Tue, 2 Dec 2025 16:53:12 -0500 Subject: [PATCH 02/15] rustdoc: Add unstable `--merge-doctests=yes/no/auto` flag This is useful for changing the *default* for whether doctests are merged or not. Currently, that default is solely controlled by `edition = 2024`, which adds a high switching cost to get doctest merging. This flag allows opt-ing in even on earlier additions. Unlike the `edition = 2024` default, `--merge-doctests=yes` gives a hard error if merging fails instead of falling back to running standalone tests. The user has explicitly said they want merging, so we shouldn't silently do something else. `--merge-doctests=auto` is equivalent to the current 2024 edition behavior, but available on earlier editions. --- src/librustdoc/config.rs | 31 +++++++++++++++ src/librustdoc/doctest.rs | 34 ++++++++++------ src/librustdoc/doctest/make.rs | 39 ++++++++++++------- src/librustdoc/doctest/markdown.rs | 4 +- src/librustdoc/lib.rs | 10 ++++- .../output-default.stdout | 4 ++ tests/rustdoc-ui/doctest/force-merge-fail.rs | 18 +++++++++ .../doctest/force-merge-fail.stderr | 6 +++ tests/rustdoc-ui/doctest/force-merge.rs | 25 ++++++++++++ tests/rustdoc-ui/doctest/force-merge.stdout | 8 ++++ tests/rustdoc-ui/doctest/force-no-merge.rs | 24 ++++++++++++ .../rustdoc-ui/doctest/force-no-merge.stdout | 7 ++++ .../rustdoc-ui/doctest/merge-doctests-auto.rs | 28 +++++++++++++ .../doctest/merge-doctests-auto.stdout | 8 ++++ .../doctest/merge-doctests-invalid.rs | 2 + .../doctest/merge-doctests-invalid.stderr | 2 + .../doctest/merge-doctests-unstable.rs | 2 + .../doctest/merge-doctests-unstable.stderr | 2 + 18 files changed, 225 insertions(+), 29 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/force-merge-fail.rs create mode 100644 tests/rustdoc-ui/doctest/force-merge-fail.stderr create mode 100644 tests/rustdoc-ui/doctest/force-merge.rs create mode 100644 tests/rustdoc-ui/doctest/force-merge.stdout create mode 100644 tests/rustdoc-ui/doctest/force-no-merge.rs create mode 100644 tests/rustdoc-ui/doctest/force-no-merge.stdout create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-auto.rs create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-auto.stdout create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-invalid.rs create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-unstable.rs create mode 100644 tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 5d16dff24c69a..e5a4593260a42 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -63,6 +63,15 @@ pub(crate) enum InputMode { HasFile(Input), } +/// Whether to run multiple doctests in the same binary. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +pub(crate) enum MergeDoctests { + #[default] + Never, + Always, + Auto, +} + /// Configuration options for rustdoc. #[derive(Clone)] pub(crate) struct Options { @@ -121,6 +130,8 @@ pub(crate) struct Options { /// Optional path to persist the doctest executables to, defaults to a /// temporary directory if not set. pub(crate) persist_doctests: Option, + /// Whether to merge + pub(crate) merge_doctests: MergeDoctests, /// Runtool to run doctests with pub(crate) test_runtool: Option, /// Arguments to pass to the runtool @@ -801,6 +812,8 @@ impl Options { Ok(result) => result, Err(e) => dcx.fatal(format!("--merge option error: {e}")), }; + let merge_doctests = parse_merge_doctests(matches, edition, dcx); + tracing::debug!("merge_doctests: {merge_doctests:?}"); if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) { dcx.struct_warn( @@ -852,6 +865,7 @@ impl Options { crate_version, test_run_directory, persist_doctests, + merge_doctests, test_runtool, test_runtool_args, test_builder, @@ -1048,3 +1062,20 @@ fn parse_merge(m: &getopts::Matches) -> Result { Some(_) => Err("argument to --merge must be `none`, `shared`, or `finalize`"), } } + +fn parse_merge_doctests( + m: &getopts::Matches, + edition: Edition, + dcx: DiagCtxtHandle<'_>, +) -> MergeDoctests { + match m.opt_str("merge-doctests").as_deref() { + Some("y") | Some("yes") | Some("on") | Some("true") => MergeDoctests::Always, + Some("n") | Some("no") | Some("off") | Some("false") => MergeDoctests::Never, + Some("auto") => MergeDoctests::Auto, + None if edition < Edition::Edition2024 => MergeDoctests::Never, + None => MergeDoctests::Auto, + Some(_) => { + dcx.fatal("argument to --merge-doctests must be a boolean (true/false) or 'auto'") + } + } +} diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 481aa392007c8..cab65181c9401 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -33,7 +33,7 @@ use tempfile::{Builder as TempFileBuilder, TempDir}; use tracing::debug; use self::rust::HirCollector; -use crate::config::{Options as RustdocOptions, OutputFormat}; +use crate::config::{MergeDoctests, Options as RustdocOptions, OutputFormat}; use crate::html::markdown::{ErrorCodes, Ignore, LangString, MdRelLine}; use crate::lint::init_lints; @@ -265,6 +265,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions }; run_tests( + dcx, opts, &rustdoc_options, &unused_extern_reports, @@ -316,6 +317,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions } pub(crate) fn run_tests( + dcx: DiagCtxtHandle<'_>, opts: GlobalTestOptions, rustdoc_options: &Arc, unused_extern_reports: &Arc>>, @@ -368,6 +370,13 @@ pub(crate) fn run_tests( } continue; } + + if rustdoc_options.merge_doctests == MergeDoctests::Always { + let mut diag = dcx.struct_fatal("failed to merge doctests"); + diag.note("requested explicitly on the command line with `--merge-doctests=yes`"); + diag.emit(); + } + // We failed to compile all compatible tests as one so we push them into the // `standalone_tests` doctests. debug!("Failed to compile compatible doctests for edition {} all at once", edition); @@ -645,9 +654,9 @@ fn run_test( // tested as standalone tests. return (Duration::default(), Err(TestFailure::CompileError)); } - if !rustdoc_options.no_capture { - // If `no_capture` is disabled, then we don't display rustc's output when compiling - // the merged doctests. + if !rustdoc_options.no_capture && rustdoc_options.merge_doctests == MergeDoctests::Auto { + // If `no_capture` is disabled, and we might fallback to standalone tests, then we don't + // display rustc's output when compiling the merged doctests. compiler.stderr(Stdio::null()); } // bundled tests are an rlib, loaded by a separate runner executable @@ -728,10 +737,12 @@ fn run_test( // tested as standalone tests. return (instant.elapsed(), Err(TestFailure::CompileError)); } - if !rustdoc_options.no_capture { - // If `no_capture` is disabled, then we don't display rustc's output when compiling - // the merged doctests. + if !rustdoc_options.no_capture && rustdoc_options.merge_doctests == MergeDoctests::Auto { + // If `no_capture` is disabled and we're autodetecting whether to merge, + // we don't display rustc's output when compiling the merged doctests. runner_compiler.stderr(Stdio::null()); + } else { + runner_compiler.stderr(Stdio::inherit()); } runner_compiler.arg("--error-format=short"); debug!("compiler invocation for doctest runner: {runner_compiler:?}"); @@ -888,7 +899,7 @@ impl IndividualTestOptions { DirState::Perm(path) } else { - DirState::Temp(get_doctest_dir().expect("rustdoc needs a tempdir")) + DirState::Temp(get_doctest_dir(options).expect("rustdoc needs a tempdir")) }; Self { outdir, path: test_path } @@ -977,21 +988,20 @@ struct CreateRunnableDocTests { visited_tests: FxHashMap<(String, usize), usize>, unused_extern_reports: Arc>>, compiling_test_count: AtomicUsize, - can_merge_doctests: bool, + can_merge_doctests: MergeDoctests, } impl CreateRunnableDocTests { fn new(rustdoc_options: RustdocOptions, opts: GlobalTestOptions) -> CreateRunnableDocTests { - let can_merge_doctests = rustdoc_options.edition >= Edition::Edition2024; CreateRunnableDocTests { standalone_tests: Vec::new(), mergeable_tests: FxIndexMap::default(), - rustdoc_options: Arc::new(rustdoc_options), opts, visited_tests: FxHashMap::default(), unused_extern_reports: Default::default(), compiling_test_count: AtomicUsize::new(0), - can_merge_doctests, + can_merge_doctests: rustdoc_options.merge_doctests, + rustdoc_options: Arc::new(rustdoc_options), } } diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index e9f5024e494d1..1f5956168d7e8 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -20,6 +20,7 @@ use rustc_span::{DUMMY_SP, FileName, Span, kw}; use tracing::debug; use super::GlobalTestOptions; +use crate::config::MergeDoctests; use crate::display::Joined as _; use crate::html::markdown::LangString; @@ -41,7 +42,7 @@ pub(crate) struct BuildDocTestBuilder<'a> { source: &'a str, crate_name: Option<&'a str>, edition: Edition, - can_merge_doctests: bool, + can_merge_doctests: MergeDoctests, // If `test_id` is `None`, it means we're generating code for a code example "run" link. test_id: Option, lang_str: Option<&'a LangString>, @@ -55,7 +56,7 @@ impl<'a> BuildDocTestBuilder<'a> { source, crate_name: None, edition: DEFAULT_EDITION, - can_merge_doctests: false, + can_merge_doctests: MergeDoctests::Never, test_id: None, lang_str: None, span: DUMMY_SP, @@ -70,7 +71,7 @@ impl<'a> BuildDocTestBuilder<'a> { } #[inline] - pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: bool) -> Self { + pub(crate) fn can_merge_doctests(mut self, can_merge_doctests: MergeDoctests) -> Self { self.can_merge_doctests = can_merge_doctests; self } @@ -117,10 +118,6 @@ impl<'a> BuildDocTestBuilder<'a> { span, global_crate_attrs, } = self; - let can_merge_doctests = can_merge_doctests - && lang_str.is_some_and(|lang_str| { - !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate - }); let result = rustc_driver::catch_fatal_errors(|| { rustc_span::create_session_if_not_set_then(edition, |_| { @@ -155,14 +152,26 @@ impl<'a> BuildDocTestBuilder<'a> { debug!("crate_attrs:\n{crate_attrs}{maybe_crate_attrs}"); debug!("crates:\n{crates}"); debug!("after:\n{everything_else}"); - - // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. - let can_be_merged = can_merge_doctests - && !has_global_allocator - && crate_attrs.is_empty() - // If this is a merged doctest and a defined macro uses `$crate`, then the path will - // not work, so better not put it into merged doctests. - && !(has_macro_def && everything_else.contains("$crate")); + debug!("merge-doctests: {can_merge_doctests:?}"); + + // Up until now, we've been dealing with settings for the whole crate. + // Now, infer settings for this particular test. + let can_be_merged = if can_merge_doctests == MergeDoctests::Auto { + let mut can_merge = false; + // Avoid tests with incompatible attributes. + can_merge |= lang_str.is_some_and(|lang_str| { + !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate + }); + // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. + can_merge &= !has_global_allocator + && crate_attrs.is_empty() + // If this is a merged doctest and a defined macro uses `$crate`, then the path will + // not work, so better not put it into merged doctests. + && !(has_macro_def && everything_else.contains("$crate")); + can_merge + } else { + can_merge_doctests != MergeDoctests::Never + }; DocTestBuilder { supports_color, has_main_fn, diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs index 7f26605f2562c..45f1e8a7fb988 100644 --- a/src/librustdoc/doctest/markdown.rs +++ b/src/librustdoc/doctest/markdown.rs @@ -3,6 +3,7 @@ use std::fs::read_to_string; use std::sync::{Arc, Mutex}; +use rustc_errors::DiagCtxtHandle; use rustc_session::config::Input; use rustc_span::{DUMMY_SP, FileName}; use tempfile::tempdir; @@ -78,7 +79,7 @@ impl DocTestVisitor for MdCollector { } /// Runs any tests/code examples in the markdown file `options.input`. -pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { +pub(crate) fn test(input: &Input, options: Options, dcx: DiagCtxtHandle<'_>) -> Result<(), String> { let input_str = match input { Input::File(path) => { read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))? @@ -118,6 +119,7 @@ pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> { let CreateRunnableDocTests { opts, rustdoc_options, standalone_tests, mergeable_tests, .. } = collector; crate::doctest::run_tests( + dcx, opts, &rustdoc_options, &Arc::new(Mutex::new(Vec::new())), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e4601bfb20d7d..be46c85311a0e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -544,6 +544,14 @@ fn opts() -> Vec { "[toolchain-shared-resources,invocation-specific,dep-info]", ), opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""), + opt( + Unstable, + Opt, + "", + "merge-doctests", + "Force all doctests to be compiled as a single binary, instead of one binary per test. If merging fails, rustdoc will emit a hard error.", + "yes|no|auto", + ), opt( Unstable, Multi, @@ -822,7 +830,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { options.should_test || output_format == config::OutputFormat::Doctest, config::markdown_input(&input), ) { - (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)), + (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options, dcx)), (true, None) => return doctest::run(dcx, input, options), (false, Some(md_input)) => { let md_input = md_input.to_owned(); diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 49eaf7e2e1e0e..4e28be347cbb1 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -154,6 +154,10 @@ Options: Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them + --merge-doctests yes|no|auto + Force all doctests to be compiled as a single binary, + instead of one binary per test. If merging fails, + rustdoc will emit a hard error. --remap-path-prefix FROM=TO Remap source names in compiler messages --show-type-layout diff --git a/tests/rustdoc-ui/doctest/force-merge-fail.rs b/tests/rustdoc-ui/doctest/force-merge-fail.rs new file mode 100644 index 0000000000000..88c36268d072d --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-fail.rs @@ -0,0 +1,18 @@ +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL" + +//~? ERROR failed to merge doctests + +/// These two doctests will fail to force-merge, and should give a hard error as a result. +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name() -> u8; } +/// ``` +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name(); } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-fail.stderr b/tests/rustdoc-ui/doctest/force-merge-fail.stderr new file mode 100644 index 0000000000000..b87807dc5ed7d --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-fail.stderr @@ -0,0 +1,6 @@ +doctest_bundle_2018.rs:$LINE:$COL: error: `unmangled_name` redeclared with a different signature: this signature doesn't match the previous declaration +error: aborting due to 1 previous error +error: failed to merge doctests + | + = note: requested explicitly on the command line with `--merge-doctests=yes` + diff --git a/tests/rustdoc-ui/doctest/force-merge.rs b/tests/rustdoc-ui/doctest/force-merge.rs new file mode 100644 index 0000000000000..bd2f474f8a560 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this contains a +// "merged compilation took ..." message. + +/// ``` +/// let x = 12; +/// ``` +/// +/// These two doctests should be force-merged, even though this uses edition 2018. +/// +/// ``` +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge.stdout b/tests/rustdoc-ui/doctest/force-merge.stdout new file mode 100644 index 0000000000000..94c7909ae0a68 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge.stdout @@ -0,0 +1,8 @@ + +running 2 tests +test $DIR/force-merge.rs - Foo (line 14) ... ok +test $DIR/force-merge.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/force-no-merge.rs b/tests/rustdoc-ui/doctest/force-no-merge.rs new file mode 100644 index 0000000000000..9ddea5fc2e55c --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-no-merge.rs @@ -0,0 +1,24 @@ +//@ edition: 2024 +//@ check-pass +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=no -Z unstable-options +//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL" + +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/// These two doctests should not force-merge, even though this crate has edition 2024 and the +/// individual doctests are not annotated. +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name() -> u8; } +/// ``` +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name(); } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-no-merge.stdout b/tests/rustdoc-ui/doctest/force-no-merge.stdout new file mode 100644 index 0000000000000..513ff77054977 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-no-merge.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-no-merge.rs - Foo (line 15) ... ok +test $DIR/force-no-merge.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/merge-doctests-auto.rs b/tests/rustdoc-ui/doctest/merge-doctests-auto.rs new file mode 100644 index 0000000000000..2e7d0db7a346f --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-auto.rs @@ -0,0 +1,28 @@ +//! `--merge-doctests=auto` should override the edition. + +//@ check-pass +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=auto -Z unstable-options + +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this contains a +// "merged compilation took ..." message. + +/// ``` +/// let x = 12; +/// ``` +/// +/// These two doctests should be auto-merged, even though this uses edition 2018. +/// +/// ``` +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout b/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout new file mode 100644 index 0000000000000..a051ffd606364 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout @@ -0,0 +1,8 @@ + +running 2 tests +test $DIR/merge-doctests-auto.rs - Foo (line 17) ... ok +test $DIR/merge-doctests-auto.rs - Foo (line 23) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs b/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs new file mode 100644 index 0000000000000..cf3a03a901ce7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --merge-doctests=bad-opt -Zunstable-options +//~? ERROR must be a boolean diff --git a/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr b/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr new file mode 100644 index 0000000000000..d232c1b59edbe --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr @@ -0,0 +1,2 @@ +error: argument to --merge-doctests must be a boolean (true/false) or 'auto' + diff --git a/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs b/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs new file mode 100644 index 0000000000000..496e531659a34 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --merge-doctests=no +//~? RAW `-Z unstable-options` flag must also be passed diff --git a/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr b/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr new file mode 100644 index 0000000000000..e8d75342bc8ef --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr @@ -0,0 +1,2 @@ +error: the `-Z unstable-options` flag must also be passed to enable the flag `merge-doctests` + From 3aa4ece95d6ad46ced3ea895fcc634371ff32039 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Wed, 3 Dec 2025 15:48:16 -0500 Subject: [PATCH 03/15] Support `-C save-temps` in rustdoc This allows viewing failed merged doctests. --- src/librustdoc/doctest.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index cab65181c9401..6e0025fe70647 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -123,8 +123,13 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> Ok(()) } -fn get_doctest_dir() -> io::Result { - TempFileBuilder::new().prefix("rustdoctest").tempdir() +fn get_doctest_dir(opts: &RustdocOptions) -> io::Result { + let mut builder = TempFileBuilder::new(); + builder.prefix("rustdoctest"); + if opts.codegen_options.save_temps { + builder.disable_cleanup(true); + } + builder.tempdir() } pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions) { @@ -197,7 +202,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let externs = options.externs.clone(); let json_unused_externs = options.json_unused_externs; - let temp_dir = match get_doctest_dir() + let temp_dir = match get_doctest_dir(&options) .map_err(|error| format!("failed to create temporary directory: {error:?}")) { Ok(temp_dir) => temp_dir, @@ -207,6 +212,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions crate::wrap_return(dcx, generate_args_file(&args_path, &options)); let extract_doctests = options.output_format == OutputFormat::Doctest; + let save_temps = options.codegen_options.save_temps; let result = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); @@ -259,7 +265,9 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions eprintln!("{error}"); // Since some files in the temporary folder are still owned and alive, we need // to manually remove the folder. - let _ = std::fs::remove_dir_all(temp_dir.path()); + if !save_temps { + let _ = std::fs::remove_dir_all(temp_dir.path()); + } std::process::exit(1); } }; From 415953a317f04b0b5ad26b1ded3671a3e2a01532 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Wed, 3 Dec 2025 17:40:10 -0500 Subject: [PATCH 04/15] `--merge-doctests` is a default, not an override --- src/librustdoc/doctest/make.rs | 23 +++++++++-------- .../force-merge-default-not-override.rs | 25 +++++++++++++++++++ .../force-merge-default-not-override.stdout | 7 ++++++ 3 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 tests/rustdoc-ui/doctest/force-merge-default-not-override.rs create mode 100644 tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index 1f5956168d7e8..569206d6ec88e 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -156,21 +156,22 @@ impl<'a> BuildDocTestBuilder<'a> { // Up until now, we've been dealing with settings for the whole crate. // Now, infer settings for this particular test. + // + // Avoid tests with incompatible attributes. + let opt_out = lang_str.is_some_and(|lang_str| { + lang_str.compile_fail || lang_str.test_harness || lang_str.standalone_crate + }); let can_be_merged = if can_merge_doctests == MergeDoctests::Auto { - let mut can_merge = false; - // Avoid tests with incompatible attributes. - can_merge |= lang_str.is_some_and(|lang_str| { - !lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate - }); - // If it contains `#[feature]` or `#[no_std]`, we don't want it to be merged either. - can_merge &= !has_global_allocator - && crate_attrs.is_empty() + // We try to look at the contents of the test to detect whether it should be merged. + // This is not a complete list of possible failures, but it catches many cases. + let will_probably_fail = has_global_allocator + || !crate_attrs.is_empty() // If this is a merged doctest and a defined macro uses `$crate`, then the path will // not work, so better not put it into merged doctests. - && !(has_macro_def && everything_else.contains("$crate")); - can_merge + || (has_macro_def && everything_else.contains("$crate")); + !opt_out && !will_probably_fail } else { - can_merge_doctests != MergeDoctests::Never + can_merge_doctests != MergeDoctests::Never && !opt_out }; DocTestBuilder { supports_color, diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs new file mode 100644 index 0000000000000..9a1e86ade67f5 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this doesn't contains a +// "merged compilation took ..." message. + +/// ```standalone_crate +/// let x = 12; +/// ``` +/// +/// These two doctests should be not be merged, even though this passes `--merge-doctests=yes`. +/// +/// ```standalone_crate +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout new file mode 100644 index 0000000000000..24b16ec82f45b --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-merge-default-not-override.rs - Foo (line 14) ... ok +test $DIR/force-merge-default-not-override.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + From 4d697d243302066fcb5cb6a9daacf7e6cdc891c7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 15:16:41 +0100 Subject: [PATCH 05/15] Remove "tidy" tool for `tests/rustdoc` testsuite --- src/tools/compiletest/src/common.rs | 9 - src/tools/compiletest/src/executor.rs | 9 - src/tools/compiletest/src/lib.rs | 28 +-- src/tools/compiletest/src/runtest.rs | 164 +----------------- .../compiletest/src/runtest/compute_diff.rs | 57 ------ src/tools/compiletest/src/runtest/rustdoc.rs | 4 +- src/tools/compiletest/src/rustdoc_gui_test.rs | 2 - 7 files changed, 8 insertions(+), 265 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 02b93593cbbd4..ddbe8601de204 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -9,7 +9,6 @@ use camino::{Utf8Path, Utf8PathBuf}; use semver::Version; use crate::edition::Edition; -use crate::executor::ColorConfig; use crate::fatal; use crate::util::{Utf8PathBufExt, add_dylib_path, string_enum}; @@ -597,11 +596,6 @@ pub struct Config { /// FIXME: this is *way* too coarse; the user can't select *which* info to verbosely dump. pub verbose: bool, - /// Whether to use colors in test output. - /// - /// Note: the exact control mechanism is delegated to [`colored`]. - pub color: ColorConfig, - /// Where to find the remote test client process, if we're using it. /// /// Note: this is *only* used for target platform executables created by `run-make` test @@ -623,9 +617,6 @@ pub struct Config { /// created in `$test_suite_build_root/rustfix_missing_coverage.txt` pub rustfix_coverage: bool, - /// Whether to run `tidy` (html-tidy) when a rustdoc test fails. - pub has_html_tidy: bool, - /// Whether to run `enzyme` autodiff tests. pub has_enzyme: bool, diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs index 4dd4b1f85aaa7..c800d11d6b2fd 100644 --- a/src/tools/compiletest/src/executor.rs +++ b/src/tools/compiletest/src/executor.rs @@ -341,15 +341,6 @@ pub(crate) struct CollectedTestDesc { pub(crate) should_fail: ShouldFail, } -/// Whether console output should be colored or not. -#[derive(Copy, Clone, Default, Debug)] -pub enum ColorConfig { - #[default] - AutoColor, - AlwaysColor, - NeverColor, -} - /// Tests with `//@ should-fail` are tests of compiletest itself, and should /// be reported as successful if and only if they would have _failed_. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index ff4cd81d33ff6..7c237102ed847 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -24,7 +24,6 @@ use core::panic; use std::collections::HashSet; use std::fmt::Write; use std::io::{self, ErrorKind}; -use std::process::{Command, Stdio}; use std::sync::{Arc, OnceLock}; use std::time::SystemTime; use std::{env, fs, vec}; @@ -43,7 +42,7 @@ use crate::common::{ }; use crate::directives::{AuxProps, DirectivesCache, FileDirectives}; use crate::edition::parse_edition; -use crate::executor::{CollectedTest, ColorConfig}; +use crate::executor::CollectedTest; /// Creates the `Config` instance for this invocation of compiletest. /// @@ -136,8 +135,9 @@ fn parse_config(args: Vec) -> Config { "overwrite stderr/stdout files instead of complaining about a mismatch", ) .optflag("", "fail-fast", "stop as soon as possible after any test fails") - .optopt("", "color", "coloring: auto, always, never", "WHEN") .optopt("", "target", "the target to build for", "TARGET") + // FIXME: Should be removed once `bootstrap` will be updated to not use this option. + .optopt("", "color", "coloring: auto, always, never", "WHEN") .optopt("", "host", "the host to build for", "HOST") .optopt("", "cdb", "path to CDB to use for CDB debuginfo tests", "PATH") .optopt("", "gdb", "path to GDB to use for GDB debuginfo tests", "PATH") @@ -276,12 +276,6 @@ fn parse_config(args: Vec) -> Config { let lldb = matches.opt_str("lldb").map(Utf8PathBuf::from); let lldb_version = matches.opt_str("lldb-version").as_deref().and_then(debuggers::extract_lldb_version); - let color = match matches.opt_str("color").as_deref() { - Some("auto") | None => ColorConfig::AutoColor, - Some("always") => ColorConfig::AlwaysColor, - Some("never") => ColorConfig::NeverColor, - Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x), - }; // FIXME: this is very questionable, we really should be obtaining LLVM version info from // `bootstrap`, and not trying to be figuring out that in `compiletest` by running the // `FileCheck` binary. @@ -306,16 +300,6 @@ fn parse_config(args: Vec) -> Config { let with_rustc_debug_assertions = matches.opt_present("with-rustc-debug-assertions"); let with_std_debug_assertions = matches.opt_present("with-std-debug-assertions"); let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode"); - let has_html_tidy = if mode == TestMode::Rustdoc { - Command::new("tidy") - .arg("--version") - .stdout(Stdio::null()) - .status() - .map_or(false, |status| status.success()) - } else { - // Avoid spawning an external command when we know html-tidy won't be used. - false - }; let has_enzyme = matches.opt_present("has-enzyme"); let filters = if mode == TestMode::RunMake { matches @@ -457,11 +441,9 @@ fn parse_config(args: Vec) -> Config { adb_device_status, verbose: matches.opt_present("verbose"), only_modified: matches.opt_present("only-modified"), - color, remote_test_client: matches.opt_str("remote-test-client").map(Utf8PathBuf::from), compare_mode, rustfix_coverage: matches.opt_present("rustfix-coverage"), - has_html_tidy, has_enzyme, channel: matches.opt_str("channel").unwrap(), git_hash: matches.opt_present("git-hash"), @@ -1146,10 +1128,6 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet) { } fn early_config_check(config: &Config) { - if !config.has_html_tidy && config.mode == TestMode::Rustdoc { - warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated"); - } - if !config.profiler_runtime && config.mode == TestMode::CoverageRun { let actioned = if config.bless { "blessed" } else { "checked" }; warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}"); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 54d6e0190ddca..f28f70ed453ea 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1,12 +1,11 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::ffi::OsString; -use std::fs::{self, File, create_dir_all}; +use std::fs::{self, create_dir_all}; use std::hash::{DefaultHasher, Hash, Hasher}; use std::io::prelude::*; -use std::io::{self, BufReader}; use std::process::{Child, Command, ExitStatus, Output, Stdio}; -use std::{env, fmt, iter, str}; +use std::{env, fmt, io, iter, str}; use build_helper::fs::remove_and_create_dir_all; use camino::{Utf8Path, Utf8PathBuf}; @@ -23,9 +22,9 @@ use crate::directives::TestProps; use crate::errors::{Error, ErrorKind, load_errors}; use crate::output_capture::ConsoleOut; use crate::read2::{Truncated, read2_abbreviated}; -use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff}; +use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff}; use crate::util::{Utf8PathBufExt, add_dylib_path, static_regex}; -use crate::{ColorConfig, help, json, stamp_file_path, warning}; +use crate::{json, stamp_file_path}; // Helper modules that implement test running logic for each test suite. // tidy-alphabetical-start @@ -2162,161 +2161,6 @@ impl<'test> TestCx<'test> { if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" } } - fn compare_to_default_rustdoc(&self, out_dir: &Utf8Path) { - if !self.config.has_html_tidy { - return; - } - writeln!(self.stdout, "info: generating a diff against nightly rustdoc"); - - let suffix = - self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); - let compare_dir = output_base_dir(self.config, self.testpaths, Some(&suffix)); - remove_and_create_dir_all(&compare_dir).unwrap_or_else(|e| { - panic!("failed to remove and recreate output directory `{compare_dir}`: {e}") - }); - - // We need to create a new struct for the lifetimes on `config` to work. - let new_rustdoc = TestCx { - config: &Config { - // FIXME: use beta or a user-specified rustdoc instead of - // hardcoding the default toolchain - rustdoc_path: Some("rustdoc".into()), - // Needed for building auxiliary docs below - rustc_path: "rustc".into(), - ..self.config.clone() - }, - ..*self - }; - - let output_file = TargetLocation::ThisDirectory(new_rustdoc.aux_output_dir_name()); - let mut rustc = new_rustdoc.make_compile_args( - &new_rustdoc.testpaths.file, - output_file, - Emit::None, - AllowUnused::Yes, - LinkToAux::Yes, - Vec::new(), - ); - let aux_dir = new_rustdoc.aux_output_dir(); - new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc); - - let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html); - if !proc_res.status.success() { - writeln!(self.stderr, "failed to run nightly rustdoc"); - return; - } - - #[rustfmt::skip] - let tidy_args = [ - "--new-blocklevel-tags", "rustdoc-search,rustdoc-toolbar,rustdoc-topbar", - "--indent", "yes", - "--indent-spaces", "2", - "--wrap", "0", - "--show-warnings", "no", - "--markup", "yes", - "--quiet", "yes", - "-modify", - ]; - let tidy_dir = |dir| { - for entry in walkdir::WalkDir::new(dir) { - let entry = entry.expect("failed to read file"); - if entry.file_type().is_file() - && entry.path().extension().and_then(|p| p.to_str()) == Some("html") - { - let status = - Command::new("tidy").args(&tidy_args).arg(entry.path()).status().unwrap(); - // `tidy` returns 1 if it modified the file. - assert!(status.success() || status.code() == Some(1)); - } - } - }; - tidy_dir(out_dir); - tidy_dir(&compare_dir); - - let pager = { - let output = Command::new("git").args(&["config", "--get", "core.pager"]).output().ok(); - output.and_then(|out| { - if out.status.success() { - Some(String::from_utf8(out.stdout).expect("invalid UTF8 in git pager")) - } else { - None - } - }) - }; - - let diff_filename = format!("build/tmp/rustdoc-compare-{}.diff", std::process::id()); - - if !write_filtered_diff( - self, - &diff_filename, - out_dir, - &compare_dir, - self.config.verbose, - |file_type, extension| { - file_type.is_file() && (extension == Some("html") || extension == Some("js")) - }, - ) { - return; - } - - match self.config.color { - ColorConfig::AlwaysColor => colored::control::set_override(true), - ColorConfig::NeverColor => colored::control::set_override(false), - _ => {} - } - - if let Some(pager) = pager { - let pager = pager.trim(); - if self.config.verbose { - writeln!(self.stderr, "using pager {}", pager); - } - let output = Command::new(pager) - // disable paging; we want this to be non-interactive - .env("PAGER", "") - .stdin(File::open(&diff_filename).unwrap()) - // Capture output and print it explicitly so it will in turn be - // captured by output-capture. - .output() - .unwrap(); - assert!(output.status.success()); - writeln!(self.stdout, "{}", String::from_utf8_lossy(&output.stdout)); - writeln!(self.stderr, "{}", String::from_utf8_lossy(&output.stderr)); - } else { - warning!("no pager configured, falling back to unified diff"); - help!( - "try configuring a git pager (e.g. `delta`) with \ - `git config --global core.pager delta`" - ); - let mut out = io::stdout(); - let mut diff = BufReader::new(File::open(&diff_filename).unwrap()); - let mut line = Vec::new(); - loop { - line.truncate(0); - match diff.read_until(b'\n', &mut line) { - Ok(0) => break, - Ok(_) => {} - Err(e) => writeln!(self.stderr, "ERROR: {:?}", e), - } - match String::from_utf8(line.clone()) { - Ok(line) => { - if line.starts_with('+') { - write!(&mut out, "{}", line.green()).unwrap(); - } else if line.starts_with('-') { - write!(&mut out, "{}", line.red()).unwrap(); - } else if line.starts_with('@') { - write!(&mut out, "{}", line.blue()).unwrap(); - } else { - out.write_all(line.as_bytes()).unwrap(); - } - } - Err(_) => { - write!(&mut out, "{}", String::from_utf8_lossy(&line).reversed()).unwrap(); - } - } - } - }; - } - fn get_lines(&self, path: &Utf8Path, mut other_files: Option<&mut Vec>) -> Vec { let content = fs::read_to_string(path.as_std_path()).unwrap(); let mut ignore = false; diff --git a/src/tools/compiletest/src/runtest/compute_diff.rs b/src/tools/compiletest/src/runtest/compute_diff.rs index 3363127b3ea37..8418dcbaf9639 100644 --- a/src/tools/compiletest/src/runtest/compute_diff.rs +++ b/src/tools/compiletest/src/runtest/compute_diff.rs @@ -1,9 +1,4 @@ use std::collections::VecDeque; -use std::fs::{File, FileType}; - -use camino::Utf8Path; - -use crate::runtest::TestCx; #[derive(Debug, PartialEq)] pub enum DiffLine { @@ -109,55 +104,3 @@ pub(crate) fn write_diff(expected: &str, actual: &str, context_size: usize) -> S } output } - -/// Filters based on filetype and extension whether to diff a file. -/// -/// Returns whether any data was actually written. -pub(crate) fn write_filtered_diff( - cx: &TestCx<'_>, - diff_filename: &str, - out_dir: &Utf8Path, - compare_dir: &Utf8Path, - verbose: bool, - filter: Filter, -) -> bool -where - Filter: Fn(FileType, Option<&str>) -> bool, -{ - use std::io::{Read, Write}; - let mut diff_output = File::create(diff_filename).unwrap(); - let mut wrote_data = false; - for entry in walkdir::WalkDir::new(out_dir.as_std_path()) { - let entry = entry.expect("failed to read file"); - let extension = entry.path().extension().and_then(|p| p.to_str()); - if filter(entry.file_type(), extension) { - let expected_path = compare_dir - .as_std_path() - .join(entry.path().strip_prefix(&out_dir.as_std_path()).unwrap()); - let expected = if let Ok(s) = std::fs::read(&expected_path) { s } else { continue }; - let actual_path = entry.path(); - let actual = std::fs::read(&actual_path).unwrap(); - let diff = unified_diff::diff( - &expected, - &expected_path.to_str().unwrap(), - &actual, - &actual_path.to_str().unwrap(), - 3, - ); - wrote_data |= !diff.is_empty(); - diff_output.write_all(&diff).unwrap(); - } - } - - if !wrote_data { - writeln!(cx.stdout, "note: diff is identical to nightly rustdoc"); - assert!(diff_output.metadata().unwrap().len() == 0); - return false; - } else if verbose { - writeln!(cx.stderr, "printing diff:"); - let mut buf = Vec::new(); - diff_output.read_to_end(&mut buf).unwrap(); - std::io::stderr().lock().write_all(&mut buf).unwrap(); - } - true -} diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index a4558de5f1c0c..3c80521e51ecd 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -28,9 +28,7 @@ impl TestCx<'_> { } let res = self.run_command_to_procres(&mut cmd); if !res.status.success() { - self.fatal_proc_rec_general("htmldocck failed!", None, &res, || { - self.compare_to_default_rustdoc(&out_dir); - }); + self.fatal_proc_rec("htmldocck failed!", &res); } } } diff --git a/src/tools/compiletest/src/rustdoc_gui_test.rs b/src/tools/compiletest/src/rustdoc_gui_test.rs index f6d026ab9cfd6..c30f3d1e10ea8 100644 --- a/src/tools/compiletest/src/rustdoc_gui_test.rs +++ b/src/tools/compiletest/src/rustdoc_gui_test.rs @@ -108,11 +108,9 @@ fn incomplete_config_for_rustdoc_gui_test() -> Config { adb_test_dir: Default::default(), adb_device_status: Default::default(), verbose: Default::default(), - color: Default::default(), remote_test_client: Default::default(), compare_mode: Default::default(), rustfix_coverage: Default::default(), - has_html_tidy: Default::default(), has_enzyme: Default::default(), channel: Default::default(), git_hash: Default::default(), From 450916305fe8482dfe2f192c0d288b0490d3a517 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 11 Jun 2025 21:29:06 +0200 Subject: [PATCH 06/15] Put negative implementors first and apply same ordering logic to foreign implementors --- src/librustdoc/formats/mod.rs | 4 ++ src/librustdoc/html/render/print_item.rs | 43 ++++++++++++++++-- src/librustdoc/html/render/write_shared.rs | 45 +++++++++++++++++-- .../html/render/write_shared/tests.rs | 6 +-- src/librustdoc/html/static/css/rustdoc.css | 3 ++ src/librustdoc/html/static/js/main.js | 39 ++++++++++++---- src/librustdoc/html/static/js/rustdoc.d.ts | 2 +- 7 files changed, 122 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index 2e8b5d9f59489..80c110ec07f56 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -76,4 +76,8 @@ impl Impl { }; true } + + pub(crate) fn is_negative_trait_impl(&self) -> bool { + self.inner_impl().is_negative_trait_impl() + } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0c511738d7c8a..47e5876263526 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -646,6 +646,27 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp }) } +/// Struct used to handle insertion of "negative impl" marker in the generated DOM. +/// +/// This marker appears once in all trait impl lists to divide negative impls from positive impls. +struct NegativeMarker { + inserted_negative_marker: bool, +} + +impl NegativeMarker { + fn new() -> Self { + Self { inserted_negative_marker: false } + } + + fn insert_if_needed(&mut self, w: &mut fmt::Formatter<'_>, implementor: &Impl) -> fmt::Result { + if !self.inserted_negative_marker && !implementor.is_negative_trait_impl() { + write!(w, "
")?; + self.inserted_negative_marker = true; + } + Ok(()) + } +} + fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display { fmt::from_fn(|w| { let tcx = cx.tcx(); @@ -1072,7 +1093,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: "
", ) )?; + let mut negative_marker = NegativeMarker::new(); for implementor in concrete { + negative_marker.insert_if_needed(w, implementor)?; write!(w, "{}", render_implementor(cx, implementor, it, &implementor_dups, &[]))?; } w.write_str("
")?; @@ -1088,7 +1111,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: "
", ) )?; + let mut negative_marker = NegativeMarker::new(); for implementor in synthetic { + negative_marker.insert_if_needed(w, implementor)?; write!( w, "{}", @@ -2302,11 +2327,18 @@ where } #[derive(PartialEq, Eq)] -struct ImplString(String); +struct ImplString { + rendered: String, + is_negative: bool, +} impl ImplString { fn new(i: &Impl, cx: &Context<'_>) -> ImplString { - ImplString(format!("{}", print_impl(i.inner_impl(), false, cx))) + let impl_ = i.inner_impl(); + ImplString { + is_negative: impl_.is_negative_trait_impl(), + rendered: format!("{}", print_impl(impl_, false, cx)), + } } } @@ -2318,7 +2350,12 @@ impl PartialOrd for ImplString { impl Ord for ImplString { fn cmp(&self, other: &Self) -> Ordering { - compare_names(&self.0, &other.0) + // We sort negative impls first. + match (self.is_negative, other.is_negative) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + _ => compare_names(&self.rendered, &other.rendered), + } } } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 6bf116c3b75ad..ca33531174b1b 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -14,6 +14,7 @@ //! or contains "invocation-specific". use std::cell::RefCell; +use std::cmp::Ordering; use std::ffi::{OsStr, OsString}; use std::fs::File; use std::io::{self, Write as _}; @@ -47,6 +48,7 @@ use crate::formats::item_type::ItemType; use crate::html::format::{print_impl, print_path}; use crate::html::layout; use crate::html::render::ordered_json::{EscapedJson, OrderedJson}; +use crate::html::render::print_item::compare_names; use crate::html::render::search_index::{SerializedSearchIndex, build_index}; use crate::html::render::sorted_template::{self, FileFormat, SortedTemplate}; use crate::html::render::{AssocItemLink, ImplRenderingParameters, StylePath}; @@ -667,7 +669,7 @@ impl TraitAliasPart { fn blank() -> SortedTemplate<::FileFormat> { SortedTemplate::from_before_after( r"(function() { - var implementors = Object.fromEntries([", + const implementors = Object.fromEntries([", r"]); if (window.register_implementors) { window.register_implementors(implementors); @@ -720,10 +722,12 @@ impl TraitAliasPart { { None } else { + let impl_ = imp.inner_impl(); Some(Implementor { - text: print_impl(imp.inner_impl(), false, cx).to_string(), + text: print_impl(impl_, false, cx).to_string(), synthetic: imp.inner_impl().kind.is_auto(), types: collect_paths_for_type(&imp.inner_impl().for_, cache), + is_negative: impl_.is_negative_trait_impl(), }) } }) @@ -742,8 +746,15 @@ impl TraitAliasPart { } path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); - let part = OrderedJson::array_sorted( - implementors.map(|implementor| OrderedJson::serialize(implementor).unwrap()), + let mut implementors = implementors.collect::>(); + implementors.sort_unstable(); + + let part = OrderedJson::array_unsorted( + implementors + .iter() + .map(OrderedJson::serialize) + .collect::, _>>() + .unwrap(), ); path_parts.push(path, OrderedJson::array_unsorted([crate_name_json, &part])); } @@ -751,10 +762,12 @@ impl TraitAliasPart { } } +#[derive(Eq)] struct Implementor { text: String, synthetic: bool, types: Vec, + is_negative: bool, } impl Serialize for Implementor { @@ -764,6 +777,7 @@ impl Serialize for Implementor { { let mut seq = serializer.serialize_seq(None)?; seq.serialize_element(&self.text)?; + seq.serialize_element(if self.is_negative { &1 } else { &0 })?; if self.synthetic { seq.serialize_element(&1)?; seq.serialize_element(&self.types)?; @@ -772,6 +786,29 @@ impl Serialize for Implementor { } } +impl PartialEq for Implementor { + fn eq(&self, other: &Self) -> bool { + self.cmp(other) == Ordering::Equal + } +} + +impl PartialOrd for Implementor { + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(self, other)) + } +} + +impl Ord for Implementor { + fn cmp(&self, other: &Self) -> Ordering { + // We sort negative impls first. + match (self.is_negative, other.is_negative) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + _ => compare_names(&self.text, &other.text), + } + } +} + /// Collect the list of aliased types and their aliases. /// /// diff --git a/src/librustdoc/html/render/write_shared/tests.rs b/src/librustdoc/html/render/write_shared/tests.rs index 1989a1f87aae6..48d592c22f6f0 100644 --- a/src/librustdoc/html/render/write_shared/tests.rs +++ b/src/librustdoc/html/render/write_shared/tests.rs @@ -68,7 +68,7 @@ fn trait_alias_template() { assert_eq!( but_last_line(&template.to_string()), r#"(function() { - var implementors = Object.fromEntries([]); + const implementors = Object.fromEntries([]); if (window.register_implementors) { window.register_implementors(implementors); } else { @@ -80,7 +80,7 @@ fn trait_alias_template() { assert_eq!( but_last_line(&template.to_string()), r#"(function() { - var implementors = Object.fromEntries([["a"]]); + const implementors = Object.fromEntries([["a"]]); if (window.register_implementors) { window.register_implementors(implementors); } else { @@ -92,7 +92,7 @@ fn trait_alias_template() { assert_eq!( but_last_line(&template.to_string()), r#"(function() { - var implementors = Object.fromEntries([["a"],["b"]]); + const implementors = Object.fromEntries([["a"],["b"]]); if (window.register_implementors) { window.register_implementors(implementors); } else { diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7f47856948493..36f44a8072af9 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -2976,6 +2976,9 @@ in src-script.js and main.js { margin-bottom: 0.75em; } +.negative-marker { + display: none; +} .variants > .docblock, .implementors-toggle > .docblock, diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index dff40485e9a90..fb6b704921818 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -800,21 +800,34 @@ function preLoadCss(cssUrl) { // window.register_implementors = imp => { - const implementors = document.getElementById("implementors-list"); - const synthetic_implementors = document.getElementById("synthetic-implementors-list"); + /** Takes an ID as input and returns a list of two elements. The first element is the DOM + * element with the given ID and the second is the "negative marker", meaning the location + * between the negative and non-negative impls. + * + * @param {string} id: ID of the DOM element. + * + * @return {[HTMLElement|null, HTMLElement|null]} + */ + function implementorsElems(id) { + const elem = document.getElementById(id); + return [elem, elem ? elem.querySelector(".negative-marker") : null]; + } + const implementors = implementorsElems("implementors-list"); + const synthetic_implementors = implementorsElems("synthetic-implementors-list"); const inlined_types = new Set(); const TEXT_IDX = 0; - const SYNTHETIC_IDX = 1; - const TYPES_IDX = 2; + const IS_NEG_IDX = 1; + const SYNTHETIC_IDX = 2; + const TYPES_IDX = 3; - if (synthetic_implementors) { + if (synthetic_implementors[0]) { // This `inlined_types` variable is used to avoid having the same implementation // showing up twice. For example "String" in the "Sync" doc page. // // By the way, this is only used by and useful for traits implemented automatically // (like "Send" and "Sync"). - onEachLazy(synthetic_implementors.getElementsByClassName("impl"), el => { + onEachLazy(synthetic_implementors[0].getElementsByClassName("impl"), el => { const aliases = el.getAttribute("data-aliases"); if (!aliases) { return; @@ -827,7 +840,7 @@ function preLoadCss(cssUrl) { } // @ts-expect-error - let currentNbImpls = implementors.getElementsByClassName("impl").length; + let currentNbImpls = implementors[0].getElementsByClassName("impl").length; // @ts-expect-error const traitName = document.querySelector(".main-heading h1 > .trait").textContent; const baseIdName = "impl-" + traitName + "-"; @@ -884,8 +897,16 @@ function preLoadCss(cssUrl) { addClass(display, "impl"); display.appendChild(anchor); display.appendChild(code); - // @ts-expect-error - list.appendChild(display); + + // If this is a negative implementor, we put it into the right location (just + // before the negative impl marker). + if (struct[IS_NEG_IDX]) { + // @ts-expect-error + list[1].before(display); + } else { + // @ts-expect-error + list[0].appendChild(display); + } currentNbImpls += 1; } } diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 18d3b6a455d3e..60df4fc10b8c5 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -520,7 +520,7 @@ declare namespace rustdoc { * Provided by generated `trait.impl` files. */ type Implementors = { - [key: string]: Array<[string, number, Array]> + [key: string]: Array<[string, 0|1, number, Array]> } type TypeImpls = { From 985178dacf81d2baa21d0261c2cc85b374d0dd8c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 11 Jun 2025 22:19:47 +0200 Subject: [PATCH 07/15] Add GUI test to ensure that negative impls are correctly sorted --- tests/rustdoc-gui/implementors.goml | 47 +++++++++++++++---- .../rustdoc-gui/src/lib2/implementors/lib.rs | 5 ++ tests/rustdoc-gui/src/lib2/lib.rs | 3 ++ 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/tests/rustdoc-gui/implementors.goml b/tests/rustdoc-gui/implementors.goml index b39b95c1a9bff..99fb9b9aff54f 100644 --- a/tests/rustdoc-gui/implementors.goml +++ b/tests/rustdoc-gui/implementors.goml @@ -2,18 +2,45 @@ // have the same display than the "local" ones. go-to: "file://" + |DOC_PATH| + "/implementors/trait.Whatever.html" assert: "#implementors-list" -// There are supposed to be two implementors listed. -assert-count: ("#implementors-list .impl", 2) +// There are supposed to be four implementors listed. +assert-count: ("#implementors-list .impl", 4) +// There are supposed to be two non-negative implementors. +assert-count: ("#implementors-list .negative-marker ~ *", 2) // Now we check that both implementors have an anchor, an ID and a similar DOM. -assert: ("#implementors-list .impl:nth-child(1) > a.anchor") -assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"}) -assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"}) -assert: "#implementors-list .impl:nth-child(1) > .code-header" +define-function: ( + "check-dom", + [id], + block { + assert-attribute: (|id| + " > a.anchor", {"href": |id|}) + assert: |id| + " > .code-header" + }, +) + +call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct2"}) +call-function: ("check-dom", {"id": "#impl-Whatever-2"}) +call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct"}) +call-function: ("check-dom", {"id": "#impl-Whatever-3"}) -assert: ("#implementors-list .impl:nth-child(2) > a.anchor") -assert-attribute: ("#implementors-list .impl:nth-child(2)", {"id": "impl-Whatever-1"}) -assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"}) -assert: "#implementors-list .impl:nth-child(2) > .code-header" +// Ensure that negative impl are sorted first. +assert-property: ( + "#implementors-list > *:nth-child(1) > h3", + {"textContent": "impl !Whatever for Struct2"}, +) +assert-property: ( + "#implementors-list > *:nth-child(2) > h3", + {"textContent": "impl !Whatever for StructToImplOnReexport"}, +) +// Third one is the negative marker. +assert-attribute: ("#implementors-list > *:nth-child(3)", {"class": "negative-marker"}) +// This one is a `` so the selector is a bit different. +assert-property: ( + "#implementors-list > *:nth-child(4) section > h3", + {"textContent": "impl Whatever for Struct"}, +) +assert-property: ( + "#implementors-list > *:nth-child(5) > h3", + {"textContent": "impl Whatever for Foo"}, +) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HasEmptyTraits.html" compare-elements-position-near-false: ( diff --git a/tests/rustdoc-gui/src/lib2/implementors/lib.rs b/tests/rustdoc-gui/src/lib2/implementors/lib.rs index 2842ac50dc1e8..f081820039275 100644 --- a/tests/rustdoc-gui/src/lib2/implementors/lib.rs +++ b/tests/rustdoc-gui/src/lib2/implementors/lib.rs @@ -1,3 +1,5 @@ +#![feature(negative_impls)] + pub trait Whatever { type Foo; @@ -5,11 +7,14 @@ pub trait Whatever { } pub struct Struct; +pub struct Struct2; impl Whatever for Struct { type Foo = u8; } +impl !Whatever for Struct2 {} + impl http::HttpTrait for Struct {} mod traits { diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs index 400488cbe8570..b87fdeea89da0 100644 --- a/tests/rustdoc-gui/src/lib2/lib.rs +++ b/tests/rustdoc-gui/src/lib2/lib.rs @@ -1,6 +1,7 @@ // ignore-tidy-linelength #![feature(doc_cfg)] +#![feature(negative_impls)] pub mod another_folder; pub mod another_mod; @@ -60,6 +61,8 @@ impl implementors::Whatever for Foo { type Foo = u32; } +impl !implementors::Whatever for StructToImplOnReexport {} + #[doc(inline)] pub use implementors::TraitToReexport; From 13091ddc932be37c0ad3db7581e5f7776cf429d0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Jun 2025 17:05:43 +0200 Subject: [PATCH 08/15] Make implementors list visible only when filled --- src/librustdoc/html/static/css/noscript.css | 4 ++++ src/librustdoc/html/static/css/rustdoc.css | 6 ++++++ src/librustdoc/html/static/js/main.js | 14 ++++++++++---- tests/rustdoc-gui/implementors.goml | 7 ++++++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 5c02e2eb26a3e..6b80d3e7bbee6 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -29,6 +29,10 @@ nav.sub { display: none; } +#synthetic-implementors-list, #implementors-list { + display: block; +} + /* Begin: styles for themes Keep the default light and dark themes synchronized with the ones in rustdoc.css */ diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 36f44a8072af9..a5e43e1d7d19b 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1158,6 +1158,12 @@ div.where { margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); } +#synthetic-implementors-list, #implementors-list { + /* To prevent layout shift when loading the page with extra implementors being loaded + from JS, we hide the list until it's complete. */ + display: none; +} + .item-info code { font-size: 0.875rem; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index fb6b704921818..72d7e61318142 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -813,7 +813,7 @@ function preLoadCss(cssUrl) { return [elem, elem ? elem.querySelector(".negative-marker") : null]; } const implementors = implementorsElems("implementors-list"); - const synthetic_implementors = implementorsElems("synthetic-implementors-list"); + const syntheticImplementors = implementorsElems("synthetic-implementors-list"); const inlined_types = new Set(); const TEXT_IDX = 0; @@ -821,13 +821,13 @@ function preLoadCss(cssUrl) { const SYNTHETIC_IDX = 2; const TYPES_IDX = 3; - if (synthetic_implementors[0]) { + if (syntheticImplementors[0]) { // This `inlined_types` variable is used to avoid having the same implementation // showing up twice. For example "String" in the "Sync" doc page. // // By the way, this is only used by and useful for traits implemented automatically // (like "Send" and "Sync"). - onEachLazy(synthetic_implementors[0].getElementsByClassName("impl"), el => { + onEachLazy(syntheticImplementors[0].getElementsByClassName("impl"), el => { const aliases = el.getAttribute("data-aliases"); if (!aliases) { return; @@ -862,7 +862,7 @@ function preLoadCss(cssUrl) { struct_loop: for (const struct of structs) { - const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors; + const list = struct[SYNTHETIC_IDX] ? syntheticImplementors : implementors; // The types list is only used for synthetic impls. // If this changes, `main.js` and `write_shared.rs` both need changed. @@ -910,6 +910,12 @@ function preLoadCss(cssUrl) { currentNbImpls += 1; } } + if (implementors[0]) { + implementors[0].style.display = "block"; + } + if (syntheticImplementors[0]) { + syntheticImplementors[0].style.display = "block"; + } }; if (window.pending_implementors) { window.register_implementors(window.pending_implementors); diff --git a/tests/rustdoc-gui/implementors.goml b/tests/rustdoc-gui/implementors.goml index 99fb9b9aff54f..d4542c6f78172 100644 --- a/tests/rustdoc-gui/implementors.goml +++ b/tests/rustdoc-gui/implementors.goml @@ -1,7 +1,7 @@ // The goal of this test is to check that the external trait implementors, generated with JS, // have the same display than the "local" ones. go-to: "file://" + |DOC_PATH| + "/implementors/trait.Whatever.html" -assert: "#implementors-list" +wait-for-css: ("#implementors-list", {"display": "block"}) // There are supposed to be four implementors listed. assert-count: ("#implementors-list .impl", 4) // There are supposed to be two non-negative implementors. @@ -66,3 +66,8 @@ assert-count: ("#implementors-list .impl", 1) go-to: "file://" + |DOC_PATH| + "/http/trait.HttpTrait.html" assert-count: ("#implementors-list .impl", 1) assert-attribute: ("#implementors-list .impl a.trait", {"href": "../http/trait.HttpTrait.html"}) + +// Now we check that if JS is disabled, the implementors list will be visible. +javascript: false +reload: +assert-css: ("#implementors-list", {"display": "block"}) From fb9d3a5db4c3358f8ca22302f0e078675bc1a596 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 10 Dec 2025 17:34:08 +0100 Subject: [PATCH 09/15] Simplify the sorting of impls and use CSS classes instead of plain JS to show/hide implementors --- src/librustdoc/html/render/print_item.rs | 10 +++---- src/librustdoc/html/render/write_shared.rs | 33 +++++---------------- src/librustdoc/html/static/css/noscript.css | 2 +- src/librustdoc/html/static/css/rustdoc.css | 2 +- src/librustdoc/html/static/js/main.js | 4 +-- 5 files changed, 17 insertions(+), 34 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 47e5876263526..f88a5b8974fb9 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -650,18 +650,18 @@ fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> imp /// /// This marker appears once in all trait impl lists to divide negative impls from positive impls. struct NegativeMarker { - inserted_negative_marker: bool, + inserted: bool, } impl NegativeMarker { fn new() -> Self { - Self { inserted_negative_marker: false } + Self { inserted: false } } fn insert_if_needed(&mut self, w: &mut fmt::Formatter<'_>, implementor: &Impl) -> fmt::Result { - if !self.inserted_negative_marker && !implementor.is_negative_trait_impl() { - write!(w, "
")?; - self.inserted_negative_marker = true; + if !self.inserted && !implementor.is_negative_trait_impl() { + w.write_str("
")?; + self.inserted = true; } Ok(()) } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index ca33531174b1b..e0a37c95257c8 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -747,7 +747,14 @@ impl TraitAliasPart { path.push(format!("{remote_item_type}.{}.js", remote_path[remote_path.len() - 1])); let mut implementors = implementors.collect::>(); - implementors.sort_unstable(); + implementors.sort_unstable_by(|a, b| { + // We sort negative impls first. + match (a.is_negative, b.is_negative) { + (false, true) => Ordering::Greater, + (true, false) => Ordering::Less, + _ => compare_names(&a.text, &b.text), + } + }); let part = OrderedJson::array_unsorted( implementors @@ -762,7 +769,6 @@ impl TraitAliasPart { } } -#[derive(Eq)] struct Implementor { text: String, synthetic: bool, @@ -786,29 +792,6 @@ impl Serialize for Implementor { } } -impl PartialEq for Implementor { - fn eq(&self, other: &Self) -> bool { - self.cmp(other) == Ordering::Equal - } -} - -impl PartialOrd for Implementor { - fn partial_cmp(&self, other: &Self) -> Option { - Some(Ord::cmp(self, other)) - } -} - -impl Ord for Implementor { - fn cmp(&self, other: &Self) -> Ordering { - // We sort negative impls first. - match (self.is_negative, other.is_negative) { - (false, true) => Ordering::Greater, - (true, false) => Ordering::Less, - _ => compare_names(&self.text, &other.text), - } - } -} - /// Collect the list of aliased types and their aliases. /// /// diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 6b80d3e7bbee6..6f44854b6914e 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -29,7 +29,7 @@ nav.sub { display: none; } -#synthetic-implementors-list, #implementors-list { +#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) { display: block; } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a5e43e1d7d19b..69a79f2736e77 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1158,7 +1158,7 @@ div.where { margin-left: calc(var(--docblock-indent) + var(--impl-items-indent)); } -#synthetic-implementors-list, #implementors-list { +#synthetic-implementors-list:not(.loaded), #implementors-list:not(.loaded) { /* To prevent layout shift when loading the page with extra implementors being loaded from JS, we hide the list until it's complete. */ display: none; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 72d7e61318142..476ecd42d6f91 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -911,10 +911,10 @@ function preLoadCss(cssUrl) { } } if (implementors[0]) { - implementors[0].style.display = "block"; + implementors[0].classList.add("loaded"); } if (syntheticImplementors[0]) { - syntheticImplementors[0].style.display = "block"; + syntheticImplementors[0].classList.add("loaded"); } }; if (window.pending_implementors) { From 40891c79e67bd4e83f98c5866e62d24e2f2e06eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 9 Dec 2025 11:31:24 +0100 Subject: [PATCH 10/15] Use ubuntu:24.04 for the `x86_64-gnu-miri` and `x86_64-gnu-aux` jobs --- src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile | 2 +- src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile index a74db2250fc67..d4113736b544b 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-aux/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM ghcr.io/rust-lang/ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile index ad2ee85c7bb51..db4fca71d6376 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-miri/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/rust-lang/ubuntu:22.04 +FROM ghcr.io/rust-lang/ubuntu:24.04 ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ From 96a700010103799b6988ab9800f72f2f2b43b696 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Mon, 8 Dec 2025 16:25:43 +0300 Subject: [PATCH 11/15] Rename some issue-* tests --- src/tools/tidy/src/issues.txt | 4 ---- .../const-item-no-type/dont-suggest-type-error.rs} | 0 .../const-item-no-type/dont-suggest-type-error.stderr} | 4 ++-- .../const-item-no-type/empty-array.rs} | 0 .../const-item-no-type/empty-array.stderr} | 4 ++-- .../const-item-no-type/in-macro.rs} | 0 .../const-item-no-type/in-macro.stderr} | 6 +++--- .../const-item-no-type/with-colon.fixed} | 0 .../const-item-no-type/with-colon.rs} | 0 .../const-item-no-type/with-colon.stderr} | 4 ++-- 10 files changed, 9 insertions(+), 13 deletions(-) rename tests/ui/{typeck/issue-79040.rs => consts/const-item-no-type/dont-suggest-type-error.rs} (100%) rename tests/ui/{typeck/issue-79040.stderr => consts/const-item-no-type/dont-suggest-type-error.stderr} (85%) rename tests/ui/{parser/issues/issue-89574.rs => consts/const-item-no-type/empty-array.rs} (100%) rename tests/ui/{parser/issues/issue-89574.stderr => consts/const-item-no-type/empty-array.stderr} (88%) rename tests/ui/{macros/issue-69396-const-no-type-in-macro.rs => consts/const-item-no-type/in-macro.rs} (100%) rename tests/ui/{macros/issue-69396-const-no-type-in-macro.stderr => consts/const-item-no-type/in-macro.stderr} (89%) rename tests/ui/{typeck/issue-100164.fixed => consts/const-item-no-type/with-colon.fixed} (100%) rename tests/ui/{typeck/issue-100164.rs => consts/const-item-no-type/with-colon.rs} (100%) rename tests/ui/{typeck/issue-100164.stderr => consts/const-item-no-type/with-colon.stderr} (82%) diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 1500c82c411ac..45187a0b6450e 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -1583,7 +1583,6 @@ ui/macros/issue-6596-1.rs ui/macros/issue-6596-2.rs ui/macros/issue-68058.rs ui/macros/issue-68060.rs -ui/macros/issue-69396-const-no-type-in-macro.rs ui/macros/issue-69838-mods-relative-to-included-path.rs ui/macros/issue-70446.rs ui/macros/issue-75982-foreign-macro-weird-mod.rs @@ -2100,7 +2099,6 @@ ui/parser/issues/issue-88770.rs ui/parser/issues/issue-88818.rs ui/parser/issues/issue-89388.rs ui/parser/issues/issue-89396.rs -ui/parser/issues/issue-89574.rs ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs ui/parser/issues/issue-90728.rs ui/parser/issues/issue-90993.rs @@ -2880,7 +2878,6 @@ ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.rs ui/typeck/auxiliary/issue-29181.rs ui/typeck/auxiliary/issue-36708.rs ui/typeck/auxiliary/issue-81943-lib.rs -ui/typeck/issue-100164.rs ui/typeck/issue-100246.rs ui/typeck/issue-100285.rs ui/typeck/issue-103899.rs @@ -2937,7 +2934,6 @@ ui/typeck/issue-74933.rs ui/typeck/issue-75883.rs ui/typeck/issue-75889.rs ui/typeck/issue-7813.rs -ui/typeck/issue-79040.rs ui/typeck/issue-80207-unsized-return.rs ui/typeck/issue-80779.rs ui/typeck/issue-81293.rs diff --git a/tests/ui/typeck/issue-79040.rs b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs similarity index 100% rename from tests/ui/typeck/issue-79040.rs rename to tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs diff --git a/tests/ui/typeck/issue-79040.stderr b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr similarity index 85% rename from tests/ui/typeck/issue-79040.stderr rename to tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr index 4ab8df8f6c936..8f1fcc645b9c0 100644 --- a/tests/ui/typeck/issue-79040.stderr +++ b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr @@ -1,5 +1,5 @@ error[E0369]: cannot add `{integer}` to `&str` - --> $DIR/issue-79040.rs:2:25 + --> $DIR/dont-suggest-type-error.rs:2:25 | LL | const FOO = "hello" + 1; | ------- ^ - {integer} @@ -7,7 +7,7 @@ LL | const FOO = "hello" + 1; | &str error: missing type for `const` item - --> $DIR/issue-79040.rs:2:14 + --> $DIR/dont-suggest-type-error.rs:2:14 | LL | const FOO = "hello" + 1; | ^ diff --git a/tests/ui/parser/issues/issue-89574.rs b/tests/ui/consts/const-item-no-type/empty-array.rs similarity index 100% rename from tests/ui/parser/issues/issue-89574.rs rename to tests/ui/consts/const-item-no-type/empty-array.rs diff --git a/tests/ui/parser/issues/issue-89574.stderr b/tests/ui/consts/const-item-no-type/empty-array.stderr similarity index 88% rename from tests/ui/parser/issues/issue-89574.stderr rename to tests/ui/consts/const-item-no-type/empty-array.stderr index f40f5aded8ef1..fe307d50353e4 100644 --- a/tests/ui/parser/issues/issue-89574.stderr +++ b/tests/ui/consts/const-item-no-type/empty-array.stderr @@ -1,11 +1,11 @@ error[E0282]: type annotations needed - --> $DIR/issue-89574.rs:2:25 + --> $DIR/empty-array.rs:2:25 | LL | const EMPTY_ARRAY = []; | ^^ cannot infer type error: missing type for `const` item - --> $DIR/issue-89574.rs:2:22 + --> $DIR/empty-array.rs:2:22 | LL | const EMPTY_ARRAY = []; | ^ diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs b/tests/ui/consts/const-item-no-type/in-macro.rs similarity index 100% rename from tests/ui/macros/issue-69396-const-no-type-in-macro.rs rename to tests/ui/consts/const-item-no-type/in-macro.rs diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr b/tests/ui/consts/const-item-no-type/in-macro.stderr similarity index 89% rename from tests/ui/macros/issue-69396-const-no-type-in-macro.stderr rename to tests/ui/consts/const-item-no-type/in-macro.stderr index 4342d7d88f54b..d6182aa114270 100644 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/consts/const-item-no-type/in-macro.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `A` is defined multiple times - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:13 + --> $DIR/in-macro.rs:4:13 | LL | const A = "A".$fn(); | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here @@ -14,7 +14,7 @@ LL | | } = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) error: missing type for `const` item - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 + --> $DIR/in-macro.rs:4:20 | LL | const A = "A".$fn(); | ^ help: provide a type for the constant: `: usize` @@ -28,7 +28,7 @@ LL | | } = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0121]: missing type for item - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 + --> $DIR/in-macro.rs:4:20 | LL | const A = "A".$fn(); | ^ not allowed in type signatures diff --git a/tests/ui/typeck/issue-100164.fixed b/tests/ui/consts/const-item-no-type/with-colon.fixed similarity index 100% rename from tests/ui/typeck/issue-100164.fixed rename to tests/ui/consts/const-item-no-type/with-colon.fixed diff --git a/tests/ui/typeck/issue-100164.rs b/tests/ui/consts/const-item-no-type/with-colon.rs similarity index 100% rename from tests/ui/typeck/issue-100164.rs rename to tests/ui/consts/const-item-no-type/with-colon.rs diff --git a/tests/ui/typeck/issue-100164.stderr b/tests/ui/consts/const-item-no-type/with-colon.stderr similarity index 82% rename from tests/ui/typeck/issue-100164.stderr rename to tests/ui/consts/const-item-no-type/with-colon.stderr index 06a132d651429..adbea1f355a0b 100644 --- a/tests/ui/typeck/issue-100164.stderr +++ b/tests/ui/consts/const-item-no-type/with-colon.stderr @@ -1,11 +1,11 @@ error: missing type for `const` item - --> $DIR/issue-100164.rs:3:10 + --> $DIR/with-colon.rs:3:10 | LL | const _A: = 123; | ^ help: provide a type for the constant: `i32` error: missing type for `const` item - --> $DIR/issue-100164.rs:7:14 + --> $DIR/with-colon.rs:7:14 | LL | const _B: = 123; | ^ help: provide a type for the constant: `i32` From 507b67f45745194e151e373325e7ec2154589484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 8 Nov 2025 22:26:43 +0000 Subject: [PATCH 12/15] Add test for incorrect macro span replacement --- .../ui/span/macro-span-caller-replacement.rs | 16 ++++++++++ .../span/macro-span-caller-replacement.stderr | 29 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 tests/ui/span/macro-span-caller-replacement.rs create mode 100644 tests/ui/span/macro-span-caller-replacement.stderr diff --git a/tests/ui/span/macro-span-caller-replacement.rs b/tests/ui/span/macro-span-caller-replacement.rs new file mode 100644 index 0000000000000..45af729beb1a8 --- /dev/null +++ b/tests/ui/span/macro-span-caller-replacement.rs @@ -0,0 +1,16 @@ +macro_rules! macro_with_format { () => { + fn check_5(arg : usize) -> String { + let s : &str; + if arg < 5 { + s = format!("{arg}"); + } else { + s = String::new(); //~ ERROR mismatched types + } + String::from(s) + } +}} + +fn main() { + macro_with_format!(); //~ ERROR mismatched types + println!( "{}", check_5(6) ); +} diff --git a/tests/ui/span/macro-span-caller-replacement.stderr b/tests/ui/span/macro-span-caller-replacement.stderr new file mode 100644 index 0000000000000..1c831f96ec0cd --- /dev/null +++ b/tests/ui/span/macro-span-caller-replacement.stderr @@ -0,0 +1,29 @@ +error[E0308]: mismatched types + --> $DIR/macro-span-caller-replacement.rs:5:17 + | +LL | macro_with_format!(); + | ^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` + | + = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/macro-span-caller-replacement.rs:7:17 + | +LL | let s : &str; + | ---- expected due to this type +... +LL | s = String::new(); + | ^^^^^^^^^^^^^ expected `&str`, found `String` +... +LL | macro_with_format!(); + | -------------------- in this macro invocation + | + = note: this error originates in the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider borrowing here + | +LL | s = &String::new(); + | + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 1bd7934d891cee73664367cfff8f914edda3d9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 8 Nov 2025 23:35:55 +0000 Subject: [PATCH 13/15] Point at span within local macros even when error happens in nested external macro ``` error[E0308]: mismatched types --> $DIR/macro-span-caller-replacement.rs:5:17 | LL | s = format!("{arg}"); | ^^^^^^^^^^^^^^^^ expected `&str`, found `String` ... LL | macro_with_format!(); | -------------------- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) ``` --- compiler/rustc_errors/src/emitter.rs | 9 +- .../tests/fail/panic/tls_macro_drop_panic.rs | 2 +- .../rustc-dev-remap.only-remap.stderr | 3 + .../rustc-dev-remap.remap-unremap.stderr | 5 +- ...diagnostic-derive-doc-comment-field.stderr | 6 + .../diagnostic-derive.stderr | 3 + tests/ui/binop/binary-op-suggest-deref.stderr | 12 +- tests/ui/binop/binop-mul-i32-f32.stderr | 12 +- .../const_param_ty_bad.stderr | 6 + .../const-eval/const-eval-overflow-3b.stderr | 12 +- .../const-eval/const-eval-overflow-4b.stderr | 12 +- tests/ui/consts/const-eval/issue-85155.stderr | 7 +- tests/ui/consts/const-eval/parse_ints.stderr | 12 ++ tests/ui/consts/const-ptr-is-null.stderr | 7 + .../ui/consts/const_transmute_type_id2.stderr | 4 + .../ui/consts/const_transmute_type_id3.stderr | 4 + .../ui/consts/const_transmute_type_id4.stderr | 4 + .../ui/consts/const_transmute_type_id5.stderr | 4 + .../ui/consts/const_transmute_type_id6.stderr | 4 + tests/ui/consts/timeout.stderr | 5 + .../hygiene/cross-crate-name-hiding-2.stderr | 6 +- tests/ui/impl-trait/equality.stderr | 12 +- .../ambiguous-glob-vs-expanded-extern.stderr | 14 +- .../issue-41731-infinite-macro-print.stderr | 14 +- .../issue-41731-infinite-macro-println.stderr | 14 +- .../invalid-iterator-chain-fixable.stderr | 18 ++- ...valid-iterator-chain-with-int-infer.stderr | 6 +- .../iterators/invalid-iterator-chain.stderr | 30 +++- tests/ui/mismatched_types/binops.stderr | 12 +- ...oat-integer-subtraction-error-24352.stderr | 12 +- tests/ui/never_type/issue-13352.stderr | 12 +- .../not-suggest-float-literal.stderr | 132 +++++++++++++----- .../suggest-float-literal.stderr | 96 +++++++++---- tests/ui/on-unimplemented/slice-index.stderr | 3 + tests/ui/on-unimplemented/sum.stderr | 12 +- tests/ui/proc-macro/mixed-site-span.stderr | 28 ++-- .../ui/span/macro-span-caller-replacement.rs | 6 +- .../span/macro-span-caller-replacement.stderr | 5 +- tests/ui/span/multiline-span-simple.stderr | 12 +- ...ut-not-available.alignment_mismatch.stderr | 3 + ...gest-deref-inside-macro-issue-58298.stderr | 7 +- .../invalid-suggest-deref-issue-127590.stderr | 16 +++ tests/ui/try-trait/bad-interconversion.stderr | 6 + .../self-referential-2.current.stderr | 3 + .../self-referential-3.stderr | 3 + .../self-referential-4.stderr | 9 ++ .../self-referential.stderr | 9 ++ tests/ui/type/type-check-defaults.stderr | 12 +- ...0017-format-into-help-deletes-macro.stderr | 21 ++- ...2007-leaked-writeln-macro-internals.stderr | 7 +- tests/ui/typeck/issue-81293.stderr | 12 +- tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr | 24 +++- 52 files changed, 558 insertions(+), 151 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d08d5a5a1ea29..78feb60261bd8 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -474,9 +474,12 @@ pub trait Emitter { .chain(span.span_labels().iter().map(|sp_label| sp_label.span)) .filter_map(|sp| { if !sp.is_dummy() && source_map.is_imported(sp) { - let maybe_callsite = sp.source_callsite(); - if sp != maybe_callsite { - return Some((sp, maybe_callsite)); + let mut span = sp; + while let Some(callsite) = span.parent_callsite() { + span = callsite; + if !source_map.is_imported(span) { + return Some((sp, span)); + } } } None diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs index 107d70a3b3c7f..a207d3923124a 100644 --- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs +++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.rs @@ -1,7 +1,7 @@ //@error-in-other-file: aborted execution // Backtraces vary wildly between platforms, we have to normalize away almost the entire thing //@normalize-stderr-test: "'main'|''" -> "$$NAME" -//@normalize-stderr-test: ".*(note|-->|\|).*\n" -> "" +//@normalize-stderr-test: ".*(note|-->|:::|\|).*\n" -> "" pub struct NoisyDrop {} diff --git a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr index 15e2cf66f8f86..d2303ef4bbb56 100644 --- a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr +++ b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr @@ -18,6 +18,9 @@ help: the following other types implement trait `VisitorResult` = note: `ControlFlow` note: required by a bound in `rustc_ast::visit::Visitor::Result` --> /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL + ::: /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr index b9276974c465e..50bb60e78d680 100644 --- a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr +++ b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr @@ -20,8 +20,11 @@ LL | impl VisitorResult for ControlFlow { note: required by a bound in `rustc_ast::visit::Visitor::Result` --> $COMPILER_DIR_REAL/rustc_ast/src/visit.rs:LL:COL | +LL | type Result: VisitorResult = (); + | ^^^^^^^^^^^^^ required by this bound in `Visitor::Result` +... LL | common_visitor_and_walkers!(Visitor<'a>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Visitor::Result` + | ---------------------------------------- in this macro invocation = note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr index 8b6c4b181c0fe..72e150dd5178d 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr @@ -15,6 +15,9 @@ LL | struct NotIntoDiagArg; = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied @@ -34,6 +37,9 @@ LL | struct NotIntoDiagArg; = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 8a0e753a9c52a..f2244a9687698 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -665,6 +665,9 @@ LL | struct Hello {} = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 85 previous errors diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr index 0c9b1d9bd938c..eb17c6cbbc66b 100644 --- a/tests/ui/binop/binary-op-suggest-deref.stderr +++ b/tests/ui/binop/binary-op-suggest-deref.stderr @@ -305,13 +305,19 @@ LL | let _ = FOO & (*"Sized".to_string().into_boxed_str()); help: the following other types implement trait `BitAnd` --> $SRC_DIR/core/src/ops/bit.rs:LL:COL | - = note: `&i32` implements `BitAnd` + = note: `i32` implements `BitAnd` + ::: $SRC_DIR/core/src/ops/bit.rs:LL:COL | - = note: `&i32` implements `BitAnd` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `BitAnd` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `BitAnd<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `BitAnd` + = note: `&i32` implements `BitAnd` = note: this error originates in the macro `bitand_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `str` cannot be known at compilation time diff --git a/tests/ui/binop/binop-mul-i32-f32.stderr b/tests/ui/binop/binop-mul-i32-f32.stderr index dc4e7fdf6c144..a8893700b1be5 100644 --- a/tests/ui/binop/binop-mul-i32-f32.stderr +++ b/tests/ui/binop/binop-mul-i32-f32.stderr @@ -8,13 +8,19 @@ LL | x * y help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Mul` + = note: `i32` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Mul<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Mul` + = note: `&i32` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index 75718fbbba0a3..5109dccd96a1d 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -84,6 +84,9 @@ LL | check(&mut () as *mut ()); | help: the trait `ConstParamTy_` is implemented for `()` --> $SRC_DIR/core/src/marker.rs:LL:COL + ::: $SRC_DIR/core/src/marker.rs:LL:COL + | + = note: in this macro invocation note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | @@ -101,6 +104,9 @@ LL | check(&() as *const ()); | help: the trait `ConstParamTy_` is implemented for `()` --> $SRC_DIR/core/src/marker.rs:LL:COL + ::: $SRC_DIR/core/src/marker.rs:LL:COL + | + = note: in this macro invocation note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr index 4209e4bcee522..54d77b1bf3e94 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -14,13 +14,19 @@ LL | = [0; (i8::MAX + 1u8) as usize]; help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: `i8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i8` implements `Add<&i8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i8` implements `Add` + = note: `&i8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 2677d7956cc98..6c6472610b724 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -14,13 +14,19 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize] help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: `i8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i8` implements `Add<&i8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i8` implements `Add` + = note: `&i8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0604]: only `u8` can be cast as `char`, not `i8` diff --git a/tests/ui/consts/const-eval/issue-85155.stderr b/tests/ui/consts/const-eval/issue-85155.stderr index 486d2adaf8cde..dfc784bc7a4f3 100644 --- a/tests/ui/consts/const-eval/issue-85155.stderr +++ b/tests/ui/consts/const-eval/issue-85155.stderr @@ -5,10 +5,13 @@ LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed here note: erroneous constant encountered - --> $DIR/auxiliary/post_monomorphization_error.rs:19:5 + --> $DIR/auxiliary/post_monomorphization_error.rs:13:17 | +LL | let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | static_assert_imm1!(IMM1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------------------- in this macro invocation | = note: this note originates in the macro `static_assert_imm1` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr index 9c9d083e7ca23..7f42e20cf8e83 100644 --- a/tests/ui/consts/const-eval/parse_ints.stderr +++ b/tests/ui/consts/const-eval/parse_ints.stderr @@ -6,8 +6,14 @@ LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; | note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation note: inside `core::num::::from_ascii_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: from_ascii_radix: radix must lie in the range `[2, 36]` @@ -18,8 +24,14 @@ LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; | note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation note: inside `core::num::::from_ascii_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-ptr-is-null.stderr b/tests/ui/consts/const-ptr-is-null.stderr index be0a1346c6475..b532ed9d4c5fa 100644 --- a/tests/ui/consts/const-ptr-is-null.stderr +++ b/tests/ui/consts/const-ptr-is-null.stderr @@ -5,9 +5,16 @@ LL | assert!(!ptr.wrapping_sub(512).is_null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MAYBE_NULL` failed inside this call | note: inside `std::ptr::const_ptr::::is_null` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: in this macro invocation note: inside `std::ptr::const_ptr::::is_null::compiletime` + --> $SRC_DIR/core/src/panic.rs:LL:COL --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: in this macro invocation error: aborting due to 1 previous error diff --git a/tests/ui/consts/const_transmute_type_id2.stderr b/tests/ui/consts/const_transmute_type_id2.stderr index 5646eb1257d1e..b420deaa49ce9 100644 --- a/tests/ui/consts/const_transmute_type_id2.stderr +++ b/tests/ui/consts/const_transmute_type_id2.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id3.stderr b/tests/ui/consts/const_transmute_type_id3.stderr index e731f496652e5..9f796cda61454 100644 --- a/tests/ui/consts/const_transmute_type_id3.stderr +++ b/tests/ui/consts/const_transmute_type_id3.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id4.stderr b/tests/ui/consts/const_transmute_type_id4.stderr index b224227cf3526..c844b10d78cfb 100644 --- a/tests/ui/consts/const_transmute_type_id4.stderr +++ b/tests/ui/consts/const_transmute_type_id4.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id5.stderr b/tests/ui/consts/const_transmute_type_id5.stderr index 6205679ebb641..9a7384eb95b42 100644 --- a/tests/ui/consts/const_transmute_type_id5.stderr +++ b/tests/ui/consts/const_transmute_type_id5.stderr @@ -5,7 +5,11 @@ LL | assert!(b == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id6.stderr b/tests/ui/consts/const_transmute_type_id6.stderr index f5d90256e7c6a..c0b35f3d1081d 100644 --- a/tests/ui/consts/const_transmute_type_id6.stderr +++ b/tests/ui/consts/const_transmute_type_id6.stderr @@ -5,7 +5,11 @@ LL | id == id | ^^^^^^^^ evaluation of `X` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/timeout.stderr b/tests/ui/consts/timeout.stderr index ecefeff76e967..6afb317c3affa 100644 --- a/tests/ui/consts/timeout.stderr +++ b/tests/ui/consts/timeout.stderr @@ -1,5 +1,10 @@ error: constant evaluation is taking a long time + --> $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + | --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. If your compilation actually takes a long time, you can safely allow the lint. diff --git a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr index fe3a12e93a7e7..336d35099c806 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr @@ -4,10 +4,10 @@ error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope LL | let x = MyStruct {}; | ^^^^^^^^ not found in this scope | - ::: $DIR/auxiliary/use_by_macro.rs:15:1 + ::: $DIR/auxiliary/use_by_macro.rs:7:24 | -LL | x!(my_struct); - | ------------- you might have meant to refer to this struct +LL | pub struct MyStruct; + | -------- you might have meant to refer to this struct error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index c2b889138c893..7f965b9609a9d 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -33,13 +33,19 @@ LL | n + sum_to(n - 1) help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: `u32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u32` implements `Add<&u32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u32` implements `Add` + = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr index c2e775e6c862a..4a9a6c99819b0 100644 --- a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr +++ b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.stderr @@ -8,10 +8,13 @@ LL | glob_vs_expanded::mac!(); = note: for more information, see issue #114095 = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `mac` could refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:11:1 + --> $DIR/auxiliary/glob-vs-expanded.rs:9:13 | +LL | () => { pub macro mac() {} } + | ^^^^^^^^^^^^^ +LL | } LL | define_mac!(); - | ^^^^^^^^^^^^^ + | ------------- in this macro invocation note: `mac` could also refer to the macro defined here --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 | @@ -33,10 +36,13 @@ LL | glob_vs_expanded::mac!(); = note: for more information, see issue #114095 = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `mac` could refer to the macro defined here - --> $DIR/auxiliary/glob-vs-expanded.rs:11:1 + --> $DIR/auxiliary/glob-vs-expanded.rs:9:13 | +LL | () => { pub macro mac() {} } + | ^^^^^^^^^^^^^ +LL | } LL | define_mac!(); - | ^^^^^^^^^^^^^ + | ------------- in this macro invocation note: `mac` could also refer to the macro defined here --> $DIR/auxiliary/glob-vs-expanded.rs:5:9 | diff --git a/tests/ui/infinite/issue-41731-infinite-macro-print.stderr b/tests/ui/infinite/issue-41731-infinite-macro-print.stderr index 84436de9aa37f..5f5d2c75525d2 100644 --- a/tests/ui/infinite/issue-41731-infinite-macro-print.stderr +++ b/tests/ui/infinite/issue-41731-infinite-macro-print.stderr @@ -1,8 +1,11 @@ error: recursion limit reached while expanding `$crate::format_args!` - --> $DIR/issue-41731-infinite-macro-print.rs:14:5 + --> $DIR/issue-41731-infinite-macro-print.rs:8:13 | +LL | print!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_print`) = note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -23,10 +26,13 @@ LL | stack!("overflow"); = note: to `{ $crate :: io :: _print($crate :: format_args! (stack! ("overflow"))); }` error: format argument must be a string literal - --> $DIR/issue-41731-infinite-macro-print.rs:14:5 + --> $DIR/issue-41731-infinite-macro-print.rs:8:13 | +LL | print!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with diff --git a/tests/ui/infinite/issue-41731-infinite-macro-println.stderr b/tests/ui/infinite/issue-41731-infinite-macro-println.stderr index 6d0432abe4c58..c19039e305e20 100644 --- a/tests/ui/infinite/issue-41731-infinite-macro-println.stderr +++ b/tests/ui/infinite/issue-41731-infinite-macro-println.stderr @@ -1,8 +1,11 @@ error: recursion limit reached while expanding `$crate::format_args_nl!` - --> $DIR/issue-41731-infinite-macro-println.rs:14:5 + --> $DIR/issue-41731-infinite-macro-println.rs:8:13 | +LL | println!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_println`) = note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -23,10 +26,13 @@ LL | stack!("overflow"); = note: to `{ $crate :: io :: _print($crate :: format_args_nl! (stack! ("overflow"))); }` error: format argument must be a string literal - --> $DIR/issue-41731-infinite-macro-println.rs:14:5 + --> $DIR/issue-41731-infinite-macro-println.rs:8:13 | +LL | println!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with diff --git a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index bef4cb6b0a1b6..99bff6b450b56 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr @@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:14:10 | @@ -72,10 +76,14 @@ LL | .sum::(), = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:23:14 | @@ -109,10 +117,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:27:38 | diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr index 638287ed1c644..c94b716e3131f 100644 --- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr @@ -9,10 +9,14 @@ LL | let x = Some(()).iter().map(|()| 1).sum::(); = help: the trait `Sum<{integer}>` is not implemented for `f32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `f32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `f32` implements `Sum<&f32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `f32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 0fd9d3999966c..7f0c154e255ad 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:12:10 | @@ -71,10 +75,14 @@ LL | .sum::(), = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:25:14 | @@ -114,10 +122,14 @@ LL | .sum::(), = help: the trait `Sum` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:33:14 | @@ -148,10 +160,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:38:38 | @@ -180,10 +196,14 @@ LL | println!("{}", vec![(), ()].iter().sum::()); = help: the trait `Sum<&()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:39:33 | diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr index 504b44dfb7f69..ec2a951aac9a4 100644 --- a/tests/ui/mismatched_types/binops.stderr +++ b/tests/ui/mismatched_types/binops.stderr @@ -26,13 +26,19 @@ LL | 2 as usize - Some(1); help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Sub` + = note: `usize` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Sub<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Sub` + = note: `&usize` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `{integer}` by `()` diff --git a/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr index b2d0ffc4710e2..54b536744f757 100644 --- a/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr +++ b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr @@ -8,13 +8,19 @@ LL | 1.0f64 - 1 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | diff --git a/tests/ui/never_type/issue-13352.stderr b/tests/ui/never_type/issue-13352.stderr index 344625af683ae..5fcbb4aab9937 100644 --- a/tests/ui/never_type/issue-13352.stderr +++ b/tests/ui/never_type/issue-13352.stderr @@ -8,13 +8,19 @@ LL | 2_usize + (loop {}); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: `usize` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Add<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Add` + = note: `&usize` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr index 3f5297be3719c..a62bf5b6a04de 100644 --- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr @@ -8,13 +8,19 @@ LL | x + 100.0 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Add` + = note: `u8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Add<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Add` + = note: `&u8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot add `&str` to `f64` @@ -27,13 +33,19 @@ LL | x + "foo" help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot add `{integer}` to `f64` @@ -46,13 +58,19 @@ LL | x + y help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `{float}` from `u8` @@ -65,13 +83,19 @@ LL | x - 100.0 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Sub` + = note: `u8` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Sub<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Sub` + = note: `&u8` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `&str` from `f64` @@ -84,13 +108,19 @@ LL | x - "foo" help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `{integer}` from `f64` @@ -103,13 +133,19 @@ LL | x - y help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `u8` by `{float}` @@ -122,13 +158,19 @@ LL | x * 100.0 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Mul` + = note: `u8` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Mul<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Mul` + = note: `&u8` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `f64` by `&str` @@ -141,13 +183,19 @@ LL | x * "foo" help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `f64` by `{integer}` @@ -160,13 +208,19 @@ LL | x * y help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot divide `u8` by `{float}` @@ -193,13 +247,19 @@ LL | x / "foo" help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot divide `f64` by `{integer}` @@ -212,13 +272,19 @@ LL | x / y help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 12 previous errors diff --git a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr index a31ed61547465..65881ca7a82f1 100644 --- a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr @@ -8,13 +8,19 @@ LL | x + 100 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Add` + = note: `f32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Add<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Add` + = note: `&f32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -31,13 +37,19 @@ LL | x + 100 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -54,13 +66,19 @@ LL | x - 100 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Sub` + = note: `f32` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Sub<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Sub` + = note: `&f32` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -77,13 +95,19 @@ LL | x - 100 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -100,13 +124,19 @@ LL | x * 100 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Mul` + = note: `f32` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Mul<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Mul` + = note: `&f32` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -123,13 +153,19 @@ LL | x * 100 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -146,13 +182,19 @@ LL | x / 100 help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Div` + = note: `f32` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Div<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Div` + = note: `&f32` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -169,13 +211,19 @@ LL | x / 100 help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index baf821c45c5e8..67b72bd038d80 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -28,6 +28,9 @@ help: the following other types implement trait `SliceIndex` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | = note: `RangeTo` implements `SliceIndex` + ::: $SRC_DIR/core/src/bstr/traits.rs:LL:COL + | + = note: in this macro invocation --> $SRC_DIR/core/src/str/traits.rs:LL:COL | = note: `RangeTo` implements `SliceIndex` diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr index c4650e9f52786..5e82948352f75 100644 --- a/tests/ui/on-unimplemented/sum.stderr +++ b/tests/ui/on-unimplemented/sum.stderr @@ -9,10 +9,14 @@ LL | vec![(), ()].iter().sum::(); = help: the trait `Sum<&()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Sum` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:4:18 | @@ -35,10 +39,14 @@ LL | vec![(), ()].iter().product::(); = help: the trait `Product<&()>` is not implemented for `i32` help: the following other types implement trait `Product` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Product` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: `i32` implements `Product<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | - = note: `i32` implements `Product` + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:7:18 | diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 2cc7ff8a88679..fd941f65b788c 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -112,10 +112,13 @@ LL | test!(); = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:69:5 + --> $DIR/mixed-site-span.rs:67:9 | +LL | invoke_with_ident!{$crate call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root +LL | }} LL | test!(); - | ^^^^^^^ no `proc_macro_item` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -262,10 +265,13 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:110:5 + --> $DIR/mixed-site-span.rs:106:9 | +LL | invoke_with_ident!{$crate mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root +... LL | test!(); - | ^^^^^^^ no `TokenItem` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -417,10 +423,13 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:150:5 + --> $DIR/mixed-site-span.rs:145:9 | +LL | invoke_with_ident!{$crate mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +... LL | test!(); - | ^^^^^^^ no `ItemUse` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -447,10 +456,13 @@ LL + ItemUse as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:150:5 + --> $DIR/mixed-site-span.rs:148:9 | +LL | invoke_with_ident!{$crate call ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +LL | }} LL | test!(); - | ^^^^^^^ no `ItemUse` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead diff --git a/tests/ui/span/macro-span-caller-replacement.rs b/tests/ui/span/macro-span-caller-replacement.rs index 45af729beb1a8..8e7239699cd15 100644 --- a/tests/ui/span/macro-span-caller-replacement.rs +++ b/tests/ui/span/macro-span-caller-replacement.rs @@ -2,7 +2,7 @@ macro_rules! macro_with_format { () => { fn check_5(arg : usize) -> String { let s : &str; if arg < 5 { - s = format!("{arg}"); + s = format!("{arg}"); //~ ERROR mismatched types } else { s = String::new(); //~ ERROR mismatched types } @@ -11,6 +11,6 @@ macro_rules! macro_with_format { () => { }} fn main() { - macro_with_format!(); //~ ERROR mismatched types - println!( "{}", check_5(6) ); + macro_with_format!(); + println!( "{}", check_5(6) ); } diff --git a/tests/ui/span/macro-span-caller-replacement.stderr b/tests/ui/span/macro-span-caller-replacement.stderr index 1c831f96ec0cd..43be48a9e362e 100644 --- a/tests/ui/span/macro-span-caller-replacement.stderr +++ b/tests/ui/span/macro-span-caller-replacement.stderr @@ -1,8 +1,11 @@ error[E0308]: mismatched types --> $DIR/macro-span-caller-replacement.rs:5:17 | +LL | s = format!("{arg}"); + | ^^^^^^^^^^^^^^^^ expected `&str`, found `String` +... LL | macro_with_format!(); - | ^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` + | -------------------- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/span/multiline-span-simple.stderr b/tests/ui/span/multiline-span-simple.stderr index af04ceaf8097c..e013b3c06bc1b 100644 --- a/tests/ui/span/multiline-span-simple.stderr +++ b/tests/ui/span/multiline-span-simple.stderr @@ -8,13 +8,19 @@ LL | foo(1 as u32 + help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: `u32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u32` implements `Add<&u32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u32` implements `Add` + = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr index 6a8a7b152c547..93e189ffa0d3f 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr @@ -6,6 +6,9 @@ LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); | note: if you're trying to build a new `AtomicU64`, consider using `AtomicU64::new` which returns `AtomicU64` --> $SRC_DIR/core/src/sync/atomic.rs:LL:COL + ::: $SRC_DIR/core/src/sync/atomic.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `atomic_int` (in Nightly builds, run with -Z macro-backtrace for more info) help: there is an associated function `from` with a similar name | diff --git a/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index 46613e8e1b487..0ed657c7fa99b 100644 --- a/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -1,10 +1,13 @@ error[E0308]: mismatched types - --> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:11:5 + --> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:5:14 | +LL | warn(format!("unsupported intrinsic {}", $intrinsic)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` +... LL | / intrinsic_match! { LL | | "abc" LL | | }; - | |_____^ expected `&str`, found `String` + | |_____- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr index 07a54d574df49..3bae5798d0471 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -24,7 +24,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -55,7 +59,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -68,7 +76,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -80,7 +92,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index da5c4d03dccbd..61fecaf89917c 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -13,9 +13,15 @@ help: the following other types implement trait `From` --> $SRC_DIR/core/src/convert/num.rs:LL:COL | = note: `u8` implements `From` + ::: $SRC_DIR/core/src/convert/num.rs:LL:COL + | + = note: in this macro invocation --> $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | = note: `u8` implements `From` + ::: $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `impl_from` which comes from the expansion of the macro `into_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr index 2855c90234d21..ca26e3dd03f35 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -9,6 +9,9 @@ LL | 42_i32 help: the trait `PartialEq` is not implemented for `i32` but trait `PartialEq` is implemented for it --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 83fed16c0a17b..8592de243adac 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -10,6 +10,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr index 4176bf7802945..c6bf1973fcbb1 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr @@ -9,6 +9,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` @@ -22,6 +25,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` @@ -35,6 +41,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr index dc5b9ba7b4426..7b4e6e9cac528 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential.stderr @@ -10,6 +10,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)` @@ -24,6 +27,9 @@ LL | (42, i) = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)` @@ -38,6 +44,9 @@ LL | (42, i) = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/type/type-check-defaults.stderr b/tests/ui/type/type-check-defaults.stderr index 4eab611244a69..a3a2ed5aa725c 100644 --- a/tests/ui/type/type-check-defaults.stderr +++ b/tests/ui/type/type-check-defaults.stderr @@ -86,13 +86,19 @@ LL | trait ProjectionPred> where T::Item : Add {} help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` note: required by a bound in `ProjectionPred` --> $DIR/type-check-defaults.rs:24:66 | diff --git a/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr b/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr index e4834c0308bc8..bc722cdd57a5a 100644 --- a/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr +++ b/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr @@ -13,10 +13,13 @@ LL | Err(format!("error: {x}").into()) | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:23:10 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:17:10 | +LL | format!("error: {}", $x) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | Err(outer!(x)) - | ^^^^^^^^^ expected `Box`, found `String` + | --------- in this macro invocation | = note: expected struct `Box` found struct `String` @@ -27,10 +30,13 @@ LL | format!("error: {}", $x).into() | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:41:2 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:35:18 | +LL | Err(format!("error: {x}")) + | ^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | entire_fn_outer!(); - | ^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` + | ------------------ in this macro invocation | = note: expected struct `Box` found struct `String` @@ -41,10 +47,13 @@ LL | Err(format!("error: {x}").into()) | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:51:5 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:45:13 | +LL | Err(format!("error: {}", $x)) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | nontrivial!(x) - | ^^^^^^^^^^^^^^ expected `Box`, found `String` + | -------------- in this macro invocation | = note: expected struct `Box` found struct `String` diff --git a/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr b/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr index 889d2c94d0cfb..30d51420b7cb3 100644 --- a/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr +++ b/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr @@ -27,13 +27,16 @@ LL | writeln!(w, "but not here")? | + error[E0308]: mismatched types - --> $DIR/issue-112007-leaked-writeln-macro-internals.rs:40:9 + --> $DIR/issue-112007-leaked-writeln-macro-internals.rs:31:9 | +LL | writeln!($w, "but not here") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>` +... LL | / if true { LL | | writeln!(w, "`;?` here ->")?; LL | | } else { LL | | baz!(w) - | | ^^^^^^^ expected `()`, found `Result<(), Error>` + | | ------- in this macro invocation LL | | } | |_____- expected this to be `()` | diff --git a/tests/ui/typeck/issue-81293.stderr b/tests/ui/typeck/issue-81293.stderr index 8318d31f0946f..604f3cca54866 100644 --- a/tests/ui/typeck/issue-81293.stderr +++ b/tests/ui/typeck/issue-81293.stderr @@ -23,13 +23,19 @@ LL | a = c + b * 5; help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: `usize` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Add<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Add` + = note: `&usize` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 352638dd0118e..dbbee54c185bf 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -8,13 +8,19 @@ LL | >::add(1, 2); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types @@ -73,13 +79,19 @@ LL | >::add(1, 2); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors From c27bcef6f8ca820f9b22a707149485388281a8a8 Mon Sep 17 00:00:00 2001 From: 21aslade Date: Wed, 3 Dec 2025 20:43:27 -0700 Subject: [PATCH 14/15] don't resolve main in lib crates --- compiler/rustc_resolve/src/lib.rs | 7 +++++++ tests/ui/entry-point/imported_main_conflict_lib.rs | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/entry-point/imported_main_conflict_lib.rs diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8132bf577d883..0b4ec6956bd15 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -73,6 +73,7 @@ use rustc_middle::ty::{ ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; use rustc_query_system::ich::StableHashingContext; +use rustc_session::config::CrateType; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym}; @@ -2430,6 +2431,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolve_main(&mut self) { + let any_exe = self.tcx.crate_types().contains(&CrateType::Executable); + // Don't try to resolve main unless it's an executable + if !any_exe { + return; + } + let module = self.graph_root; let ident = Ident::with_dummy_span(sym::main); let parent_scope = &ParentScope::module(module, self.arenas); diff --git a/tests/ui/entry-point/imported_main_conflict_lib.rs b/tests/ui/entry-point/imported_main_conflict_lib.rs new file mode 100644 index 0000000000000..b50e37951ede4 --- /dev/null +++ b/tests/ui/entry-point/imported_main_conflict_lib.rs @@ -0,0 +1,10 @@ +// Tests that ambiguously glob importing main doesn't fail to compile in non-executable crates +// Regression test for #149412 +//@ check-pass +#![crate_type = "lib"] + +mod m1 { pub(crate) fn main() {} } +mod m2 { pub(crate) fn main() {} } + +use m1::*; +use m2::*; From c60ed211d1a7216fd422f99da158e853e3eca2d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 10 Dec 2025 20:20:22 +0000 Subject: [PATCH 15/15] Do not suggest moving expression out of for loop when hitting `break` from desugaring --- .../src/diagnostics/conflict_errors.rs | 4 +- .../closure/spawn-thread.edition2018.stderr | 10 ----- .../moves/arc-consumed-in-looped-closure.rs | 37 +++++++++++++++++++ .../arc-consumed-in-looped-closure.stderr | 27 ++++++++++++++ .../nested-loop-moved-value-wrong-continue.rs | 6 +-- ...ted-loop-moved-value-wrong-continue.stderr | 30 +++------------ 6 files changed, 74 insertions(+), 40 deletions(-) create mode 100644 tests/ui/moves/arc-consumed-in-looped-closure.rs create mode 100644 tests/ui/moves/arc-consumed-in-looped-closure.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f8a6fafbe78ac..2999d1f2926cc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -4521,7 +4521,9 @@ struct BreakFinder { impl<'hir> Visitor<'hir> for BreakFinder { fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { match ex.kind { - hir::ExprKind::Break(destination, _) => { + hir::ExprKind::Break(destination, _) + if !ex.span.is_desugaring(DesugaringKind::ForLoop) => + { self.found_breaks.push((destination, ex.span)); } hir::ExprKind::Continue(destination) => { diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr index ac8e1c5fa858d..4ac5dfb8d228a 100644 --- a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr +++ b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr @@ -12,16 +12,6 @@ LL | | drop((x.0, x.1, x.2)); | | --- use occurs due to use in closure LL | | }); | |_________- value moved here, in previous iteration of loop - | -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = std::thread::spawn(use || { -LL + -LL + drop((x.0, x.1, x.2)); -LL + }); -LL ~ for _ in 0..10 { -LL ~ let handler = value; - | error: aborting due to 1 previous error diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.rs b/tests/ui/moves/arc-consumed-in-looped-closure.rs new file mode 100644 index 0000000000000..8700c78508476 --- /dev/null +++ b/tests/ui/moves/arc-consumed-in-looped-closure.rs @@ -0,0 +1,37 @@ +use std::thread; +use std::sync::{Arc, Mutex, Condvar}; +use std::collections::VecDeque; + +type Job = Box; + +struct ThreadPool { + workers: Vec>, + queue: Arc<()>, +} + +impl ThreadPool { + fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + panic!() + } +} + +fn main() { + let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because + let pool = ThreadPool { + workers: vec![], + queue: Arc::new(()), + }; + + for i in 0..20 { //~ NOTE inside of this loop + // let results = Arc::clone(&results); // Forgot this. + pool.execute(move || { //~ ERROR E0382 + //~^ NOTE value moved into closure here, in previous iteration of loop + //~| HELP consider cloning the value before moving it into the closure + let mut r = results.lock().unwrap(); //~ NOTE use occurs due to use in closure + r.push(i); + }); + } +} diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.stderr b/tests/ui/moves/arc-consumed-in-looped-closure.stderr new file mode 100644 index 0000000000000..47d6fd6cbad3b --- /dev/null +++ b/tests/ui/moves/arc-consumed-in-looped-closure.stderr @@ -0,0 +1,27 @@ +error[E0382]: use of moved value: `results` + --> $DIR/arc-consumed-in-looped-closure.rs:30:22 + | +LL | let results = Arc::new(Mutex::new(Vec::new())); + | ------- move occurs because `results` has type `Arc>>`, which does not implement the `Copy` trait +... +LL | for i in 0..20 { + | -------------- inside of this loop +LL | // let results = Arc::clone(&results); // Forgot this. +LL | pool.execute(move || { + | ^^^^^^^ value moved into closure here, in previous iteration of loop +... +LL | let mut r = results.lock().unwrap(); + | ------- use occurs due to use in closure + | +help: consider cloning the value before moving it into the closure + | +LL ~ let value = results.clone(); +LL ~ pool.execute(move || { +LL | +LL | +LL ~ let mut r = value.lock().unwrap(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs index 87800d314ed50..0cbb501a57641 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs @@ -7,8 +7,6 @@ fn foo() { //~^ NOTE this reinitialization might get skipped //~| NOTE move occurs because `foo` has type `String` //~| NOTE inside of this loop - //~| HELP consider moving the expression out of the loop - //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE //~| NOTE baz.push(foo); @@ -35,8 +33,6 @@ fn main() { //~| NOTE for bar in &bars { //~^ NOTE inside of this loop - //~| HELP consider moving the expression out of the loop - //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE if foo == *bar { baz.push(foo); @@ -44,7 +40,7 @@ fn main() { //~| HELP consider cloning the value continue; //~^ NOTE verify that your loop breaking logic is correct - //~| NOTE this `continue` advances the loop at line 36 + //~| NOTE this `continue` advances the loop at line 34 } } qux.push(foo); diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr index 6ef1a4193b1ae..60be70007fbe2 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --- ---------------- inside of this loop @@ -14,29 +14,20 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:17:9 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --------------- ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8 -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ for foo in foos { let mut value = baz.push(foo); -LL ~ for bar in &bars { if foo == *bar { -LL | -... -LL | -LL ~ value; - | + | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8 help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone()); | ++++++++ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18 | LL | for foo in foos { | --- @@ -54,7 +45,7 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:45:17 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17 | LL | for foo in foos { | --------------- @@ -63,16 +54,7 @@ LL | for bar in &bars { | ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at line 36 -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = baz.push(foo); -LL ~ for bar in &bars { -LL | -... -LL | if foo == *bar { -LL ~ value; - | + | ^^^^^^^^ this `continue` advances the loop at line 34 help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone());