authorbors <bors@rust-lang.org> 2026-07-06 18:54:19 UTC
committerbors <bors@rust-lang.org> 2026-07-06 18:54:19 UTC
logc4af71034e89a431eeee91125a31ad001379faac
treec008f1eb6e980c3c5aa61f648765eee6a32a549c
parent36714a9983d6ba11203d8bb87a1b372247fbcf06
parent2847dbc72bda323bf461ccc97b5ab42851b367ff

Auto merge of #158847 - jhpratt:rollup-MkjhKjV, r=jhpratt

Rollup of 24 pull requests Successful merges: - rust-lang/rust#158377 (add `-Zforce-intrinsic-fallback` flag) - rust-lang/rust#158642 (Clarify some interning details) - rust-lang/rust#158694 (Positive test for closures needing expectations) - rust-lang/rust#158743 (Look for cdb location in the registry first) - rust-lang/rust#158775 (bootstrap: only encode RUSTFLAGS when a flag contains a space) - rust-lang/rust#158782 (Add and use cfg(target_has_threads) to enforce no_thread impl usage) - rust-lang/rust#158785 (hook intrinsic-test into aarch64-gnu) - rust-lang/rust#158819 (Put `InhabitedPredicate::NotInModule` earlier in disjunction since it can be a lot faster) - rust-lang/rust#157734 (Stabilize `local_key_cell_update`) - rust-lang/rust#158183 (std: allocate less memory in `current_exe` for OpenBSD) - rust-lang/rust#158310 (Remove unexpected usage of Unambig in non-infer variants) - rust-lang/rust#158671 (Move tests batch 17) - rust-lang/rust#158730 (Update `FIXME(static_mut_refs)` comments) - rust-lang/rust#158752 (Reorganize `tests/ui/issues` [18/N]) - rust-lang/rust#158755 (Use `ThinVec` more in the AST) - rust-lang/rust#158757 (Fix incorrect tracking issue for `read_le`/`read_be`) - rust-lang/rust#158765 (Fix ICE on non-ident path in `doc(auto_cfg values)`) - rust-lang/rust#158771 (library: expand HashSet::extract_if coverage) - rust-lang/rust#158772 (rustc-dev-guide subtree update) - rust-lang/rust#158776 (fix: emit diagnostic for AVR target without target-cpu) - rust-lang/rust#158786 (Add regression test for builtin attr macro values) - rust-lang/rust#158810 (Add supplementary information for get_unchecked(mut)) - rust-lang/rust#158825 (Fix typo) - rust-lang/rust#158838 (tidy: Use `empty_alternate = true` for triagebot mention glob check)

223 files changed, 1839 insertions(+), 1078 deletions(-)

compiler/rustc_ast/src/ast.rs+13-3
......@@ -407,7 +407,7 @@ impl GenericBound {
407407 }
408408}
409409
410pub type GenericBounds = Vec<GenericBound>;
410pub type GenericBounds = ThinVec<GenericBound>;
411411
412412/// Specifies the enforced ordering for generic parameters. In the future,
413413/// if we wanted to relax this order, we could override `PartialEq` and
......@@ -1534,7 +1534,7 @@ impl Expr {
15341534 let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) else {
15351535 return None;
15361536 };
1537 TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None)
1537 TyKind::TraitObject(thin_vec![lhs, rhs], TraitObjectSyntax::None)
15381538 }
15391539
15401540 ExprKind::Underscore => TyKind::Infer,
......@@ -1868,7 +1868,7 @@ pub enum ExprKind {
18681868 ///
18691869 /// Usually not written directly in user code but
18701870 /// indirectly via the macro `core::mem::offset_of!(...)`.
1871 OffsetOf(Box<Ty>, Vec<Ident>),
1871 OffsetOf(Box<Ty>, ThinVec<Ident>),
18721872
18731873 /// A macro invocation; pre-expansion.
18741874 MacCall(Box<MacCall>),
......@@ -4391,27 +4391,37 @@ mod size_asserts {
43914391 // tidy-alphabetical-start
43924392 static_assert_size!(AssocItem, 80);
43934393 static_assert_size!(AssocItemKind, 16);
4394 static_assert_size!(AttrKind, 16);
43944395 static_assert_size!(Attribute, 32);
43954396 static_assert_size!(Block, 32);
43964397 static_assert_size!(Expr, 72);
43974398 static_assert_size!(ExprKind, 40);
43984399 static_assert_size!(Fn, 192);
4400 static_assert_size!(FnDecl, 24);
4401 static_assert_size!(FnHeader, 76);
4402 static_assert_size!(FnSig, 96);
43994403 static_assert_size!(ForeignItem, 80);
44004404 static_assert_size!(ForeignItemKind, 16);
44014405 static_assert_size!(GenericArg, 24);
4406 static_assert_size!(GenericArgs, 40);
44024407 static_assert_size!(GenericBound, 88);
4408 static_assert_size!(GenericParam, 80);
44034409 static_assert_size!(Generics, 40);
44044410 static_assert_size!(Impl, 80);
44054411 static_assert_size!(Item, 152);
44064412 static_assert_size!(ItemKind, 88);
4413 static_assert_size!(Lifetime, 16);
44074414 static_assert_size!(LitKind, 24);
44084415 static_assert_size!(Local, 96);
4416 static_assert_size!(MetaItem, 88);
4417 static_assert_size!(MetaItemKind, 40);
44094418 static_assert_size!(MetaItemLit, 40);
44104419 static_assert_size!(Param, 40);
44114420 static_assert_size!(Pat, 80);
44124421 static_assert_size!(PatKind, 56);
44134422 static_assert_size!(Path, 24);
44144423 static_assert_size!(PathSegment, 24);
4424 static_assert_size!(QSelf, 24);
44154425 static_assert_size!(Stmt, 32);
44164426 static_assert_size!(StmtKind, 16);
44174427 static_assert_size!(TraitImplHeader, 72);
compiler/rustc_ast/src/visit.rs+2
......@@ -386,6 +386,8 @@ macro_rules! common_visitor_and_walkers {
386386 impl_visitable_list!(<$($lt)? $($mut)?>
387387 ThinVec<AngleBracketedArg>,
388388 ThinVec<Attribute>,
389 ThinVec<GenericBound>,
390 ThinVec<Ident>,
389391 ThinVec<(Ident, Option<Ident>)>,
390392 ThinVec<(NodeId, Path)>,
391393 ThinVec<PathSegment>,
compiler/rustc_attr_parsing/src/attributes/doc.rs+6-5
......@@ -348,8 +348,11 @@ impl DocParser {
348348 // If it's a list, then only `any()` and `none()` are allowed and they must not
349349 // contain any item.
350350 MetaItemOrLitParser::MetaItemParser(sub_item) => {
351 if let Some(ident) = sub_item.ident()
352 && [sym::any, sym::none].contains(&ident.name)
351 let Some(ident) = sub_item.ident() else {
352 cx.adcx().expected_identifier(sub_item.path().span());
353 continue;
354 };
355 if [sym::any, sym::none].contains(&ident.name)
353356 && let ArgParser::List(list) = sub_item.args()
354357 && list.mixed().count() == 0
355358 {
......@@ -371,9 +374,7 @@ impl DocParser {
371374 } else {
372375 cx.emit_lint(
373376 rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
374 DocAutoCfgHideShowUnexpectedItem {
375 attr_name: sub_item.ident().unwrap().name,
376 },
377 DocAutoCfgHideShowUnexpectedItem { attr_name: ident.name },
377378 sub_item.span(),
378379 );
379380 }
compiler/rustc_builtin_macros/src/deriving/debug.rs+1-1
......@@ -167,7 +167,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) ->
167167 let ty_dyn_debug = cx.ty(
168168 span,
169169 ast::TyKind::TraitObject(
170 vec![cx.trait_bound(path_debug, false)],
170 thin_vec![cx.trait_bound(path_debug, false)],
171171 ast::TraitObjectSyntax::Dyn,
172172 ),
173173 );
compiler/rustc_builtin_macros/src/deriving/generic/mod.rs+3-3
......@@ -617,7 +617,7 @@ impl<'a> TraitDef<'a> {
617617 ident,
618618 generics: Generics::default(),
619619 after_where_clause: ast::WhereClause::default(),
620 bounds: Vec::new(),
620 bounds: ThinVec::new(),
621621 ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)),
622622 })),
623623 tokens: None,
......@@ -639,7 +639,7 @@ impl<'a> TraitDef<'a> {
639639 // Extra restrictions on the generics parameters to the
640640 // type being derived upon.
641641 let span = param.ident.span.with_ctxt(ctxt);
642 let bounds: Vec<_> = self
642 let bounds: ThinVec<_> = self
643643 .additional_bounds
644644 .iter()
645645 .map(|p| {
......@@ -723,7 +723,7 @@ impl<'a> TraitDef<'a> {
723723 {
724724 continue;
725725 }
726 let mut bounds: Vec<_> = self
726 let mut bounds: ThinVec<_> = self
727727 .additional_bounds
728728 .iter()
729729 .map(|p| {
compiler/rustc_codegen_llvm/src/back/write.rs+3-9
......@@ -22,7 +22,7 @@ use rustc_fs_util::{link_or_copy, path_to_c_string};
2222use rustc_middle::ty::TyCtxt;
2323use rustc_session::Session;
2424use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
25use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym};
25use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext};
2626use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
2727use tracing::{debug, trace};
2828
......@@ -209,14 +209,8 @@ pub(crate) fn target_machine_factory(
209209
210210 let code_model = to_llvm_code_model(sess.code_model());
211211
212 let mut singlethread = sess.target.singlethread;
213
214 // On the wasm target once the `atomics` feature is enabled that means that
215 // we're no longer single-threaded, or otherwise we don't want LLVM to
216 // lower atomic operations to single-threaded operations.
217 if singlethread && sess.target.is_like_wasm && sess.target_features.contains(&sym::atomics) {
218 singlethread = false;
219 }
212 // This is used to set cfg_has_threads, so all logic must be in this method.
213 let singlethread = sess.target.singlethread(&sess.target_features);
220214
221215 let triple = SmallCStr::new(&versioned_llvm_target(sess));
222216 let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
compiler/rustc_codegen_ssa/src/back/metadata.rs+2-1
......@@ -24,6 +24,7 @@ use rustc_target::spec::{CfgAbi, LlvmAbi, Os, RelocModel, Target, ef_avr_arch};
2424use tracing::debug;
2525
2626use super::apple;
27use crate::errors;
2728
2829/// The default metadata loader. This is used by cg_llvm and cg_clif.
2930///
......@@ -370,7 +371,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
370371 if let Some(ref cpu) = sess.opts.cg.target_cpu {
371372 ef_avr_arch(cpu)
372373 } else {
373 bug!("AVR CPU not explicitly specified")
374 sess.dcx().emit_fatal(errors::CpuRequired)
374375 }
375376 }
376377 Architecture::Csky => {
compiler/rustc_codegen_ssa/src/mir/intrinsic.rs+11
......@@ -63,6 +63,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6363 result_place: Option<PlaceValue<Bx::Value>>,
6464 source_info: SourceInfo,
6565 ) -> IntrinsicResult<'tcx, Bx::Value> {
66 // When `-Zforce-intrinsic-fallback` is enabled, always use the fallback body if it exists,
67 if bx.tcx().sess.opts.unstable_opts.force_intrinsic_fallback
68 && let Some(def) = bx.tcx().intrinsic(instance.def_id())
69 && !def.must_be_overridden
70 {
71 return IntrinsicResult::Fallback(ty::Instance::new_raw(
72 instance.def_id(),
73 instance.args,
74 ));
75 }
76
6677 let span = source_info.span;
6778
6879 let name = bx.tcx().item_name(instance.def_id());
compiler/rustc_data_structures/src/intern.rs+30-48
......@@ -1,4 +1,3 @@
1use std::cmp::Ordering;
21use std::fmt::{self, Debug};
32use std::hash::{Hash, Hasher};
43use std::ops::Deref;
......@@ -11,26 +10,40 @@ mod private {
1110 pub struct PrivateZst;
1211}
1312
14/// A reference to a value that is interned, and is known to be unique.
13/// This type is a reference with one special behaviour: the reference pointer (i.e. the address of
14/// the value referred to) is used for equality and hashing, rather than the value's contents, as
15/// would occur with a vanilla reference. There are two cases when this is useful.
1516///
16/// Note that it is possible to have a `T` and a `Interned<T>` that are (or
17/// refer to) equal but different values. But if you have two different
18/// `Interned<T>`s, they both refer to the same value, at a single location in
19/// memory. This means that equality and hashing can be done on the value's
20/// address rather than the value's contents, which can improve performance.
17/// - Types where uniqueness is guaranteed. This is most commonly achieved via interning -- hence
18/// the name `Interned` -- though it may also be possible via other means. In this case, the use
19/// of `Interned` is primarily a performance optimization, because pointer equality/hashing gives
20/// the same results as value equality/hashing, but is faster. (The use of the `Interned` type
21/// also provides documentation about the interned-ness.)
2122///
22/// The `PrivateZst` field means you can pattern match with `Interned(v, _)`
23/// but you can only construct a `Interned` with `new_unchecked`, and not
24/// directly.
23/// Note that in this case it is possible to have a `T` and a `Interned<T>` that are (or refer
24/// to) equal but different values. But if you have two different `Interned<T>`s, they both refer
25/// to the same value, at a single location in memory.
26///
27/// - Types with identity, where distinct values should always be considered unequal, even if they
28/// have equal values. These are rare in Rust, but do occur sometimes. In this case, the use of
29/// `Interned` gives different behaviour, because pointer equality/hashing gives different result
30/// to value equality/hashing, and is also faster.
31///
32/// The `PrivateZst` field means you can pattern match with `Interned(v, _)` but you can only
33/// construct a `Interned` with `new_unchecked`, and not directly. This means that all creation
34/// points can be audited easily.
2535#[rustc_pass_by_value]
2636pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst);
2737
2838impl<'a, T> Interned<'a, T> {
29 /// Create a new `Interned` value. The value referred to *must* be interned
30 /// and thus be unique, and it *must* remain unique in the future. This
31 /// function has `_unchecked` in the name but is not `unsafe`, because if
32 /// the uniqueness condition is violated condition it will cause incorrect
33 /// behaviour but will not affect memory safety.
39 /// Create a new `Interned` value. The value referred to *must* satisfy one of the following
40 /// two conditions.
41 /// - It must be unique and it must remain unique in the future.
42 /// - It must be of a type with "identity" such that distinct values should always be
43 /// considered unequal.
44 ///
45 /// This function has `_unchecked` in the name but is not `unsafe`, because if neither of these
46 /// conditions is met it will cause incorrect behaviour but will not affect memory safety.
3447 #[inline]
3548 pub const fn new_unchecked(t: &'a T) -> Self {
3649 Interned(t, private::PrivateZst)
......@@ -64,41 +77,10 @@ impl<'a, T> PartialEq for Interned<'a, T> {
6477
6578impl<'a, T> Eq for Interned<'a, T> {}
6679
67impl<'a, T: PartialOrd> PartialOrd for Interned<'a, T> {
68 fn partial_cmp(&self, other: &Interned<'a, T>) -> Option<Ordering> {
69 // Pointer equality implies equality, due to the uniqueness constraint,
70 // but the contents must be compared otherwise.
71 if ptr::eq(self.0, other.0) {
72 Some(Ordering::Equal)
73 } else {
74 let res = self.0.partial_cmp(other.0);
75 debug_assert_ne!(res, Some(Ordering::Equal));
76 res
77 }
78 }
79}
80
81impl<'a, T: Ord> Ord for Interned<'a, T> {
82 fn cmp(&self, other: &Interned<'a, T>) -> Ordering {
83 // Pointer equality implies equality, due to the uniqueness constraint,
84 // but the contents must be compared otherwise.
85 if ptr::eq(self.0, other.0) {
86 Ordering::Equal
87 } else {
88 let res = self.0.cmp(other.0);
89 debug_assert_ne!(res, Ordering::Equal);
90 res
91 }
92 }
93}
94
95impl<'a, T> Hash for Interned<'a, T>
96where
97 T: Hash,
98{
80impl<'a, T> Hash for Interned<'a, T> {
9981 #[inline]
10082 fn hash<H: Hasher>(&self, s: &mut H) {
101 // Pointer hashing is sufficient, due to the uniqueness constraint.
83 // Pointer hashing is sufficient.
10284 ptr::hash(self.0, s)
10385 }
10486}
compiler/rustc_data_structures/src/intern/tests.rs+1-26
......@@ -1,5 +1,6 @@
11use super::*;
22
3#[allow(unused)]
34#[derive(Debug)]
45struct S(u32);
56
......@@ -11,22 +12,6 @@ impl PartialEq for S {
1112
1213impl Eq for S {}
1314
14impl PartialOrd for S {
15 fn partial_cmp(&self, other: &S) -> Option<Ordering> {
16 // The `==` case should be handled by `Interned`.
17 assert_ne!(self.0, other.0);
18 self.0.partial_cmp(&other.0)
19 }
20}
21
22impl Ord for S {
23 fn cmp(&self, other: &S) -> Ordering {
24 // The `==` case should be handled by `Interned`.
25 assert_ne!(self.0, other.0);
26 self.0.cmp(&other.0)
27 }
28}
29
3015#[test]
3116fn test_uniq() {
3217 let s1 = S(1);
......@@ -45,14 +30,4 @@ fn test_uniq() {
4530 assert_eq!(v1, v1);
4631 assert_eq!(v3a, v3b);
4732 assert_ne!(v1, v4); // same content but different addresses: not equal
48
49 assert_eq!(v1.cmp(&v2), Ordering::Less);
50 assert_eq!(v3a.cmp(&v2), Ordering::Greater);
51 assert_eq!(v1.cmp(&v1), Ordering::Equal); // only uses Interned::eq, not S::cmp
52 assert_eq!(v3a.cmp(&v3b), Ordering::Equal); // only uses Interned::eq, not S::cmp
53
54 assert_eq!(v1.partial_cmp(&v2), Some(Ordering::Less));
55 assert_eq!(v3a.partial_cmp(&v2), Some(Ordering::Greater));
56 assert_eq!(v1.partial_cmp(&v1), Some(Ordering::Equal)); // only uses Interned::eq, not S::cmp
57 assert_eq!(v3a.partial_cmp(&v3b), Some(Ordering::Equal)); // only uses Interned::eq, not S::cmp
5833}
compiler/rustc_feature/src/builtin_attrs.rs+1
......@@ -50,6 +50,7 @@ const GATED_CFGS: &[GatedCfg] = &[
5050 sym::cfg_target_has_reliable_f16_f128,
5151 Features::cfg_target_has_reliable_f16_f128,
5252 ),
53 (sym::target_has_threads, sym::cfg_target_has_threads, Features::cfg_target_has_threads),
5354 (sym::target_object_format, sym::cfg_target_object_format, Features::cfg_target_object_format),
5455];
5556
compiler/rustc_feature/src/unstable.rs+2
......@@ -254,6 +254,8 @@ declare_features! (
254254 (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
255255 /// Allows checking whether or not the backend correctly supports unstable float types.
256256 (internal, cfg_target_has_reliable_f16_f128, "1.88.0", None),
257 /// Allows checking whether or not the target might have thread support.
258 (internal, cfg_target_has_threads, "CURRENT_RUSTC_VERSION", None),
257259 /// Allows identifying the `compiler_builtins` crate.
258260 (internal, compiler_builtins, "1.13.0", None),
259261 /// Allows skipping `ConstParamTy_` trait implementation checks
compiler/rustc_hir/src/hir.rs+1-1
......@@ -511,7 +511,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> {
511511#[derive(Clone, Copy, Debug, StableHash)]
512512#[repr(u8, C)]
513513pub enum ConstArgKind<'hir, Unambig = ()> {
514 Tup(&'hir [&'hir ConstArg<'hir, Unambig>]),
514 Tup(&'hir [&'hir ConstArg<'hir>]),
515515 /// **Note:** Currently this is only used for bare const params
516516 /// (`N` where `fn foo<const N: usize>(...)`),
517517 /// not paths to any const (`N` where `const N: usize = ...`).
compiler/rustc_hir/src/intravisit.rs+1-1
......@@ -1088,7 +1088,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>(
10881088 try_visit!(visitor.visit_id(*hir_id));
10891089 match kind {
10901090 ConstArgKind::Tup(exprs) => {
1091 walk_list!(visitor, visit_const_arg, *exprs);
1091 walk_list!(visitor, visit_const_arg_unambig, *exprs);
10921092 V::Result::output()
10931093 }
10941094 ConstArgKind::Struct(qpath, field_exprs) => {
compiler/rustc_middle/src/ty/inhabitedness/mod.rs+1-1
......@@ -93,7 +93,7 @@ impl<'tcx> VariantDef {
9393 match field.vis {
9494 Visibility::Public => pred,
9595 Visibility::Restricted(from) => {
96 pred.or(tcx, InhabitedPredicate::NotInModule(from))
96 InhabitedPredicate::NotInModule(from).or(tcx, pred)
9797 }
9898 }
9999 }),
compiler/rustc_monomorphize/src/collector.rs+9-2
......@@ -995,11 +995,18 @@ fn visit_instance_use<'tcx>(
995995 output.push(create_fn_mono_item(tcx, panic_instance, source));
996996 }
997997 } else if !intrinsic.must_be_overridden
998 && !tcx.sess.replaced_intrinsics.contains(&intrinsic.name)
998 && (tcx.sess.opts.unstable_opts.force_intrinsic_fallback
999 || !tcx.sess.replaced_intrinsics.contains(&intrinsic.name))
9991000 {
10001001 // Codegen the fallback body of intrinsics with fallback bodies.
10011002 // We have to skip this otherwise as there's no body to codegen.
1002 // We also skip intrinsics the backend handles, to reduce monomorphizations.
1003 //
1004 // We also skip `replaced_intrinsics` which are always replaced by the backend and hence
1005 // monomorphizing the fallback body would be pointless.
1006 //
1007 // However, when -Zforce-intrinsic-fallback is set (e.g. to test the fallback
1008 // implementations) we ignore the optimization hint and do monomorphize
1009 // the fallback body.
10031010 let instance = ty::Instance::new_raw(instance.def_id(), instance.args);
10041011 if tcx.should_codegen_locally(instance) {
10051012 output.push(create_fn_mono_item(tcx, instance, source));
compiler/rustc_parse/src/parser/expr.rs+2-2
......@@ -1154,8 +1154,8 @@ impl<'a> Parser<'a> {
11541154 /// Parse the field access used in offset_of, matched by `$(e:expr)+`.
11551155 /// Currently returns a list of idents. However, it should be possible in
11561156 /// future to also do array indices, which might be arbitrary expressions.
1157 pub(crate) fn parse_floating_field_access(&mut self) -> PResult<'a, Vec<Ident>> {
1158 let mut fields = Vec::new();
1157 pub(crate) fn parse_floating_field_access(&mut self) -> PResult<'a, ThinVec<Ident>> {
1158 let mut fields = ThinVec::new();
11591159 let mut trailing_dot = None;
11601160
11611161 loop {
compiler/rustc_parse/src/parser/generics.rs+6-6
......@@ -26,7 +26,7 @@ impl<'a> Parser<'a> {
2626 /// BOUND = LT_BOUND (e.g., `'a`)
2727 /// ```
2828 fn parse_lt_param_bounds(&mut self) -> GenericBounds {
29 let mut lifetimes = Vec::new();
29 let mut lifetimes = ThinVec::new();
3030 while self.check_lifetime() {
3131 lifetimes.push(ast::GenericBound::Outlives(self.expect_lifetime()));
3232
......@@ -86,7 +86,7 @@ impl<'a> Parser<'a> {
8686 }
8787 self.parse_generic_bounds()?
8888 } else {
89 Vec::new()
89 ThinVec::new()
9090 };
9191
9292 let default = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
......@@ -125,7 +125,7 @@ impl<'a> Parser<'a> {
125125 ident,
126126 id: ast::DUMMY_NODE_ID,
127127 attrs: preceding_attrs,
128 bounds: Vec::new(),
128 bounds: ThinVec::new(),
129129 kind: GenericParamKind::Const { ty, span, default: None },
130130 is_placeholder: false,
131131 colon_span: None,
......@@ -148,7 +148,7 @@ impl<'a> Parser<'a> {
148148 ident,
149149 id: ast::DUMMY_NODE_ID,
150150 attrs: preceding_attrs,
151 bounds: Vec::new(),
151 bounds: ThinVec::new(),
152152 kind: GenericParamKind::Const { ty, span, default },
153153 is_placeholder: false,
154154 colon_span: None,
......@@ -189,7 +189,7 @@ impl<'a> Parser<'a> {
189189 ident,
190190 id: ast::DUMMY_NODE_ID,
191191 attrs: preceding_attrs,
192 bounds: Vec::new(),
192 bounds: ThinVec::new(),
193193 kind: GenericParamKind::Const { ty, span, default },
194194 is_placeholder: false,
195195 colon_span: None,
......@@ -225,7 +225,7 @@ impl<'a> Parser<'a> {
225225 let (colon_span, bounds) = if this.eat(exp!(Colon)) {
226226 (Some(this.prev_token.span), this.parse_lt_param_bounds())
227227 } else {
228 (None, Vec::new())
228 (None, ThinVec::new())
229229 };
230230
231231 if this.check_noexpect(&token::Eq) && this.look_ahead(1, |t| t.is_lifetime()) {
compiler/rustc_parse/src/parser/item.rs+3-2
......@@ -1148,7 +1148,7 @@ impl<'a> Parser<'a> {
11481148 // Parse optional colon and supertrait bounds.
11491149 let had_colon = self.eat(exp!(Colon));
11501150 let span_at_colon = self.prev_token.span;
1151 let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
1151 let bounds = if had_colon { self.parse_generic_bounds()? } else { ThinVec::new() };
11521152
11531153 let span_before_eq = self.prev_token.span;
11541154 if self.eat(exp!(Eq)) {
......@@ -1266,7 +1266,8 @@ impl<'a> Parser<'a> {
12661266 let mut generics = self.parse_generics()?;
12671267
12681268 // Parse optional colon and param bounds.
1269 let bounds = if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { Vec::new() };
1269 let bounds =
1270 if self.eat(exp!(Colon)) { self.parse_generic_bounds()? } else { ThinVec::new() };
12701271 generics.where_clause = self.parse_where_clause()?;
12711272
12721273 let ty = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None };
compiler/rustc_parse/src/parser/ty.rs+4-4
......@@ -576,7 +576,7 @@ impl<'a> Parser<'a> {
576576 lo.to(self.prev_token.span),
577577 parens,
578578 );
579 let bounds = vec![GenericBound::Trait(poly_trait_ref)];
579 let bounds = thin_vec![GenericBound::Trait(poly_trait_ref)];
580580 self.parse_remaining_bounds(bounds, parse_plus)
581581 }
582582
......@@ -1080,7 +1080,7 @@ impl<'a> Parser<'a> {
10801080 /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted).
10811081 /// Otherwise, this only parses a single bound or none.
10821082 fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> {
1083 let mut bounds = Vec::new();
1083 let mut bounds = ThinVec::new();
10841084
10851085 // In addition to looping while we find generic bounds:
10861086 // We continue even if we find a keyword. This is necessary for error recovery on,
......@@ -1432,7 +1432,7 @@ impl<'a> Parser<'a> {
14321432 // Someone has written something like `&dyn (Trait + Other)`. The correct code
14331433 // would be `&(dyn Trait + Other)`
14341434 if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
1435 let bounds = vec![];
1435 let bounds = thin_vec![];
14361436 self.parse_remaining_bounds(bounds, true)?;
14371437 self.expect(exp!(CloseParen))?;
14381438 self.dcx().emit_err(errors::IncorrectParensTraitBounds {
......@@ -1617,7 +1617,7 @@ impl<'a> Parser<'a> {
16171617 id: lt.id,
16181618 ident: lt.ident,
16191619 attrs: ast::AttrVec::new(),
1620 bounds: Vec::new(),
1620 bounds: ThinVec::new(),
16211621 is_placeholder: false,
16221622 kind: ast::GenericParamKind::Lifetime,
16231623 colon_span: None,
compiler/rustc_resolve/src/imports.rs+4-15
......@@ -210,23 +210,10 @@ pub(crate) struct ImportData<'ra> {
210210 pub on_unknown_attr: Option<OnUnknownData>,
211211}
212212
213/// All imports are unique and allocated on a same arena,
214/// so we can use referential equality to compare them.
213/// `Interned` is used because values of this type have "identity" and compare as unequal even if
214/// they have the same contents.
215215pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>;
216216
217// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the
218// contained data.
219// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees
220// are upheld.
221impl std::hash::Hash for ImportData<'_> {
222 fn hash<H>(&self, _: &mut H)
223 where
224 H: std::hash::Hasher,
225 {
226 unreachable!()
227 }
228}
229
230217impl<'ra> ImportData<'ra> {
231218 pub(crate) fn is_glob(&self) -> bool {
232219 matches!(self.kind, ImportKind::Glob { .. })
......@@ -291,6 +278,8 @@ pub(crate) struct NameResolution<'ra> {
291278 pub orig_ident_span: Span,
292279}
293280
281/// `Interned` is used because values of this type have "identity" and compare as unequal even if
282/// they have the same contents.
294283pub(crate) type NameResolutionRef<'ra> = Interned<'ra, CmRefCell<NameResolution<'ra>>>;
295284
296285impl<'ra> NameResolution<'ra> {
compiler/rustc_resolve/src/late/diagnostics.rs+2-2
......@@ -28,7 +28,7 @@ use rustc_session::{Session, lint};
2828use rustc_span::edit_distance::{edit_distance, find_best_match_for_name};
2929use rustc_span::edition::Edition;
3030use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
31use thin_vec::ThinVec;
31use thin_vec::{ThinVec, thin_vec};
3232use tracing::debug;
3333
3434use super::NoConstantGenericsReason;
......@@ -4522,7 +4522,7 @@ fn mk_where_bound_predicate(
45224522 let new_where_bound_predicate = ast::WhereBoundPredicate {
45234523 bound_generic_params: ThinVec::new(),
45244524 bounded_ty: Box::new(ty.clone()),
4525 bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
4525 bounds: thin_vec![ast::GenericBound::Trait(ast::PolyTraitRef {
45264526 bound_generic_params: ThinVec::new(),
45274527 modifiers: ast::TraitBoundModifiers::NONE,
45284528 trait_ref: ast::TraitRef {
compiler/rustc_resolve/src/lib.rs+9-30
......@@ -683,8 +683,8 @@ struct ModuleData<'ra> {
683683 self_decl: Option<Decl<'ra>>,
684684}
685685
686/// All modules are unique and allocated on a same arena,
687/// so we can use referential equality to compare them.
686/// `Interned` is used because values of this type have "identity" and compare as unequal even if
687/// they have the same contents.
688688#[derive(Clone, Copy, PartialEq, Eq, Hash)]
689689#[rustc_pass_by_value]
690690struct Module<'ra>(Interned<'ra, ModuleData<'ra>>);
......@@ -699,19 +699,6 @@ struct LocalModule<'ra>(Interned<'ra, ModuleData<'ra>>);
699699#[rustc_pass_by_value]
700700struct ExternModule<'ra>(Interned<'ra, ModuleData<'ra>>);
701701
702// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the
703// contained data.
704// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees
705// are upheld.
706impl std::hash::Hash for ModuleData<'_> {
707 fn hash<H>(&self, _: &mut H)
708 where
709 H: std::hash::Hasher,
710 {
711 unreachable!()
712 }
713}
714
715702impl<'ra> ModuleData<'ra> {
716703 fn new(
717704 parent: Option<Module<'ra>>,
......@@ -916,6 +903,7 @@ impl<'ra> LocalModule<'ra> {
916903 assert!(kind.is_local());
917904 let parent = parent.map(|m| m.to_module());
918905 let data = ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude, vis, arenas);
906 // SAFETY: `Interned` is valid because values of this type have "identity".
919907 LocalModule(Interned::new_unchecked(arenas.modules.alloc(data)))
920908 }
921909
......@@ -937,6 +925,7 @@ impl<'ra> ExternModule<'ra> {
937925 assert!(!kind.is_local());
938926 let parent = parent.map(|m| m.to_module());
939927 let data = ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude, vis, arenas);
928 // SAFETY: `Interned` is valid because values of this type have "identity".
940929 ExternModule(Interned::new_unchecked(arenas.modules.alloc(data)))
941930 }
942931
......@@ -1001,23 +990,10 @@ struct DeclData<'ra> {
1001990 parent_module: Option<Module<'ra>>,
1002991}
1003992
1004/// All name declarations are unique and allocated on a same arena,
1005/// so we can use referential equality to compare them.
993/// `Interned` is used because values of this type have "identity" and compare as unequal even if
994/// they have the same contents.
1006995type Decl<'ra> = Interned<'ra, DeclData<'ra>>;
1007996
1008// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the
1009// contained data.
1010// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees
1011// are upheld.
1012impl std::hash::Hash for DeclData<'_> {
1013 fn hash<H>(&self, _: &mut H)
1014 where
1015 H: std::hash::Hasher,
1016 {
1017 unreachable!()
1018 }
1019}
1020
1021997/// Name declaration kind.
1022998#[derive(Debug)]
1023999enum DeclKind<'ra> {
......@@ -1585,12 +1561,15 @@ impl<'ra> ResolverArenas<'ra> {
15851561 }
15861562
15871563 fn alloc_decl(&'ra self, data: DeclData<'ra>) -> Decl<'ra> {
1564 // SAFETY: `Interned` is valid because values of this type have "identity".
15881565 Interned::new_unchecked(self.dropless.alloc(data))
15891566 }
15901567 fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
1568 // SAFETY: `Interned` is valid because values of this type have "identity".
15911569 Interned::new_unchecked(self.imports.alloc(import))
15921570 }
15931571 fn alloc_name_resolution(&'ra self, orig_ident_span: Span) -> NameResolutionRef<'ra> {
1572 // SAFETY: `Interned` is valid because values of this type have "identity".
15941573 Interned::new_unchecked(
15951574 self.name_resolutions.alloc(CmRefCell::new(NameResolution::new(orig_ident_span))),
15961575 )
compiler/rustc_session/src/config/cfg.rs+6
......@@ -149,6 +149,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
149149 | (sym::target_pointer_width, Some(_))
150150 | (sym::target_vendor, None | Some(_))
151151 | (sym::target_has_atomic, Some(_))
152 | (sym::target_has_threads, None | Some(_))
152153 | (sym::target_has_atomic_primitive_alignment, Some(_))
153154 | (sym::target_has_atomic_load_store, Some(_))
154155 | (sym::target_has_reliable_f16, None | Some(_))
......@@ -303,6 +304,10 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
303304 }
304305 }
305306
307 if !sess.target.singlethread(&sess.target_features) {
308 ins_none!(sym::target_has_threads);
309 }
310
306311 ins_sym!(sym::target_os, sess.target.os.desc_symbol());
307312 ins_sym!(sym::target_pointer_width, sym::integer(sess.target.pointer_width));
308313
......@@ -485,6 +490,7 @@ impl CheckCfg {
485490 ins!(sym::target_has_atomic_primitive_alignment, empty_values).extend(atomic_values);
486491
487492 ins!(sym::target_thread_local, no_values);
493 ins!(sym::target_has_threads, no_values);
488494
489495 ins!(sym::ub_checks, no_values);
490496 ins!(sym::contract_checks, no_values);
compiler/rustc_session/src/options.rs+3
......@@ -2419,6 +2419,9 @@ options! {
24192419 fmt_debug: FmtDebug = (FmtDebug::Full, parse_fmt_debug, [TRACKED],
24202420 "how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \
24212421 `shallow` prints only type names, `none` prints nothing and disables `{:?}`. (default: `full`)"),
2422 force_intrinsic_fallback: bool = (false, parse_bool, [TRACKED],
2423 "always use the fallback body of an intrinsic, if it has one, instead of lowering \
2424 the intrinsic in the codegen backend (default: no)."),
24222425 force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
24232426 "force all crates to be `rustc_private` unstable (default: no)"),
24242427 function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED],
compiler/rustc_span/src/symbol.rs+2
......@@ -598,6 +598,7 @@ symbols! {
598598 cfg_target_has_atomic,
599599 cfg_target_has_atomic_equal_alignment,
600600 cfg_target_has_reliable_f16_f128,
601 cfg_target_has_threads,
601602 cfg_target_object_format,
602603 cfg_target_thread_local,
603604 cfg_target_vendor,
......@@ -2084,6 +2085,7 @@ symbols! {
20842085 target_has_reliable_f16_math,
20852086 target_has_reliable_f128,
20862087 target_has_reliable_f128_math,
2088 target_has_threads,
20872089 target_object_format,
20882090 target_os,
20892091 target_pointer_width,
compiler/rustc_target/src/spec/mod.rs+26-144
......@@ -40,11 +40,11 @@
4040use core::result::Result;
4141use std::borrow::Cow;
4242use std::collections::BTreeMap;
43use std::hash::{Hash, Hasher};
43use std::fmt;
44use std::hash::Hash;
4445use std::ops::{Deref, DerefMut};
4546use std::path::{Path, PathBuf};
4647use std::str::FromStr;
47use std::{fmt, io};
4848
4949use rustc_abi::{
5050 Align, CVariadicStatus, CanonAbi, Endian, ExternAbi, Integer, Size, TargetDataLayout,
......@@ -52,9 +52,7 @@ use rustc_abi::{
5252};
5353use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
5454use rustc_error_messages::{DiagArgValue, IntoDiagArg, into_diag_arg_using_display};
55use rustc_fs_util::try_canonicalize;
5655use rustc_macros::{BlobDecodable, Decodable, Encodable, StableHash};
57use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
5856use rustc_span::{Symbol, kw, sym};
5957use serde_json::Value;
6058use tracing::debug;
......@@ -67,11 +65,13 @@ pub mod crt_objects;
6765mod abi_map;
6866mod base;
6967mod json;
68mod tuple;
7069
7170pub use abi_map::{AbiMap, AbiMapping};
7271pub use base::apple;
7372pub use base::avr::ef_avr_arch;
7473pub use json::json_schema;
74pub use tuple::TargetTuple;
7575
7676/// Linker is called through a C/C++ compiler.
7777#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
......@@ -2256,6 +2256,26 @@ impl Target {
22562256 }
22572257 }
22582258 }
2259
2260 /// Is this target single-threaded?
2261 ///
2262 /// This affects both optimizations (e.g., atomics can be lowered to regular operations) and
2263 /// is also exposed as cfg(target_has_threads).
2264 pub fn singlethread(&self, target_features: &FxIndexSet<Symbol>) -> bool {
2265 // On the wasm target once the `atomics` feature is enabled that means that
2266 // we're no longer single-threaded, or otherwise we don't want LLVM to
2267 // lower atomic operations to single-threaded operations.
2268 //
2269 // FIXME: This (probably?) implies that atomics should be a target modifier, at which point
2270 // it probably makes sense to be a separate target to ship precompiled artifacts for it?
2271 //
2272 // cc #77839 (tracking issue for wasm atomics)
2273 if self.singlethread && self.is_like_wasm && target_features.contains(&sym::atomics) {
2274 return false;
2275 }
2276
2277 self.singlethread
2278 }
22592279}
22602280
22612281pub trait HasTargetSpec {
......@@ -2571,7 +2591,8 @@ pub struct TargetOptions {
25712591 pub requires_lto: bool,
25722592
25732593 /// This target has no support for threads.
2574 pub singlethread: bool,
2594 // This is private because wasm changes this depending on target features.
2595 singlethread: bool,
25752596
25762597 /// Whether library functions call lowering/optimization is disabled in LLVM
25772598 /// for this target unconditionally.
......@@ -3893,142 +3914,3 @@ impl Target {
38933914 Symbol::intern(&self.vendor)
38943915 }
38953916}
3896
3897/// Either a target tuple string or a path to a JSON file.
3898#[derive(Clone, Debug)]
3899pub enum TargetTuple {
3900 TargetTuple(String),
3901 TargetJson {
3902 /// Warning: This field may only be used by rustdoc. Using it anywhere else will lead to
3903 /// inconsistencies as it is discarded during serialization.
3904 path_for_rustdoc: PathBuf,
3905 tuple: String,
3906 contents: String,
3907 },
3908}
3909
3910// Use a manual implementation to ignore the path field
3911impl PartialEq for TargetTuple {
3912 fn eq(&self, other: &Self) -> bool {
3913 match (self, other) {
3914 (Self::TargetTuple(l0), Self::TargetTuple(r0)) => l0 == r0,
3915 (
3916 Self::TargetJson { path_for_rustdoc: _, tuple: l_tuple, contents: l_contents },
3917 Self::TargetJson { path_for_rustdoc: _, tuple: r_tuple, contents: r_contents },
3918 ) => l_tuple == r_tuple && l_contents == r_contents,
3919 _ => false,
3920 }
3921 }
3922}
3923
3924// Use a manual implementation to ignore the path field
3925impl Hash for TargetTuple {
3926 fn hash<H: Hasher>(&self, state: &mut H) -> () {
3927 match self {
3928 TargetTuple::TargetTuple(tuple) => {
3929 0u8.hash(state);
3930 tuple.hash(state)
3931 }
3932 TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents } => {
3933 1u8.hash(state);
3934 tuple.hash(state);
3935 contents.hash(state)
3936 }
3937 }
3938 }
3939}
3940
3941// Use a manual implementation to prevent encoding the target json file path in the crate metadata
3942impl<S: Encoder> Encodable<S> for TargetTuple {
3943 fn encode(&self, s: &mut S) {
3944 match self {
3945 TargetTuple::TargetTuple(tuple) => {
3946 s.emit_u8(0);
3947 s.emit_str(tuple);
3948 }
3949 TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents } => {
3950 s.emit_u8(1);
3951 s.emit_str(tuple);
3952 s.emit_str(contents);
3953 }
3954 }
3955 }
3956}
3957
3958impl<D: Decoder> Decodable<D> for TargetTuple {
3959 fn decode(d: &mut D) -> Self {
3960 match d.read_u8() {
3961 0 => TargetTuple::TargetTuple(d.read_str().to_owned()),
3962 1 => TargetTuple::TargetJson {
3963 path_for_rustdoc: PathBuf::new(),
3964 tuple: d.read_str().to_owned(),
3965 contents: d.read_str().to_owned(),
3966 },
3967 _ => {
3968 panic!("invalid enum variant tag while decoding `TargetTuple`, expected 0..2");
3969 }
3970 }
3971 }
3972}
3973
3974impl TargetTuple {
3975 /// Creates a target tuple from the passed target tuple string.
3976 pub fn from_tuple(tuple: &str) -> Self {
3977 TargetTuple::TargetTuple(tuple.into())
3978 }
3979
3980 /// Creates a target tuple from the passed target path.
3981 pub fn from_path(path: &Path) -> Result<Self, io::Error> {
3982 let canonicalized_path = try_canonicalize(path)?;
3983 let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| {
3984 io::Error::new(
3985 io::ErrorKind::InvalidInput,
3986 format!("target path {canonicalized_path:?} is not a valid file: {err}"),
3987 )
3988 })?;
3989 let tuple = canonicalized_path
3990 .file_stem()
3991 .expect("target path must not be empty")
3992 .to_str()
3993 .expect("target path must be valid unicode")
3994 .to_owned();
3995 Ok(TargetTuple::TargetJson { path_for_rustdoc: canonicalized_path, tuple, contents })
3996 }
3997
3998 /// Returns a string tuple for this target.
3999 ///
4000 /// If this target is a path, the file name (without extension) is returned.
4001 pub fn tuple(&self) -> &str {
4002 match *self {
4003 TargetTuple::TargetTuple(ref tuple) | TargetTuple::TargetJson { ref tuple, .. } => {
4004 tuple
4005 }
4006 }
4007 }
4008
4009 /// Returns an extended string tuple for this target.
4010 ///
4011 /// If this target is a path, a hash of the path is appended to the tuple returned
4012 /// by `tuple()`.
4013 pub fn debug_tuple(&self) -> String {
4014 use std::hash::DefaultHasher;
4015
4016 match self {
4017 TargetTuple::TargetTuple(tuple) => tuple.to_owned(),
4018 TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents: content } => {
4019 let mut hasher = DefaultHasher::new();
4020 content.hash(&mut hasher);
4021 let hash = hasher.finish();
4022 format!("{tuple}-{hash}")
4023 }
4024 }
4025 }
4026}
4027
4028impl fmt::Display for TargetTuple {
4029 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4030 write!(f, "{}", self.debug_tuple())
4031 }
4032}
4033
4034into_diag_arg_using_display!(&TargetTuple);
compiler/rustc_target/src/spec/tuple.rs created+146
......@@ -0,0 +1,146 @@
1use std::hash::{Hash, Hasher};
2use std::path::{Path, PathBuf};
3use std::{fmt, io};
4
5use rustc_error_messages::into_diag_arg_using_display;
6use rustc_fs_util::try_canonicalize;
7use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
8
9/// Either a target tuple string or a path to a JSON file.
10#[derive(Clone, Debug)]
11pub enum TargetTuple {
12 TargetTuple(String),
13 TargetJson {
14 /// Warning: This field may only be used by rustdoc. Using it anywhere else will lead to
15 /// inconsistencies as it is discarded during serialization.
16 path_for_rustdoc: PathBuf,
17 tuple: String,
18 contents: String,
19 },
20}
21
22// Use a manual implementation to ignore the path field
23impl PartialEq for TargetTuple {
24 fn eq(&self, other: &Self) -> bool {
25 match (self, other) {
26 (Self::TargetTuple(l0), Self::TargetTuple(r0)) => l0 == r0,
27 (
28 Self::TargetJson { path_for_rustdoc: _, tuple: l_tuple, contents: l_contents },
29 Self::TargetJson { path_for_rustdoc: _, tuple: r_tuple, contents: r_contents },
30 ) => l_tuple == r_tuple && l_contents == r_contents,
31 _ => false,
32 }
33 }
34}
35
36// Use a manual implementation to ignore the path field
37impl Hash for TargetTuple {
38 fn hash<H: Hasher>(&self, state: &mut H) -> () {
39 match self {
40 TargetTuple::TargetTuple(tuple) => {
41 0u8.hash(state);
42 tuple.hash(state)
43 }
44 TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents } => {
45 1u8.hash(state);
46 tuple.hash(state);
47 contents.hash(state)
48 }
49 }
50 }
51}
52
53// Use a manual implementation to prevent encoding the target json file path in the crate metadata
54impl<S: Encoder> Encodable<S> for TargetTuple {
55 fn encode(&self, s: &mut S) {
56 match self {
57 TargetTuple::TargetTuple(tuple) => {
58 s.emit_u8(0);
59 s.emit_str(tuple);
60 }
61 TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents } => {
62 s.emit_u8(1);
63 s.emit_str(tuple);
64 s.emit_str(contents);
65 }
66 }
67 }
68}
69
70impl<D: Decoder> Decodable<D> for TargetTuple {
71 fn decode(d: &mut D) -> Self {
72 match d.read_u8() {
73 0 => TargetTuple::TargetTuple(d.read_str().to_owned()),
74 1 => TargetTuple::TargetJson {
75 path_for_rustdoc: PathBuf::new(),
76 tuple: d.read_str().to_owned(),
77 contents: d.read_str().to_owned(),
78 },
79 _ => {
80 panic!("invalid enum variant tag while decoding `TargetTuple`, expected 0..2");
81 }
82 }
83 }
84}
85
86impl TargetTuple {
87 /// Creates a target tuple from the passed target tuple string.
88 pub fn from_tuple(tuple: &str) -> Self {
89 TargetTuple::TargetTuple(tuple.into())
90 }
91
92 /// Creates a target tuple from the passed target path.
93 pub fn from_path(path: &Path) -> Result<Self, io::Error> {
94 let canonicalized_path = try_canonicalize(path)?;
95 let contents = std::fs::read_to_string(&canonicalized_path).map_err(|err| {
96 io::Error::new(
97 io::ErrorKind::InvalidInput,
98 format!("target path {canonicalized_path:?} is not a valid file: {err}"),
99 )
100 })?;
101 let tuple = canonicalized_path
102 .file_stem()
103 .expect("target path must not be empty")
104 .to_str()
105 .expect("target path must be valid unicode")
106 .to_owned();
107 Ok(TargetTuple::TargetJson { path_for_rustdoc: canonicalized_path, tuple, contents })
108 }
109
110 /// Returns a string tuple for this target.
111 ///
112 /// If this target is a path, the file name (without extension) is returned.
113 pub fn tuple(&self) -> &str {
114 match *self {
115 TargetTuple::TargetTuple(ref tuple) | TargetTuple::TargetJson { ref tuple, .. } => {
116 tuple
117 }
118 }
119 }
120
121 /// Returns an extended string tuple for this target.
122 ///
123 /// If this target is a path, a hash of the path is appended to the tuple returned
124 /// by `tuple()`.
125 pub fn debug_tuple(&self) -> String {
126 use std::hash::DefaultHasher;
127
128 match self {
129 TargetTuple::TargetTuple(tuple) => tuple.to_owned(),
130 TargetTuple::TargetJson { path_for_rustdoc: _, tuple, contents: content } => {
131 let mut hasher = DefaultHasher::new();
132 content.hash(&mut hasher);
133 let hash = hasher.finish();
134 format!("{tuple}-{hash}")
135 }
136 }
137 }
138}
139
140impl fmt::Display for TargetTuple {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 write!(f, "{}", self.debug_tuple())
143 }
144}
145
146into_diag_arg_using_display!(&TargetTuple);
library/core/src/ptr/const_ptr.rs+2-1
......@@ -1497,9 +1497,10 @@ impl<T> *const [T] {
14971497 /// Returns a raw pointer to an element or subslice, without doing bounds
14981498 /// checking.
14991499 ///
1500 /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
1500 /// Calling this method with an [out-of-bounds index] or when `self` is not dereferenceable
15011501 /// is *[undefined behavior]* even if the resulting pointer is not used.
15021502 ///
1503 /// [out-of-bounds index]: #method.add
15031504 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
15041505 ///
15051506 /// # Examples
library/core/src/ptr/non_null.rs+2-1
......@@ -1573,9 +1573,10 @@ impl<T> NonNull<[T]> {
15731573 /// Returns a raw pointer to an element or subslice, without doing bounds
15741574 /// checking.
15751575 ///
1576 /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
1576 /// Calling this method with an [out-of-bounds index] or when `self` is not dereferenceable
15771577 /// is *[undefined behavior]* even if the resulting pointer is not used.
15781578 ///
1579 /// [out-of-bounds index]: #method.add
15791580 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
15801581 ///
15811582 /// # Examples
library/std/src/collections/hash/set/tests.rs+26-8
......@@ -418,14 +418,32 @@ fn test_retain() {
418418}
419419
420420#[test]
421fn test_extract_if() {
422 let mut x: HashSet<_> = [1].iter().copied().collect();
423 let mut y: HashSet<_> = [1].iter().copied().collect();
424
425 x.extract_if(|_| true).for_each(drop);
426 y.extract_if(|_| false).for_each(drop);
427 assert_eq!(x.len(), 0);
428 assert_eq!(y.len(), 1);
421fn test_extract_if_empty() {
422 let mut set: HashSet<i32> = HashSet::new();
423 let extracted: Vec<_> =
424 set.extract_if(|_| unreachable!("there's nothing to decide on")).collect();
425
426 assert!(extracted.is_empty());
427 assert!(set.is_empty());
428}
429
430#[test]
431fn test_extract_if_consuming_nothing() {
432 let mut set: HashSet<_> = (0..3).collect();
433 let extracted: Vec<_> = set.extract_if(|_| false).collect();
434
435 assert!(extracted.is_empty());
436 assert_eq!(set, HashSet::from([0, 1, 2]));
437}
438
439#[test]
440fn test_extract_if_consuming_all() {
441 let mut set: HashSet<_> = (0..3).collect();
442 let mut extracted: Vec<_> = set.extract_if(|_| true).collect();
443 extracted.sort_unstable();
444
445 assert_eq!(extracted, vec![0, 1, 2]);
446 assert!(set.is_empty());
429447}
430448
431449#[test]
library/std/src/io/mod.rs+2-2
......@@ -1295,7 +1295,7 @@ pub trait Read {
12951295 /// Ok(())
12961296 /// }
12971297 /// ```
1298 #[unstable(feature = "read_le", issue = "156983")]
1298 #[unstable(feature = "read_le", issue = "156984")]
12991299 #[inline]
13001300 fn read_le<T: FromEndianBytes>(&mut self) -> Result<T>
13011301 where
......@@ -1328,7 +1328,7 @@ pub trait Read {
13281328 /// Ok(())
13291329 /// }
13301330 /// ```
1331 #[unstable(feature = "read_le", issue = "156983")]
1331 #[unstable(feature = "read_le", issue = "156984")]
13321332 #[inline]
13331333 fn read_be<T: FromEndianBytes>(&mut self) -> Result<T>
13341334 where
library/std/src/lib.rs+2
......@@ -276,6 +276,7 @@
276276#![feature(asm_experimental_arch)]
277277#![feature(autodiff)]
278278#![feature(cfg_sanitizer_cfi)]
279#![feature(cfg_target_has_threads)]
279280#![feature(cfg_target_thread_local)]
280281#![feature(cfi_encoding)]
281282#![feature(const_trait_impl)]
......@@ -286,6 +287,7 @@
286287#![feature(doc_masked)]
287288#![feature(doc_notable_trait)]
288289#![feature(dropck_eyepatch)]
290#![feature(exact_div)]
289291#![feature(f16)]
290292#![feature(f128)]
291293#![feature(ffi_const)]
library/std/src/sync/mod.rs+1-1
......@@ -9,7 +9,7 @@
99//! Consider the following code, operating on some global static variables:
1010//!
1111//! ```rust
12//! // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
12//! // FIXME(static_mut_refs): use raw pointers instead of references
1313//! #![allow(static_mut_refs)]
1414//!
1515//! static mut A: u32 = 0;
library/std/src/sys/alloc/vexos.rs+1-1
......@@ -1,4 +1,4 @@
1// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
1// FIXME(static_mut_refs): use raw pointers instead of references
22#![allow(static_mut_refs)]
33
44use crate::alloc::{GlobalAlloc, Layout, System};
library/std/src/sys/alloc/xous.rs+1-1
......@@ -1,4 +1,4 @@
1// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
1// FIXME(static_mut_refs): use raw pointers instead of references
22#![allow(static_mut_refs)]
33
44use crate::alloc::{GlobalAlloc, Layout, System};
library/std/src/sys/paths/unix.rs+19-6
......@@ -234,18 +234,31 @@ pub fn current_exe() -> io::Result<PathBuf> {
234234 unsafe {
235235 let mut mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, libc::getpid(), libc::KERN_PROC_ARGV];
236236 let mib = mib.as_mut_ptr();
237 let mut argv_len = 0;
238 cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_len, ptr::null_mut(), 0))?;
239 let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize);
240 cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_len, ptr::null_mut(), 0))?;
241 argv.set_len(argv_len as usize);
237
238 // Determine the required size (in bytes) for the argument array ...
239 let mut argv_size = 0;
240 cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_size, ptr::null_mut(), 0))?;
241
242 // ... allocate a buffer for it ...
243 let argc = argv_size.div_exact(size_of::<*const libc::c_char>()).unwrap();
244 let mut argv = Vec::<*const libc::c_char>::with_capacity(argc);
245
246 // ... and retrieve the argument array.
247 cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _, &mut argv_size, ptr::null_mut(), 0))?;
248 let argc = argv_size.div_exact(size_of::<*const libc::c_char>()).unwrap();
249 argv.set_len(argc);
250
242251 if argv[0].is_null() {
243252 return Err(io::const_error!(io::ErrorKind::Uncategorized, "no current exe available"));
244253 }
245254 let argv0 = CStr::from_ptr(argv[0]).to_bytes();
246 if argv0[0] == b'.' || argv0.iter().any(|b| *b == b'/') {
255 if argv0.iter().any(|b| *b == b'/') {
256 // The program name is path-like, so try to canonicalize it.
247257 crate::fs::canonicalize(OsStr::from_bytes(argv0))
248258 } else {
259 // The program was probably found in the PATH. Instead of trying to
260 // find it again (which might not succeed if PATH has changed), just
261 // return the program name – this function is best-effort anyway.
249262 Ok(PathBuf::from(OsStr::from_bytes(argv0)))
250263 }
251264 }
library/std/src/sys/sync/condvar/no_threads.rs+3
......@@ -2,6 +2,9 @@ use crate::sys::sync::Mutex;
22use crate::thread::sleep;
33use crate::time::Duration;
44
5#[cfg(target_has_threads)]
6compile_error!("Using no_threads implementation on a target with threads");
7
58pub struct Condvar {}
69
710impl Condvar {
library/std/src/sys/sync/mutex/no_threads.rs+3
......@@ -1,5 +1,8 @@
11use crate::cell::Cell;
22
3#[cfg(target_has_threads)]
4compile_error!("Using no_threads implementation on a target with threads");
5
36pub struct Mutex {
47 // This platform has no threads, so we can use a Cell here.
58 locked: Cell<bool>,
library/std/src/sys/sync/once/no_threads.rs+3
......@@ -2,6 +2,9 @@ use crate::cell::Cell;
22use crate::sync as public;
33use crate::sync::once::OnceExclusiveState;
44
5#[cfg(target_has_threads)]
6compile_error!("Using no_threads implementation on a target with threads");
7
58pub struct Once {
69 state: Cell<State>,
710}
library/std/src/sys/sync/rwlock/no_threads.rs+3
......@@ -1,5 +1,8 @@
11use crate::cell::Cell;
22
3#[cfg(target_has_threads)]
4compile_error!("Using no_threads implementation on a target with threads");
5
36pub struct RwLock {
47 // This platform has no threads, so we can use a Cell here.
58 mode: Cell<isize>,
library/std/src/sys/thread_local/no_threads.rs+3
......@@ -5,6 +5,9 @@ use crate::cell::{Cell, UnsafeCell};
55use crate::mem::MaybeUninit;
66use crate::ptr;
77
8#[cfg(target_has_threads)]
9compile_error!("Using no_threads implementation on a target with threads");
10
811#[doc(hidden)]
912#[allow_internal_unstable(thread_local_internals)]
1013#[allow_internal_unsafe]
library/std/src/thread/local.rs+9-2
......@@ -620,10 +620,17 @@ impl<T: 'static> LocalKey<Cell<T>> {
620620
621621 /// Updates the contained value using a function.
622622 ///
623 /// This will lazily initialize the value if this thread has not referenced
624 /// this key yet.
625 ///
626 /// # Panics
627 ///
628 /// Panics if the key currently has its destructor running,
629 /// and it **may** panic if the destructor has previously been run for this thread.
630 ///
623631 /// # Examples
624632 ///
625633 /// ```
626 /// #![feature(local_key_cell_update)]
627634 /// use std::cell::Cell;
628635 ///
629636 /// thread_local! {
......@@ -633,7 +640,7 @@ impl<T: 'static> LocalKey<Cell<T>> {
633640 /// X.update(|x| x + 1);
634641 /// assert_eq!(X.get(), 6);
635642 /// ```
636 #[unstable(feature = "local_key_cell_update", issue = "143989")]
643 #[stable(feature = "local_key_cell_update", since = "CURRENT_RUSTC_VERSION")]
637644 pub fn update(&'static self, f: impl FnOnce(T) -> T)
638645 where
639646 T: Copy,
library/std/tests/thread_local/tests.rs+1-1
......@@ -110,7 +110,7 @@ fn smoke_dtor() {
110110
111111#[test]
112112fn circular() {
113 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
113 // FIXME(static_mut_refs): use raw pointers instead of references
114114 #![allow(static_mut_refs)]
115115
116116 struct S1(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>);
src/bootstrap/Cargo.lock+12
......@@ -71,6 +71,7 @@ dependencies = [
7171 "tracing-subscriber",
7272 "walkdir",
7373 "windows 0.61.1",
74 "windows-registry",
7475 "xz2",
7576]
7677
......@@ -1095,6 +1096,17 @@ dependencies = [
10951096 "windows-link 0.2.1",
10961097]
10971098
1099[[package]]
1100name = "windows-registry"
1101version = "0.6.1"
1102source = "registry+https://github.com/rust-lang/crates.io-index"
1103checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
1104dependencies = [
1105 "windows-link 0.2.1",
1106 "windows-result 0.4.1",
1107 "windows-strings 0.5.1",
1108]
1109
10981110[[package]]
10991111name = "windows-result"
11001112version = "0.3.2"
src/bootstrap/Cargo.toml+3
......@@ -66,6 +66,9 @@ tracing = { version = "0.1", optional = true, features = ["attributes"] }
6666tracing-chrome = { version = "0.7", optional = true }
6767tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] }
6868
69[target.'cfg(windows)'.dependencies.windows-registry]
70version = "0.6"
71
6972[target.'cfg(windows)'.dependencies.junction]
7073version = "1.3.0"
7174
src/bootstrap/src/core/build_steps/compile.rs+1-1
......@@ -1917,7 +1917,7 @@ pub fn compiler_file(
19171917 return PathBuf::new();
19181918 }
19191919 let mut cmd = command(compiler);
1920 cmd.args(builder.cc_handled_clags(target, c));
1920 cmd.args(builder.cc_handled_cflags(target, c));
19211921 cmd.args(builder.cc_unhandled_cflags(target, GitRepo::Rustc, c));
19221922 cmd.arg(format!("-print-file-name={file}"));
19231923 let out = cmd.run_capture_stdout(builder).stdout();
src/bootstrap/src/core/build_steps/llvm.rs+2-2
......@@ -800,7 +800,7 @@ fn configure_cmake(
800800 // Needs `suppressed_compiler_flag_prefixes` to be gone, and hence
801801 // https://github.com/llvm/llvm-project/issues/88780 to be fixed.
802802 for flag in builder
803 .cc_handled_clags(target, CLang::C)
803 .cc_handled_cflags(target, CLang::C)
804804 .into_iter()
805805 .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::C))
806806 .filter(|flag| !suppressed_compiler_flag_prefixes.iter().any(|p| flag.starts_with(p)))
......@@ -821,7 +821,7 @@ fn configure_cmake(
821821 cfg.define("CMAKE_C_FLAGS", cflags);
822822 let mut cxxflags = ccflags.cxxflags.clone();
823823 for flag in builder
824 .cc_handled_clags(target, CLang::Cxx)
824 .cc_handled_cflags(target, CLang::Cxx)
825825 .into_iter()
826826 .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::Cxx))
827827 .filter(|flag| {
src/bootstrap/src/core/build_steps/test.rs+2-2
......@@ -2682,9 +2682,9 @@ Please disable assertions with `rust.debug-assertions = false`.
26822682 // Only pass correct values for these flags for the `run-make` suite as it
26832683 // requires that a C++ compiler was configured which isn't always the case.
26842684 if !builder.config.dry_run() && mode == CompiletestMode::RunMake {
2685 let mut cflags = builder.cc_handled_clags(target, CLang::C);
2685 let mut cflags = builder.cc_handled_cflags(target, CLang::C);
26862686 cflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C));
2687 let mut cxxflags = builder.cc_handled_clags(target, CLang::Cxx);
2687 let mut cxxflags = builder.cc_handled_cflags(target, CLang::Cxx);
26882688 cxxflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx));
26892689 cmd.arg("--cc")
26902690 .arg(builder.cc(target))
src/bootstrap/src/core/builder/cargo.rs+34-10
......@@ -78,6 +78,26 @@ impl Rustflags {
7878 }
7979}
8080
81/// Picks the environment variable and value to pass a set of [`Rustflags`] to cargo.
82///
83/// `flags` is the `\x1f`-separated string built by [`Rustflags`]. We prefer the plain,
84/// space-separated form (`RUSTFLAGS`/`RUSTDOCFLAGS`) so the command stays readable and
85/// copy-pasteable in bootstrap's debug output, and only fall back to the `CARGO_ENCODED_*` form
86/// (which keeps the `\x1f` separators) when a flag value contains a space that the plain,
87/// whitespace-split form can't represent. See <https://github.com/rust-lang/rust/issues/158749>.
88pub(super) fn flags_env(
89 plain: &'static str,
90 encoded: &'static str,
91 flags: &str,
92) -> (&'static str, String) {
93 // A space can only appear inside a flag value, since the separators are `\x1f`.
94 if flags.contains(' ') {
95 (encoded, flags.to_string())
96 } else {
97 (plain, flags.replace('\x1f', " "))
98 }
99}
100
81101/// Flags that are passed to the `rustc` shim binary. These flags will only be applied when
82102/// compiling host code, i.e. when `--target` is unset.
83103#[derive(Debug, Default)]
......@@ -480,21 +500,25 @@ impl From<Cargo> for BootstrapCommand {
480500
481501 cargo.command.args(cargo.args);
482502
483 // Always unset the plain RUSTFLAGS/RUSTDOCFLAGS so that downstream
484 // tools (e.g. build.rs scripts) see only the encoded form. Any flags
485 // from the caller's environment have already been folded into the
486 // Rustflags struct via `propagate_cargo_env`.
503 // Unset any inherited flag variables (plain and encoded) so cargo uses only the flags
504 // bootstrap sets below. Flags from the caller's environment have already been folded into
505 // the Rustflags struct via `propagate_cargo_env`. This also matters because we may set the
506 // plain form below, which cargo ignores when `CARGO_ENCODED_RUSTFLAGS` is also present.
487507 cargo.command.env_remove("RUSTFLAGS");
508 cargo.command.env_remove("CARGO_ENCODED_RUSTFLAGS");
488509 cargo.command.env_remove("RUSTDOCFLAGS");
510 cargo.command.env_remove("CARGO_ENCODED_RUSTDOCFLAGS");
489511
490 let rustflags = &cargo.rustflags.0;
491 if !rustflags.is_empty() {
492 cargo.command.env("CARGO_ENCODED_RUSTFLAGS", rustflags);
512 if !cargo.rustflags.0.is_empty() {
513 let (var, value) =
514 flags_env("RUSTFLAGS", "CARGO_ENCODED_RUSTFLAGS", &cargo.rustflags.0);
515 cargo.command.env(var, value);
493516 }
494517
495 let rustdocflags = &cargo.rustdocflags.0;
496 if !rustdocflags.is_empty() {
497 cargo.command.env("CARGO_ENCODED_RUSTDOCFLAGS", rustdocflags);
518 if !cargo.rustdocflags.0.is_empty() {
519 let (var, value) =
520 flags_env("RUSTDOCFLAGS", "CARGO_ENCODED_RUSTDOCFLAGS", &cargo.rustdocflags.0);
521 cargo.command.env(var, value);
498522 }
499523
500524 let encoded_hostflags = cargo.hostflags.encode();
src/bootstrap/src/core/builder/tests.rs+23
......@@ -3349,3 +3349,26 @@ fn render_compiler(compiler: Compiler, config: &RenderConfig) -> String {
33493349fn host_target() -> String {
33503350 get_host_target().to_string()
33513351}
3352
3353#[test]
3354fn flags_env_prefers_plain_form_without_spaces() {
3355 use super::cargo::flags_env;
3356
3357 // No flag value contains a space, so use the readable, copy-pasteable plain form
3358 // rather than the `\x1f`-separated encoded form (rust-lang/rust#158749).
3359 assert_eq!(
3360 flags_env("RUSTFLAGS", "CARGO_ENCODED_RUSTFLAGS", "--cfg=foo\u{1f}-Cdebuginfo=0"),
3361 ("RUSTFLAGS", "--cfg=foo -Cdebuginfo=0".to_string()),
3362 );
3363
3364 // A flag value contains a space (e.g. an `-L` path), which the whitespace-split plain
3365 // form can't represent, so keep the encoded form.
3366 assert_eq!(
3367 flags_env(
3368 "RUSTFLAGS",
3369 "CARGO_ENCODED_RUSTFLAGS",
3370 "-Clink-arg=-L/opt/my libs\u{1f}--cfg=foo"
3371 ),
3372 ("CARGO_ENCODED_RUSTFLAGS", "-Clink-arg=-L/opt/my libs\u{1f}--cfg=foo".to_string()),
3373 );
3374}
src/bootstrap/src/core/debuggers/cdb.rs+23-12
......@@ -7,15 +7,12 @@ pub(crate) struct Cdb {
77 pub(crate) cdb: PathBuf,
88}
99
10/// FIXME: This CDB discovery code was very questionable when it was in
11/// compiletest, and it's just as questionable now that it's in bootstrap.
10/// We consult the registry to find the installed cdb.exe and try "Program Files" if that fails.
1211pub(crate) fn discover_cdb(target: TargetSelection) -> Option<Cdb> {
1312 if !cfg!(windows) || !target.ends_with("-pc-windows-msvc") {
1413 return None;
1514 }
1615
17 let pf86 =
18 PathBuf::from(env::var_os("ProgramFiles(x86)").or_else(|| env::var_os("ProgramFiles"))?);
1916 let cdb_arch = if cfg!(target_arch = "x86") {
2017 "x86"
2118 } else if cfg!(target_arch = "x86_64") {
......@@ -28,14 +25,28 @@ pub(crate) fn discover_cdb(target: TargetSelection) -> Option<Cdb> {
2825 return None; // No compatible CDB.exe in the Windows 10 SDK
2926 };
3027
31 let mut path = pf86;
32 path.push(r"Windows Kits\10\Debuggers"); // We could check 8.1 etc. too?
33 path.push(cdb_arch);
34 path.push(r"cdb.exe");
28 let path = discover_cdb_registry(cdb_arch).or_else(|| discover_cdb_program_files(cdb_arch))?;
29 Some(Cdb { cdb: path })
30}
3531
36 if !path.exists() {
37 return None;
38 }
32#[cfg(windows)]
33fn discover_cdb_registry(cdb_arch: &'static str) -> Option<PathBuf> {
34 use windows_registry::LOCAL_MACHINE;
35 let roots = LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots").ok()?;
36 // "KitsRoot10" is used by both the Windows 10 and 11 SDKs.
37 let mut path: PathBuf = roots.get_string("KitsRoot10").ok()?.into();
38 path.extend([r"Debuggers", cdb_arch, r"cdb.exe"]);
39 path.exists().then_some(path)
40}
3941
40 Some(Cdb { cdb: path })
42#[cfg(not(windows))]
43fn discover_cdb_registry(_cdb_arch: &'static str) -> Option<PathBuf> {
44 None
45}
46
47fn discover_cdb_program_files(cdb_arch: &'static str) -> Option<PathBuf> {
48 let mut path =
49 PathBuf::from(env::var_os("ProgramFiles(x86)").or_else(|| env::var_os("ProgramFiles"))?);
50 path.extend([r"Windows Kits\10\Debuggers", cdb_arch, r"cdb.exe"]);
51 path.exists().then_some(path)
4152}
src/bootstrap/src/lib.rs+1-1
......@@ -1280,7 +1280,7 @@ impl Build {
12801280
12811281 /// Returns C flags that `cc-rs` thinks should be enabled for the
12821282 /// specified target by default.
1283 fn cc_handled_clags(&self, target: TargetSelection, c: CLang) -> Vec<String> {
1283 fn cc_handled_cflags(&self, target: TargetSelection, c: CLang) -> Vec<String> {
12841284 if self.config.dry_run() {
12851285 return Vec::new();
12861286 }
src/bootstrap/src/utils/cc_detect.rs+2-2
......@@ -119,7 +119,7 @@ pub fn fill_target_compiler(build: &mut Build, target: TargetSelection) {
119119 .or_else(|| cfg.try_get_archiver().map(|c| PathBuf::from(c.get_program())).ok());
120120
121121 build.cc.insert(target, compiler.clone());
122 let mut cflags = build.cc_handled_clags(target, CLang::C);
122 let mut cflags = build.cc_handled_cflags(target, CLang::C);
123123 cflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C));
124124
125125 // If we use llvm-libunwind, we will need a C++ compiler as well for all targets
......@@ -146,7 +146,7 @@ pub fn fill_target_compiler(build: &mut Build, target: TargetSelection) {
146146 build.do_if_verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target)));
147147 build.do_if_verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple));
148148 if let Ok(cxx) = build.cxx(target) {
149 let mut cxxflags = build.cc_handled_clags(target, CLang::Cxx);
149 let mut cxxflags = build.cc_handled_cflags(target, CLang::Cxx);
150150 cxxflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx));
151151 build.do_if_verbose(|| println!("CXX_{} = {cxx:?}", target.triple));
152152 build.do_if_verbose(|| println!("CXXFLAGS_{} = {cxxflags:?}", target.triple));
src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile+2-1
......@@ -26,4 +26,5 @@ ENV RUST_CONFIGURE_ARGS="--build=aarch64-unknown-linux-gnu \
2626 --enable-profiler \
2727 --enable-compiler-docs"
2828ENV SCRIPT="python3 ../x.py --stage 2 test && \
29 python3 ../x.py --stage 2 test src/tools/cargo"
29 python3 ../x.py --stage 2 test src/tools/cargo && \
30 python3 ../x.py --stage 2 test library/stdarch/crates/intrinsic-test"
src/doc/rustc-dev-guide/rust-version+1-1
......@@ -1 +1 @@
18c75e93c5c7671c29f3e8c096b7acf56822ed23a
17fb284d9037fa54f6a9b24261c82b394472cbfd7
src/doc/rustc-dev-guide/src/SUMMARY.md+1
......@@ -193,6 +193,7 @@
193193 - [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md)
194194 - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md)
195195 - [Having separate `Trait` and `Projection` bounds](./traits/separate-projection-bounds.md)
196- [Well-formedness](./analysis/well-formed.md)
196197- [Variance](./variance.md)
197198- [Coherence checking](./coherence.md)
198199- [HIR Type checking](./hir-typeck/summary.md)
src/doc/rustc-dev-guide/src/analysis/well-formed.md created+326
......@@ -0,0 +1,326 @@
1# Well-formedness
2
3## What is well-formedness?
4
5"Well-formed" means "correctly built"[^wf-history].
6Something is _well-formed_ when its structure follows rules.
7When we use this term in the Rust compiler we are concerned with establishing some kind of _internal consistency_.
8
9## Well-formedness in Rust
10
11To check that something is well-formed is to perform a "Well-formedness check".
12
13In the Rust compiler there are two different forms of well-formedness checking:
14
15- **Type-Level Term**[^terms][^terms-abbreviated] well-formedness check.
16 - Also called "Term well-formedness" or "Term well-formedness checking".
17 - Not a distinct analysis stage, this gets performed throughout analysis.
18- **Item**[^items] well-formedness check (item-wfck.)
19 - "Item-wfck" will often wind up requiring Terms be well-formed, but skips some areas.
20 - Inner "Terms" can (incorrectly) get normalized first.
21 - More coherent as a stage in the compiler than "term well-formedness" (which is performed in many places.)
22
23See: [What Well-Formedness Isn't](#what-well-formedness-isnt).
24
25## Well-formedness of type-level terms
26
27Term well-formedness checking begins with building a list of things that need to be true for a term to be well-formed.
28We call these "Obligations"[^obligations].
29
30Type-Level Terms are considered well-formed when their associated obligations are satisfied by the trait solver.
31
32### Obligations for well-formedness
33
34Specific obligations are things like `String: Clone`, `A: usize`, or `<T as Iterator>::Item: Debug`.
35
36On this page we show the split between obligations and terms/items as:
37
38```rust,ignore
39<terms or items>
40---
41<obligations>
42```
43
44Here is an example of a well-formed type-level term:
45
46```rust,ignore
47Vec<String>
48---
49// Obligations to fulfill
50Vec<T> where T: Sized
51// Trait solver says `String: Sized` is true, so this is well-formed.
52Vec<String> where String: Sized
53```
54
55When we compute the obligations for `Vec<String>`, we'll find that `Vec<T>` generates the obligation `T: Sized`.
56We substitute `T` with `String` in `Vec<String>`, so we find the obligation `String: Sized` which the trait solver will determine to be satisfied.
57
58The following **is not** well-formed:
59
60```rust,ignore
61Vec<str>
62---
63// Obligations to fulfill
64Vec<T> where T: Sized
65// Trait solver says `str: Sized` is not true, so this is not well-formed.
66Vec<str> where str: Sized
67```
68
69The above computes the obligation `T: Sized`, like before, but we substitute `T` for `str` in the instance of `Vec<str>` finding the obligation `str: sized`.
70This obligation will be determined by the trait solver to be _unsatisfied_.
71
72#### Determining obligations
73
74In the compiler, obligations of terms are found through the [`obligations`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/wf/fn.obligations.html) function in the [term well-formedness module](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/wf/index.html).
75
76#### Other obligations
77
78Obligations are more than just trait and const generic bounds, but we've only mentioned these specific obligations so far as they are what we care about when we do "well-formedness checking" of terms.
79See: [`PredicateKind`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_type_ir/predicate_kind/enum.PredicateKind.html) and [`ClauseKind`](https://doc.rust-lang.org/beta/nightly-rustc/rustc_type_ir/predicate_kind/enum.ClauseKind.html) for a full list of obligations.
80
81### We don't need normalization (yet)
82
83[Normalization](../normalization.md) is the process of resolving [type aliases](../normalization.md#aliases) into their underlying type.
84
85A type alias is considered well-formed if its where clauses are satisfied.
86The underlying type undergoes well-formedness checking at most definition and instantiation sites, but there are exceptions.
87
88### Const generic arguments
89
90Term well-formedness is responsible for getting "type checking" obligations of const generic terms[^tyck-const-generics].
91Let's look at the following use of const generics:
92
93```rust,ignore
94fn use_const_generics<const U: usize>() { /* ... */ }
95// call site
96use_const_generics::<6>();
97---
98// call site wfck obligations
99const 6: usize
100```
101
102The call site will provide us with the obligation `6: usize` during well-formedness checking.
103This obligation will be passed off to the trait solver just like any trait-style obligation, as the trait solver has more responsibilities than its name suggests.
104
105## Well-formedness of items
106
107Items are, generally speaking, "Things that get defined".
108Item-wfck happens at the signature level for types and functions, methods, and definitions/implementations of traits.
109
110```rust,ignore
111// The `Vec<str>` is checked during item wfck
112fn foo(_: Vec<str>) {
113 // The `Vec<[u8]>` is not handled by item wfck as it's not in the signature
114 let _: Vec<[u8]>
115}
116---
117Vec<str>: Sized // Generated
118Vec<[u8]>: Sized // Not done at item-wfck. Done elsewhere.
119```
120
121Item-wfck has more responsibilities than only collecting the obligations of its internal type-level terms and passing them to the trait solver.
122We do not talk about all of these here, but they can be found at the individual `check_*` functions in [**the item-wfck module**](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/wfcheck/index.html).
123
124<!-- FIXME: Expand more on item well-formedness that isn't const generic / trait bound obligation based. These are not special cases, but important points! -->
125
126### Global and trivial bounds
127
128<!-- TODO later: Cut this into its own page -->
129
130Trait bounds are a common Obligation.
131Global and Trivial trait bounds are kinds of trait bounds where we already have enough information to determine if they are true or false.
132Item-wfck is responsible for finding and checking these bounds.
133
134- **Global bounds** are, in the old solver, post-normalization bounds that don't contain any generic parameters (like `<T>` or `'a`) or bound variables (like `for<'b>`).
135- **Trivial bounds** are bounds that do not need further normalization to determine if they're well-formed or not. <!-- TODO: check with lcnr if this is genuinely what a trivial bound is. -->
136
137Consider the following function definition:
138
139```rust,ignore
140fn apartment_complex<T>(block: T, name: String) where String: Clone { /* ... */ }
141---
142String: Clone // Trivial & Global bound! There's no aliases to resolve.
143// There could be bligations on T but we don't care about them here.
144```
145
146This produces a trait bound obligation `String: Clone` that is _Global_ (no generic parameters) and _Trivial_ (didn't require normalization to be well-formedness checked).
147The trait solver doesn't need to be given any additional information for it to be able to make a judgment on the well-formedness of `String: Clone`.
148
149False trivial bounds are simply trivial bounds that do not hold.
150The following is a basic example:
151
152```rust,ignore
153fn apartment_simple<T>(block: T, name: String) where String: Copy { /* ... */ }
154---
155String: Copy // Trivial bound again, but this one is false!
156```
157
158Here we have a trivial bound that does not hold, because `String` is not `Copy`.
159
160#### Trivial bounds are not always global
161
162Trivial Bounds are not a subset of Global Bounds.
163A trivial bound that isn't Global is `for<'a> String: Clone` (trivially true, has a bound variable) or `&'a str: Copy` (trivially false, has a generic parameter).
164
165#### Item-wfck and trivial/global bounds
166
167<!-- When cutting out the subsection on global/trivial bounds, keep this part on the well-formedness page. -->
168
169When checking items are well-formed we will check that there are no trivially false global bounds.
170
171## When we don't fully do well-formedness checking
172
173Well-formedness checking is not a coherent "stage" of type checking.
174There are many areas where well-formedness checking is performed, and some areas where we skip over well-formedness checking due to limitations in what kinds of analysis we can currently perform.
175Ideally, we would never skip or defer well-formedness checking.
176
177### We (sometimes) need normalization
178
179There are places where normalization of an Item happens before its Terms have gone through well-formedness checking.
180This is considered problematic as doing so allows some terms to [bypass term well-formedness checking entirely](https://github.com/rust-lang/rust/issues/100041).
181
182### Trait objects
183
184We do not require the where clauses of trait objects to be well-formed when determining if that trait object is well-formed.
185These where clauses are proven when coercing into a trait object, but this remains a hole in well-formedness checking.
186
187As an example, the following will compile because we don't have a point where we're constructing the trait object from a concrete type:
188
189```rust,ignore
190trait Trait
191where
192 for<'a> [u8]: Sized {}
193
194fn foo(_: &dyn Trait) {}
195---
196// This doesn't end up being generated, because it happens within a trait object.
197[u8]: Sized
198```
199
200The above should not compile because `[u8]: Sized`, but this won't be checked until actual use:
201
202```rust
203trait Trait
204where
205 for<'a> [u8]: Sized {}
206
207fn foo(_: &dyn Trait) {}
208
209// We still need to specify the bound here, otherwise `[u8]: Sized` _is_
210// checked as an obligation.
211impl Trait for u8 where for<'a> [u8]: Sized {}
212
213fn main() {
214 // No matter what we do, this boundary between concrete type and trait
215 // object will produce the obligation `[u8]: Sized`, which will fail when
216 // handed over to the trait solver.
217 let object: Box<dyn Trait> = Box::new(42u8);
218 foo(&object);
219}
220```
221
222This exception does not apply to Const Generic Arguments in trait objects:
223
224```rust,ignore
225trait Trait<const N: usize> {}
226fn foo<const B: bool>(_: &dyn Trait<B>) {}
227---
228const N: usize
229const B: bool
230N = B // Substitution
231const B: usize + bool
232```
233
234The above doesn't compile, unlike the previous example we gave.
235We're doing _some_ well-formedness checking here when it comes to the const generic arguments.
236
237### Binders / higher-ranked types
238
239Binders / Higher-Ranked Types reduce the amount well-formedness checking we do on a term, leaving well-formedness checking to when the bound is instantiated:
240
241```rust,ignore
242let _: for<'a> fn(Vec<[&'a ()]>);
243---
244// This doesn't end up being generated, because it happens within a HRB
245[&'a ()]: Sized // slices aren't sized, this would fail!
246```
247
248Specifically, obligations involving variables from binders (`for<'a>`) are only checked when the binder is instantiated.
249Some things are stilled checked under the `for<'a>`, but we still skip a lot of things.
250
251A lot of unsoundness surrounds this behavior.
252See: [#25860](https://github.com/rust-lang/rust/issues/25860), [#84591](https://github.com/rust-lang/rust/issues/84591).
253
254Let's consider the following:
255
256```rust,ignore
257for<'a, 'b> fn(&'a &'b ())
258```
259
260The above HRB implies `'b: 'a` (a lifetime bound), rather than two completely separate lifetimes.
261This is normal lifetime behavior, but during well-formedness checking we cannot prove that this bound is generally true[^horrible], so we skip it.
262
263### Free type aliases
264
265The right-hand side of Free Type Aliases[^fta] is not fully checked to be well-formed at the definition site, only the types of const generic arguments in the RHS are checked.
266
267The following free type alias passes type checking, at time of writing:
268
269```rust,ignore
270type WorksButShouldNot = Vec<str>;
271---
272// This should fail! But we skip the RHS of free type aliases
273str: Sized // Not generated
274```
275
276This shouldn't work, as both `T: Sized`, `str: Sized` are implied by `Vec<T>`.
277This "passes" item-wfck because the RHS of a free type alias doesn't go through well-formedness checking _until it's used_.
278Item-wfck is **deferred until use** for this specific case.
279
280For Const Generics we still do a small amount of well-formedness checking at the definition site of a free type alias.
281This is consistent with our current special-casing of const generic well-formedness checking when we skip over things like where bounds.
282
283This means that the following, despite being of a similar form to the above example, fails as it should:
284
285```rust,ignore
286pub struct Consty<const A: bool>;
287type Alias = Consty<42>;
288---
289// This *is* generated as an obligation, so this (correctly) fails.
29042: bool // This is generated!
291```
292
293<!-- TODO: Link to something explaining the underlying "why" of the difference between const and trait well-formedness checking in FTAs, or eliminate that difference. Whatever comes first. -->
294
295## "well-formed" or "wellformed"?
296
297Prefer "well-formed" over "wellformed", as this is consistent with logic literature.
298This also gets abbreviated to WF in other parts of the dev guide / docs.
299
300## Informal usage
301
302In conversation, contributors may refer to something as "well-formed" and not necessarily mean what we cover here because "well-formedness" is a general phrase associated with the correctness of formal structures.
303This isn't necessarily in error, but it should be looked out for.
304
305## What well-formedness isn't
306
307Well-formedness checking is not "number of parameters" or "parameter type" checking[^kind-checking].
308Neither term well-formedness checking nor item-wfck is concerned with if a type with 2 parameters has 1 or 3 types applied to it (assuming no defaults), or if a const generic parameter has a type applied to it.
309These kinds of problems will get handled during HIR-ty Lowering[^hir-ty-lower], not wfck.
310
311Well-formedness doesn't check or validate lifetimes, this is handled in [MIR](../borrow-check.md).
312
313Well-formedness in the Rust compiler doesn't correspond to "correct syntax" as it does in logic.
314The term has a history of general use in a mathematical context of "follows a given set of rules".
315In Rust, our original usage was closer to "this thing is internally consistent" with respect to the bounds on a type in places such as the original [clarification on projections and well-formedness RFC](https://github.com/rust-lang/rfcs/blob/master/text/1214-projections-lifetimes-and-wf.md).
316
317[^obligations]: These get referred to as Obligations, Requirements, or Constraints in the documentation. Preferred term is "obligations", as this matches the suffix of the type and the names of relevant functions. In future, this may be superseded by the new solver's term "Goal".
318[^wf-history]: In linguistics this is "grammatically correct", in logic it is "syntactically correct", and in casual mathematician use it can be read as a more general "follows the rules we set for this domain".
319[^horrible]: Instead, this bound is checked during "MIR borrowck" when the lifetimes are instantiated.
320[^fta]: Type aliases not associated with anything, i.e. a module-level `type Alias = Vec<u8>;`.
321[^items]: "Definition" style things in rust, See the [glossary](../appendix/glossary.md).
322[^terms]: AKA Type expressions and subexpressions in the general sense, not a specific struct or enum in the rust compiler. See the [glossary](../appendix/glossary.md).
323[^terms-abbreviated]: Abbreviated as "Terms" on this page in some areas.
324[^kind-checking]: AKA "kind checking", as we might see in languages like Haskell.
325[^hir-ty-lower]: <https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/hir_ty_lowering/index.html>
326[^tyck-const-generics]: #checking-types-of-const-arguments
src/doc/rustc-dev-guide/src/appendix/glossary.md+1
......@@ -102,6 +102,7 @@ Term | Meaning
102102<span id="trans">trans 👎</span> | Short for _translation_, the code to translate MIR into LLVM IR. **Renamed to** [codegen](#codegen).
103103<span id="ty">`Ty`</span> | The internal representation of a type. ([see more](../ty.md))
104104<span id="tyctxt">`TyCtxt`</span> | The data structure often referred to as [`tcx`](#tcx) in code which provides access to session data and the query system.
105<span id="type-level-term">Type-Level Term</span> | An expression at the type level, such as a Type or Const Generic.
105106<span id="ufcs">UFCS 👎</span> | Short for _universal function call syntax_, this is an unambiguous syntax for calling a method. **Term no longer in use!** Prefer _fully-qualified path / syntax_. ([see more](../hir-typeck/summary.md), [see the reference](https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls))
106107<span id="ut">uninhabited type</span> | A type which has _no_ values. This is not the same as a ZST, which has exactly 1 value. An example of an uninhabited type is `enum Foo {}`, which has no variants, and so, can never be created. The compiler can treat code that deals with uninhabited types as dead code, since there is no such value to be manipulated. `!` (the never type) is an uninhabited type. Uninhabited types are also called _empty types_.
107108<span id="upvar">upvar</span> | A variable captured by a closure from outside the closure.
src/doc/rustc-dev-guide/src/autodiff/installation.md+25-23
......@@ -18,30 +18,30 @@ Please run:
1818rustup +nightly component add enzyme
1919```
2020
21## Installation guide for Nix user.
21## Installation guide for Nix
22
23On [Nix], you can declare a nightly Rust toolchain with the Enzyme component using the [oxalica rust-overlay].
24
25For example:
26
27```nix
28rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override {
29 extensions = [ "enzyme" ];
30})
31```
32
33Alternatively, you can create a [toolchain file] that declares the Enzyme component such as
34
35```toml
36[toolchain]
37channel = "nightly-2026-06-23"
38components = [ "enzyme" ]
39```
40
41and consume it in the overlay
2242
23This setup was recommended by a nix and autodiff user.
24It uses [`Overlay`].
25Please verify for yourself if you are comfortable using that repository.
26In that case you might use the following nix configuration to get a rustc that supports `std::autodiff`.
2743```nix
28{
29 enzymeLib = pkgs.fetchzip {
30 url = "https://ci-artifacts.rust-lang.org/rustc-builds/ec818fda361ca216eb186f5cf45131bd9c776bb4/enzyme-nightly-x86_64-unknown-linux-gnu.tar.xz";
31 sha256 = "sha256-Rnrop44vzS+qmYNaRoMNNMFyAc3YsMnwdNGYMXpZ5VY=";
32 };
33
34 rustToolchain = pkgs.symlinkJoin {
35 name = "rust-with-enzyme";
36 paths = [pkgs.rust-bin.nightly.latest.default];
37 nativeBuildInputs = [pkgs.makeWrapper];
38 postBuild = ''
39 libdir=$out/lib/rustlib/x86_64-unknown-linux-gnu/lib
40 cp ${enzymeLib}/enzyme-preview/lib/rustlib/x86_64-unknown-linux-gnu/lib/libEnzyme-22.so $libdir/
41 wrapProgram $out/bin/rustc --add-flags "--sysroot $out"
42 '';
43 };
44}
44rust-bin.fromRustupToolchainFile ./rust-toolchain.toml
4545```
4646
4747## Build instructions
......@@ -135,4 +135,6 @@ This will build Enzyme, and you can find it in `Enzyme/enzyme/build/lib/<LLD/Cla
135135(Endings might differ based on your OS).
136136
137137[`Repo`]: https://github.com/rust-lang/rust/
138[`Overlay`]: https://github.com/oxalica/rust-overlay
138[Nix]: https://nixos.org/
139[oxalica rust-overlay]: https://github.com/oxalica/rust-overlay
140[toolchain file]: https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file
src/doc/rustc-dev-guide/src/building/bootstrapping/bootstrap-in-dependencies.md+6-3
......@@ -1,6 +1,8 @@
11# `cfg(bootstrap)` in compiler dependencies
22
3The rust compiler uses some external crates that can run into cyclic dependencies with the compiler itself: the compiler needs an updated crate to build, but the crate needs an updated compiler. This page describes how `#[cfg(bootstrap)]` can be used to break this cycle.
3The Rust compiler uses some external crates that can run into cyclic dependencies with the compiler itself:
4the compiler needs an updated crate to build, but the crate needs an updated compiler.
5This page describes how `#[cfg(bootstrap)]` can be used to break this cycle.
46
57## Enabling `#[cfg(bootstrap)]`
68
......@@ -38,7 +40,7 @@ As a concrete example we'll use a change where the `#[naked]` attribute was made
3840
3941### Step 1: accept the new behavior in the compiler ([#139797](https://github.com/rust-lang/rust/pull/139797))
4042
41In this example it is possible to accept both the old and new behavior at the same time by disabling an error.
43In this example, it is possible to accept both the old and new behavior at the same time by disabling an error.
4244
4345### Step 2: update the crate ([#821](https://github.com/rust-lang/compiler-builtins/pull/821))
4446
......@@ -50,4 +52,5 @@ For `compiler-builtins` this meant a version bump, in other cases it may be a gi
5052
5153### Step 4: remove the old behavior from the compiler ([#139753](https://github.com/rust-lang/rust/pull/139753))
5254
53The updated crate can now be used. In this example that meant that the old behavior could be removed.
55The updated crate can now be used.
56In this example that meant that the old behavior could be removed.
src/doc/rustc-dev-guide/src/building/bootstrapping/debugging-bootstrap.md+23-12
......@@ -1,12 +1,15 @@
11# Debugging bootstrap
22
3There are two main ways of debugging (and profiling bootstrap). The first is through println logging, and the second is through the `tracing` feature.
3There are two main ways of debugging (and profiling bootstrap).
4The first is through println logging, and the second is through the `tracing` feature.
45
56## `println` logging
67
7Bootstrap has extensive unstructured logging. Most of it is gated behind the `--verbose` flag (pass `-vv` for even more detail).
8Bootstrap has extensive unstructured logging.
9Most of it is gated behind the `--verbose` flag (pass `-vv` for even more detail).
810
9If you want to see verbose output of executed Cargo commands and other kinds of detailed logs, pass `-v` or `-vv` when invoking bootstrap. Note that the logs are unstructured and may be overwhelming.
11If you want to see verbose output of executed Cargo commands and other kinds of detailed logs, pass `-v` or `-vv` when invoking bootstrap.
12Note that the logs are unstructured and may be overwhelming.
1013
1114```
1215$ ./x dist rustc --dry-run -vv
......@@ -27,7 +30,8 @@ Bootstrap has a conditional `tracing` feature, which provides the following feat
2730- It generates a command execution summary, which shows which commands were executed, how many of their executions were cached, and what commands were the slowest to run.
2831 - The generated `command-stats.txt` file is in a simple human-readable format.
2932
30The structured logs will be written to standard error output (`stderr`), while the other outputs will be stored in files in the `<build-dir>/bootstrap-trace/<pid>` directory. For convenience, bootstrap will also create a symlink to the latest generated trace output directory at `<build-dir>/bootstrap-trace/latest`.
33The structured logs will be written to standard error output (`stderr`), while the other outputs will be stored in files in the `<build-dir>/bootstrap-trace/<pid>` directory.
34For convenience, bootstrap will also create a symlink to the latest generated trace output directory at `<build-dir>/bootstrap-trace/latest`.
3135
3236> Note that if you execute bootstrap with `--dry-run`, the tracing output directory might change. Bootstrap will always print a path where the tracing output files were stored at the end of its execution.
3337
......@@ -73,18 +77,24 @@ Build completed successfully in 0:00:00
7377
7478#### Controlling tracing output
7579
76The environment variable `BOOTSTRAP_TRACING` accepts a [`tracing_subscriber` filter][tracing-env-filter]. If you set `BOOTSTRAP_TRACING=trace`, you will enable all logs, but that can be overwhelming. You can thus use the filter to reduce the amount of data logged.
80The environment variable `BOOTSTRAP_TRACING` accepts a [`tracing_subscriber` filter][tracing-env-filter].
81If you set `BOOTSTRAP_TRACING=trace`, you will enable all logs, but that can be overwhelming.
82You can thus use the filter to reduce the amount of data logged.
7783
7884There are two orthogonal ways to control which kind of tracing logs you want:
7985
80861. You can specify the log **level**, e.g. `debug` or `trace`.
8187 - If you select a level, all events/spans with an equal or higher priority level will be shown.
82882. You can also control the log **target**, e.g. `bootstrap` or `bootstrap::core::config` or a custom target like `CONFIG_HANDLING` or `STEP`.
83 - Custom targets are used to limit what kinds of spans you are interested in, as the `BOOTSTRAP_TRACING=trace` output can be quite verbose. Currently, you can use the following custom targets:
89 - Custom targets are used to limit what kinds of spans you are interested in, as the `BOOTSTRAP_TRACING=trace` output can be quite verbose.
90 Currently, you can use the following custom targets:
8491 - `CONFIG_HANDLING`: show spans related to config handling.
85 - `STEP`: show all executed steps. Executed commands have `info` event level.
86 - `COMMAND`: show all executed commands. Executed commands have `trace` event level.
87 - `IO`: show performed I/O operations. Executed commands have `trace` event level.
92 - `STEP`: show all executed steps.
93 Executed commands have `info` event level.
94 - `COMMAND`: show all executed commands.
95 Executed commands have `trace` event level.
96 - `IO`: show performed I/O operations.
97 Executed commands have `trace` event level.
8898 - Note that many I/O are currently not being traced.
8999
90100You can of course combine them (custom target logs are typically gated behind `TRACE` log level additionally):
......@@ -100,14 +110,15 @@ Note that the level that you specify using `BOOTSTRAP_TRACING` also has an effec
100110##### FIXME(#96176): specific tracing for `compiler()` vs `compiler_for()`
101111
102112The additional targets `COMPILER` and `COMPILER_FOR` are used to help trace what
103`builder.compiler()` and `builder.compiler_for()` does. They should be removed
104if [#96176][cleanup-compiler-for] is resolved.
113`builder.compiler()` and `builder.compiler_for()` does.
114They should be removed if [#96176][cleanup-compiler-for] is resolved.
105115
106116[cleanup-compiler-for]: https://github.com/rust-lang/rust/issues/96176
107117
108118### Using `tracing` in bootstrap
109119
110Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples:
120Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature.
121Examples:
111122
112123```rs
113124#[cfg(feature = "tracing")]
src/doc/rustc-dev-guide/src/building/bootstrapping/how-bootstrap-does-it.md+8-6
......@@ -1,14 +1,16 @@
11# How Bootstrap does it
22
33The core concept in Bootstrap is a build [`Step`], which are chained together
4by [`Builder::ensure`]. [`Builder::ensure`] takes a [`Step`] as input, and runs
5the [`Step`] if and only if it has not already been run. Let's take a closer
6look at [`Step`].
4by [`Builder::ensure`].
5[`Builder::ensure`] takes a [`Step`] as input, and runs
6the [`Step`] if and only if it has not already been run.
7Let's take a closer look at [`Step`].
78
89## Synopsis of [`Step`]
910
1011A [`Step`] represents a granular collection of actions involved in the process
11of producing some artifact. It can be thought of like a rule in Makefiles.
12of producing some artifact.
13It can be thought of like a rule in Makefiles.
1214The [`Step`] trait is defined as:
1315
1416```rs,no_run
......@@ -30,8 +32,8 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
3032- `run` is the function that is responsible for doing the work.
3133 [`Builder::ensure`] invokes `run`.
3234- `should_run` is the command-line interface, which determines if an invocation
33 such as `x build foo` should run a given [`Step`]. In a "default" context
34 where no paths are provided, then `make_run` is called directly.
35 such as `x build foo` should run a given [`Step`].
36 In a "default" context where no paths are provided, then `make_run` is called directly.
3537- `make_run` is invoked only for things directly asked via the CLI and not
3638 for steps which are dependencies of other steps.
3739
src/doc/rustc-dev-guide/src/building/bootstrapping/intro.md+9-11
......@@ -1,14 +1,13 @@
11# Bootstrapping the compiler
22
3[*Bootstrapping*][boot] is the process of using a compiler to compile itself.
4More accurately, it means using an older compiler to compile a newer version
5of the same compiler.
3[*Bootstrapping*] is the process of using a compiler to compile itself.
4More accurately, it means using an older compiler to compile a newer version of the same compiler.
65
76This raises a chicken-and-egg paradox: where did the first compiler come from?
8It must have been written in a different language. In Rust's case it was
9[written in OCaml][ocaml-compiler]. However, it was abandoned long ago, and the
10only way to build a modern version of rustc is with a slightly less modern
11version.
7It must have been written in a different language.
8In Rust's case it was [written in OCaml].
9However, it was abandoned long ago, and the
10only way to build a modern version of rustc is with a slightly less modern version.
1211
1312This is exactly how `x.py` works: it downloads the current beta release of
1413rustc, then uses it to compile the new compiler.
......@@ -17,8 +16,7 @@ In this section, we give a high-level overview of
1716[what Bootstrap does](./what-bootstrapping-does.md), followed by a high-level
1817introduction to [how Bootstrap does it](./how-bootstrap-does-it.md).
1918
20Additionally, see [debugging bootstrap](./debugging-bootstrap.md) to learn
21about debugging methods.
19Additionally, see [debugging bootstrap](./debugging-bootstrap.md) to learn about debugging methods.
2220
23[boot]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers)
24[ocaml-compiler]: https://github.com/rust-lang/rust/tree/ef75860a0a72f79f97216f8aaa5b388d98da6480/src/boot
21[*Bootstrapping*]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers)
22[written in OCaml]: https://github.com/rust-lang/rust/tree/ef75860a0a72f79f97216f8aaa5b388d98da6480/src/boot
src/doc/rustc-dev-guide/src/compiler-debugging.md+2-2
......@@ -236,7 +236,7 @@ The compiler uses the [`tracing`] crate for logging.
236236
237237For details, see [the chapter on tracing](./tracing.md).
238238
239## Narrowing (Bisecting) Regressions
239## Narrowing (bisecting) regressions
240240
241241The [cargo-bisect-rustc][bisect] tool can be used as a quick and easy way to
242242find exactly which PR caused a change in `rustc` behavior.
......@@ -248,7 +248,7 @@ You can then look at the PR to get more context on *why* it was changed.
248248[bisect]: https://github.com/rust-lang/cargo-bisect-rustc
249249[bisect-tutorial]: https://rust-lang.github.io/cargo-bisect-rustc/tutorial.html
250250
251## Downloading Artifacts from Rust's CI
251## Downloading artifacts from Rust's CI
252252
253253The [rustup-toolchain-install-master][rtim] tool by kennytm can be used to
254254download the artifacts produced by Rust's CI for a specific SHA1 -- this
src/doc/rustc-dev-guide/src/contributing.md+8-8
......@@ -257,7 +257,7 @@ In particular, we don't recommend running the full `./x test` suite locally,
257257since it takes a very long time to execute.
258258See the [Testing with CI] chapter for using Rust's CI to test your changes.
259259
260[Testing with CI]: https://rustc-dev-guide.rust-lang.org/tests/ci.html#testing-with-ci
260[Testing with CI]: tests/ci.md#testing-with-ci
261261
262262### r+
263263
......@@ -425,7 +425,7 @@ Just a few things to keep in mind:
425425
426426- When contributing text to the guide, please contextualize the information with some time period
427427 and/or a reason so that the reader knows how much to trust the information.
428 Aim to provide a reasonable amount of context, possibly including but not limited to:
428 Aim to provide a reasonable amount of context, and consider including:
429429
430430 - A reason for why the text may be out of date other than "change",
431431 as change is a constant across the project.
......@@ -444,29 +444,29 @@ Just a few things to keep in mind:
444444 For the action to pick the date, add a special annotation before specifying the date:
445445
446446 ```md
447 <!-- date-check --> Nov 2025
447 <!-- date-check --> Jul 2026
448448 ```
449449
450450 Example:
451451
452452 ```md
453 As of <!-- date-check --> Nov 2025, the foo did the bar.
453 As of <!-- date-check --> Jul 2026, the foo did the bar.
454454 ```
455455
456456 For cases where the date should not be part of the visible rendered output,
457457 use the following instead:
458458
459459 ```md
460 <!-- date-check: Nov 2025 -->
460 <!-- date-check: Jul 2026 -->
461461 ```
462462
463463 - A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide
464464 further explanation for the change process or a way to verify that the information is not
465465 outdated.
466466
467- If a text grows rather long (more than a few page scrolls) or complicated (more than four
468 subsections), it might benefit from having a Table of Contents at the beginning,
469 which you can auto-generate by including the `<!-- toc -->` marker at the top.
467- Use sentence case for chapter and sections titles.
468
469- Use dashes (`-`) to separate words file names.
470470
471471#### ⚠️ Note: Where to contribute `rustc-dev-guide` changes
472472
src/doc/rustc-dev-guide/src/offload/installation.md+1-1
......@@ -44,7 +44,7 @@ Run this test script for offload-specific tests:
4444./x test --stage 1 tests/codegen-llvm/gpu_offload
4545```
4646
47For testing the CI locally, you may use the commands outlined in [Testing with Docker](https://rustc-dev-guide.rust-lang.org/tests/docker.html):
47For testing the CI locally, you may use the commands outlined in [Testing with Docker](../tests/docker.md):
4848```console
4949cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux
5050```
src/doc/rustc-dev-guide/src/tests/best-practices.md+1-1
......@@ -171,7 +171,7 @@ place.
171171 If a test suite can
172172 randomly spuriously fail due to flaky tests, did the whole test suite pass or
173173 did I just get lucky/unlucky?
174- Flaky tests can randomly fail in full CI, wasting previous full CI resources.
174- Flaky tests can randomly fail in full CI, wasting precious resources.
175175
176176## Compiletest directives
177177
src/doc/rustc-dev-guide/src/tests/ci.md+1-1
......@@ -209,7 +209,7 @@ to help make the perf comparison as fair as possible.
209209>
210210> 3. Run the prescribed try jobs with `@bors try`. As aforementioned, this
211211> requires the user to either (1) have `try` permissions or (2) be delegated
212> with `try` permissions by `@bors delegate=try` by someone who has `try`
212> with `try` permissions by `@bors delegate try` by someone who has `try`
213213> permissions.
214214>
215215> Note that this is usually easier to do than manually edit [`jobs.yml`].
src/doc/rustc-dev-guide/src/traits/separate-projection-bounds.md+1-1
......@@ -8,7 +8,7 @@ The way we prove `Projection` bounds directly relies on proving the correspondin
88It feels like it might make more sense to just have a single implementation which checks whether a trait is implemented and returns (a way to compute) its associated types.
99
1010This is unfortunately quite difficult, as we may use a different candidate for norm than for the corresponding trait bound.
11See [alias-bound vs where-bound](https://rustc-dev-guide.rust-lang.org/solve/candidate-preference.html#we-always-consider-aliasbound-candidates) and [global where-bound vs impl](https://rustc-dev-guide.rust-lang.org/solve/candidate-preference.html#we-prefer-global-where-bounds-over-impls).
11See [alias-bound vs where-bound](../solve/candidate-preference.md#we-always-consider-aliasbound-candidates) and [global where-bound vs impl](../solve/candidate-preference.md#we-prefer-global-where-bounds-over-impls).
1212
1313There are also some other subtle reasons for why we can't do so.
1414The most stupid is that for rigid aliases;
src/doc/unstable-book/src/compiler-flags/force-intrinsic-fallback.md created+6
......@@ -0,0 +1,6 @@
1## `force-intrinsic-fallback`
2
3Configures codegen to always use the fallback body of an intrinsic, if it has one,
4instead of lowering the intrinsic in the codegen backend.
5
6This is useful for testing the fallback implementation.
src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed+1-1
......@@ -1,5 +1,5 @@
11#![allow(unused)]
2// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
2// FIXME(static_mut_refs): use raw pointers instead of references
33#![allow(static_mut_refs)]
44
55#[derive(Debug)]
src/tools/clippy/tests/ui/redundant_static_lifetimes.rs+1-1
......@@ -1,5 +1,5 @@
11#![allow(unused)]
2// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
2// FIXME(static_mut_refs): use raw pointers instead of references
33#![allow(static_mut_refs)]
44
55#[derive(Debug)]
src/tools/clippy/tests/ui/useless_conversion.fixed+1-1
......@@ -1,7 +1,7 @@
11#![deny(clippy::useless_conversion)]
22#![allow(clippy::into_iter_on_ref)]
33#![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)]
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77use std::ops::ControlFlow;
src/tools/clippy/tests/ui/useless_conversion.rs+1-1
......@@ -1,7 +1,7 @@
11#![deny(clippy::useless_conversion)]
22#![allow(clippy::into_iter_on_ref)]
33#![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)]
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77use std::ops::ControlFlow;
src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs+1-1
......@@ -1,7 +1,7 @@
11//@only-target: linux android
22//@compile-flags: -Zmiri-disable-isolation
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77use std::mem::MaybeUninit;
src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs+1-1
......@@ -5,7 +5,7 @@
55//! the fallback path in `guard::key::enable`, which uses a *single* pthread_key
66//! to manage a thread-local list of dtors to call.
77
8// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
8// FIXME(static_mut_refs): use raw pointers instead of references
99#![allow(static_mut_refs)]
1010
1111use std::{mem, ptr};
src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs+1-1
......@@ -3,7 +3,7 @@
33//@compile-flags: -Zmiri-deterministic-concurrency
44//@run-native
55
6// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99use std::{io, thread};
src/tools/miri/tests/pass-dep/libc/libc-pipe.rs+1-1
......@@ -69,7 +69,7 @@ fn test_pipe_threaded() {
6969 thread2.join().unwrap();
7070}
7171
72// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
72// FIXME(static_mut_refs): use raw pointers instead of references
7373#[allow(static_mut_refs)]
7474fn test_race() {
7575 static mut VAL: u8 = 0;
src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs+1-1
......@@ -3,7 +3,7 @@
33//@compile-flags: -Zmiri-deterministic-concurrency
44//@run-native
55
6// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99use std::thread;
src/tools/miri/tests/pass/atomic.rs+1-1
......@@ -3,7 +3,7 @@
33//@[tree]compile-flags: -Zmiri-tree-borrows
44//@compile-flags: -Zmiri-strict-provenance
55
6// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99use std::sync::atomic::Ordering::*;
src/tools/miri/tests/pass/static_memory_modification.rs+1-1
......@@ -1,4 +1,4 @@
1// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
1// FIXME(static_mut_refs): use raw pointers instead of references
22#![allow(static_mut_refs)]
33
44use std::sync::atomic::{AtomicUsize, Ordering};
src/tools/miri/tests/pass/static_mut.rs+1-1
......@@ -1,4 +1,4 @@
1// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
1// FIXME(static_mut_refs): use raw pointers instead of references
22#![allow(static_mut_refs)]
33
44use std::ptr::addr_of;
src/tools/miri/tests/pass/tls/tls_static.rs+1-1
......@@ -8,7 +8,7 @@
88//! dereferencing the pointer on `t2` resolves to `t1`'s thread-local. In this
99//! test, we also check that thread-locals act as per-thread statics.
1010
11// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
11// FIXME(static_mut_refs): use raw pointers instead of references
1212#![allow(static_mut_refs)]
1313#![feature(thread_local)]
1414
src/tools/tidy/src/issues.txt-2
......@@ -2324,8 +2324,6 @@ ui/resolve/issue-2356.rs
23242324ui/resolve/issue-23716.rs
23252325ui/resolve/issue-24968.rs
23262326ui/resolve/issue-26545.rs
2327ui/resolve/issue-3021-c.rs
2328ui/resolve/issue-3021.rs
23292327ui/resolve/issue-30535.rs
23302328ui/resolve/issue-3099-a.rs
23312329ui/resolve/issue-3099-b.rs
src/tools/tidy/src/triagebot.rs+6-1
......@@ -51,7 +51,12 @@ pub fn check(path: &Path, tidy_ctx: TidyCtx) {
5151 // The full-path doesn't exists, maybe it's a glob, let's add it to the glob set builder
5252 // to be checked against all the file and directories in the repository.
5353 let trimmed_path = clean_path.trim_end_matches('/');
54 builder.add(globset::Glob::new(&format!("{trimmed_path}{{,/*}}")).unwrap());
54 builder.add(
55 globset::GlobBuilder::new(&format!("{trimmed_path}{{,/*}}"))
56 .empty_alternates(true)
57 .build()
58 .unwrap(),
59 );
5560 glob_entries.push(clean_path.to_string());
5661 } else if is_in_submodule(Path::new(clean_path)) {
5762 check.error(format!(
tests/codegen-llvm/force-intrinsic-fallback.rs created+38
......@@ -0,0 +1,38 @@
1//@ compile-flags: --crate-type=lib -C no-prepopulate-passes -Copt-level=3
2//
3//@ revisions: NORMAL FALLBACK
4//@ [FALLBACK] compile-flags: -Zforce-intrinsic-fallback
5#![feature(core_intrinsics, funnel_shifts)]
6
7// Check the effect of `-Zforce-intrinsic-fallback`.
8//
9// Without the flag, the dedicated backend lowering of the intrinsic is used.
10// With the flag, the fallback body is called instead.
11
12#[no_mangle]
13pub fn call_minimumf32(x: f32, y: f32) -> f32 {
14 // CHECK-LABEL: @call_minimumf32
15
16 // NORMAL: call float @llvm.minimum.f32
17 // NORMAL-NOT: minimumf32
18
19 // FALLBACK-NOT: @llvm.minimum
20 // FALLBACK: call {{.*}}minimumf32
21 core::intrinsics::minimumf32(x, y)
22}
23
24// Codegen backends can return a list of `replaced_intrinsics`, for which codegen of the fallback is
25// normally skipped. `unchecked_funnel_shl` is in that list for the LLVM backend, so we test it here
26// to ensure that with the flag enabled the fallback body is actually code generated and called.
27
28#[no_mangle]
29pub fn call_funnel_shl(a: u32, b: u32, shift: u32) -> u32 {
30 // CHECK-LABEL: @call_funnel_shl
31
32 // NORMAL: call i32 @llvm.fshl.i32
33 // NORMAL-NOT: funnel_shl
34
35 // FALLBACK-NOT: @llvm.fshl
36 // FALLBACK: call {{.*}}funnel_shl
37 unsafe { core::intrinsics::unchecked_funnel_shl(a, b, shift) }
38}
tests/run-make/avr-custom-target-missing-cpu/avr-custom-missing-cpu.json created+33
......@@ -0,0 +1,33 @@
1{
2 "arch": "avr",
3 "atomic-cas": false,
4 "crt-objects-fallback": "false",
5 "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8",
6 "eh-frame-header": false,
7 "exe-suffix": ".elf",
8 "late-link-args": {
9 "gnu-cc": [
10 "-lgcc"
11 ],
12 "gnu-lld-cc": [
13 "-lgcc"
14 ]
15 },
16 "linker": "avr-gcc",
17 "linker-flavor": "gnu-cc",
18 "llvm-target": "avr-unknown-unknown",
19 "max-atomic-width": 16,
20 "metadata": {
21 "description": null,
22 "host_tools": false,
23 "std": false,
24 "tier": 3
25 },
26 "pre-link-args": {
27 "gnu-cc": [],
28 "gnu-lld-cc": []
29 },
30 "relocation-model": "static",
31 "target-c-int-width": 16,
32 "target-pointer-width": 16
33}
tests/run-make/avr-custom-target-missing-cpu/foo.rs created+13
......@@ -0,0 +1,13 @@
1#![feature(no_core, lang_items)]
2#![no_core]
3
4#[lang = "pointee_sized"]
5pub trait PointeeSized {}
6
7#[lang = "meta_sized"]
8pub trait MetaSized: PointeeSized {}
9
10#[lang = "sized"]
11trait Sized {}
12
13pub fn foo() {}
tests/run-make/avr-custom-target-missing-cpu/rmake.rs created+16
......@@ -0,0 +1,16 @@
1// Custom AVR targets can reach ELF e_flags emission without an explicit CPU
2// Make sure that reports the normal missing-CPU diagnostic instead of ICEing
3//
4//@ needs-llvm-components: avr
5
6use run_make_support::rustc;
7
8fn main() {
9 rustc()
10 .arg("-Zunstable-options")
11 .input("foo.rs")
12 .target("avr-custom-missing-cpu.json")
13 .crate_type("lib")
14 .run_fail()
15 .assert_stderr_contains("target requires explicitly specifying a cpu with `-C target-cpu`");
16}
tests/rustdoc-ui/doc-auto-cfg-values-non-ident.rs created+7
......@@ -0,0 +1,7 @@
1// Regression test for https://github.com/rust-lang/rust/issues/158744.
2
3#![feature(doc_cfg)]
4
5#[doc(auto_cfg(hide(a, values(::b))))]
6//~^ ERROR malformed `doc` attribute input
7fn f() {}
tests/rustdoc-ui/doc-auto-cfg-values-non-ident.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0565]: malformed `doc` attribute input
2 --> $DIR/doc-auto-cfg-values-non-ident.rs:5:1
3 |
4LL | #[doc(auto_cfg(hide(a, values(::b))))]
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^^
6 | |
7 | expected a valid identifier here
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0565`.
tests/rustdoc-ui/doc-cfg-2.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `foo`
44LL | #[doc(cfg(foo), cfg(bar))]
55 | ^^^
66 |
7 = help: expected names are: `FALSE` and `test` and 32 more
7 = help: expected names are: `FALSE` and `test` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(foo)`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/abi/statics/static-mut-foreign.rs+1-1
......@@ -3,7 +3,7 @@
33// statics cannot. This ensures that there's some form of error if this is
44// attempted.
55
6// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99use std::ffi::c_int;
tests/ui/array-slice-vec/slice-panic-1.rs+1-1
......@@ -5,7 +5,7 @@
55
66// Test that if a slicing expr[..] fails, the correct cleanups happen.
77
8// FIXME(static_mut_refs): this could use an atomic
8// FIXME(static_mut_refs): use raw pointers instead of references
99#![allow(static_mut_refs)]
1010
1111use std::thread;
tests/ui/array-slice-vec/slice-panic-2.rs+1-1
......@@ -5,7 +5,7 @@
55
66// Test that if a slicing expr[..] fails, the correct cleanups happen.
77
8// FIXME(static_mut_refs): this could use an atomic
8// FIXME(static_mut_refs): use raw pointers instead of references
99#![allow(static_mut_refs)]
1010
1111use std::thread;
tests/ui/array-slice-vec/slice.rs+1-1
......@@ -3,7 +3,7 @@
33
44// Test slicing sugar.
55
6// FIXME(static_mut_refs): this could use an atomic
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99extern crate core;
tests/ui/associated-types/unconstrained-lifetime-in-projection.rs created+25
......@@ -0,0 +1,25 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/29861>.
2//! Unconstrained lifetimes in associated type were wrongly allowed when
3//! occurred in projection.
4
5pub trait MakeRef<'a> {
6 type Ref;
7}
8impl<'a, T: 'a> MakeRef<'a> for T {
9 type Ref = &'a T;
10}
11
12pub trait MakeRef2 {
13 type Ref2;
14}
15impl<'a, T: 'a> MakeRef2 for T {
16//~^ ERROR the lifetime parameter `'a` is not constrained
17 type Ref2 = <T as MakeRef<'a>>::Ref;
18}
19
20fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") }
21//~^ ERROR temporary value dropped while borrowed
22
23fn main() {
24 println!("{}", foo());
25}
tests/ui/associated-types/unconstrained-lifetime-in-projection.stderr created+21
......@@ -0,0 +1,21 @@
1error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
2 --> $DIR/unconstrained-lifetime-in-projection.rs:15:6
3 |
4LL | impl<'a, T: 'a> MakeRef2 for T {
5 | ^^ unconstrained lifetime parameter
6
7error[E0716]: temporary value dropped while borrowed
8 --> $DIR/unconstrained-lifetime-in-projection.rs:20:43
9 |
10LL | fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") }
11 | ^^^^^^^^^^^^^^^^^^^ -- borrow later used here
12 | | |
13 | | temporary value is freed at the end of this statement
14 | creates a temporary value which is freed while still in use
15 |
16 = note: consider using a `let` binding to create a longer lived value
17
18error: aborting due to 2 previous errors
19
20Some errors have detailed explanations: E0207, E0716.
21For more information about an error, try `rustc --explain E0207`.
tests/ui/async-await/issues/issue-67611-static-mut-refs.rs+1-1
......@@ -1,7 +1,7 @@
11//@ build-pass
22//@ edition:2018
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77static mut A: [i32; 5] = [1, 2, 3, 4, 5];
tests/ui/attributes/builtin-attr-macro-value-issue-145922.rs created+34
......@@ -0,0 +1,34 @@
1//@ check-pass
2#![allow(unused_attributes, unused_macros)]
3
4// Regression test for #145922.
5// This used to create a delayed ICE while parsing builtin attributes.
6#[crate_type = concat!("my", "crate")]
7macro_rules! foo {
8 () => {
9 32
10 };
11}
12
13#[recursion_limit = concat!("1", "2")]
14macro_rules! baz {
15 () => {
16 32
17 };
18}
19
20#[type_length_limit = concat!("1", "2")]
21macro_rules! qux {
22 () => {
23 32
24 };
25}
26
27#[windows_subsystem = concat!("cons", "ole")]
28macro_rules! bar {
29 () => {
30 32
31 };
32}
33
34fn main() {}
tests/ui/binding/order-drop-with-match.rs+1-1
......@@ -5,7 +5,7 @@
55// in ORDER matching up to when it ran.
66// Correct order is: matched, inner, outer
77
8// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
8// FIXME(static_mut_refs): use raw pointers instead of references
99#![allow(static_mut_refs)]
1010
1111static mut ORDER: [usize; 3] = [0, 0, 0];
tests/ui/binding/ref-pattern-drop-behavior-8860.rs+1-1
......@@ -1,6 +1,6 @@
11// https://github.com/rust-lang/rust/issues/8860
22//@ run-pass
3// FIXME(static_mut_refs): this could use an atomic
3// FIXME(static_mut_refs): use raw pointers instead of references
44#![allow(static_mut_refs)]
55#![allow(dead_code)]
66
tests/ui/borrowck/index-self-with-arithmetic-on-self-item.rs created+10
......@@ -0,0 +1,10 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/29743>.
2//! Test borrowck doesn't complain about using arithmetic with self item
3//! as index.
4//@ check-pass
5
6fn main() {
7 let mut i = [1, 2, 3];
8 i[i[0]] = 0;
9 i[i[0] - 1] = 0;
10}
tests/ui/cfg/disallowed-cli-cfgs.rs+2
......@@ -8,6 +8,7 @@
88//@ revisions: target_object_format_ target_pointer_width_ target_vendor_
99//@ revisions: target_has_atomic_ target_has_atomic_primitive_alignment_
1010//@ revisions: target_has_atomic_load_store_ target_thread_local_ relocation_model_
11//@ revisions: target_has_threads_
1112//@ revisions: fmt_debug_
1213//@ revisions: reliable_f16_ reliable_f16_math_ reliable_f128_ reliable_f128_math_
1314
......@@ -34,6 +35,7 @@
3435//@ [target_has_atomic_]compile-flags: --cfg target_has_atomic="32"
3536//@ [target_has_atomic_primitive_alignment_]compile-flags: --cfg target_has_atomic_primitive_alignment="32"
3637//@ [target_has_atomic_load_store_]compile-flags: --cfg target_has_atomic_load_store="32"
38//@ [target_has_threads_]compile-flags: --cfg target_has_threads
3739//@ [target_thread_local_]compile-flags: --cfg target_thread_local
3840//@ [relocation_model_]compile-flags: --cfg relocation_model="a"
3941//@ [fmt_debug_]compile-flags: --cfg fmt_debug="shallow"
tests/ui/cfg/disallowed-cli-cfgs.target_has_threads_.stderr created+8
......@@ -0,0 +1,8 @@
1error: unexpected `--cfg target_has_threads` flag
2 |
3 = note: config `target_has_threads` is only supposed to be controlled by `--target`
4 = note: manually setting a built-in cfg can and does create incoherent behaviors
5 = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
6
7error: aborting due to 1 previous error
8
tests/ui/check-cfg/cargo-build-script.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `has_foo`
44LL | #[cfg(has_foo)]
55 | ^^^^^^^
66 |
7 = help: expected names are: `has_bar` and 32 more
7 = help: expected names are: `has_bar` and 33 more
88 = help: consider using a Cargo feature instead
99 = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
1010 [lints.rust]
tests/ui/check-cfg/cargo-feature.none.stderr+1-1
......@@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable`
2525LL | #[cfg(tokio_unstable)]
2626 | ^^^^^^^^^^^^^^
2727 |
28 = help: expected names are: `docsrs`, `feature`, and `test` and 32 more
28 = help: expected names are: `docsrs`, `feature`, and `test` and 33 more
2929 = help: consider using a Cargo feature instead
3030 = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
3131 [lints.rust]
tests/ui/check-cfg/cargo-feature.some.stderr+1-1
......@@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable`
2525LL | #[cfg(tokio_unstable)]
2626 | ^^^^^^^^^^^^^^
2727 |
28 = help: expected names are: `CONFIG_NVME`, `docsrs`, `feature`, and `test` and 32 more
28 = help: expected names are: `CONFIG_NVME`, `docsrs`, `feature`, and `test` and 33 more
2929 = help: consider using a Cargo feature instead
3030 = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
3131 [lints.rust]
tests/ui/check-cfg/cfg-select.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `invalid_cfg1`
44LL | invalid_cfg1 => {}
55 | ^^^^^^^^^^^^
66 |
7 = help: expected names are: `FALSE` and `test` and 32 more
7 = help: expected names are: `FALSE` and `test` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(invalid_cfg1)`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `value`
44LL | #[cfg(value)]
55 | ^^^^^
66 |
7 = help: expected names are: `bar`, `bee`, `cow`, and `foo` and 32 more
7 = help: expected names are: `bar`, `bee`, `cow`, and `foo` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(value)`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_value`
44LL | #[cfg(my_value)]
55 | ^^^^^^^^
66 |
7 = help: expected names are: `bar` and `foo` and 32 more
7 = help: expected names are: `bar` and `foo` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(my_value)`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/exhaustive-names-values.feature.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key`
44LL | #[cfg(unknown_key = "value")]
55 | ^^^^^^^^^^^^^^^^^^^^^
66 |
7 = help: expected names are: `feature` and 32 more
7 = help: expected names are: `feature` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/exhaustive-names-values.full.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key`
44LL | #[cfg(unknown_key = "value")]
55 | ^^^^^^^^^^^^^^^^^^^^^
66 |
7 = help: expected names are: `feature` and 32 more
7 = help: expected names are: `feature` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/hrtb-crash.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `b`
44LL | for<#[cfg(b)] c> u8:;
55 | ^ help: found config with similar value: `target_feature = "b"`
66 |
7 = help: expected names are: `FALSE`, `docsrs`, and `test` and 32 more
7 = help: expected names are: `FALSE`, `docsrs`, and `test` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(b)`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/mix.stderr+1-1
......@@ -44,7 +44,7 @@ warning: unexpected `cfg` condition name: `uu`
4444LL | #[cfg_attr(uu, unix)]
4545 | ^^
4646 |
47 = help: expected names are: `feature` and 32 more
47 = help: expected names are: `feature` and 33 more
4848 = help: to expect this configuration use `--check-cfg=cfg(uu)`
4949 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
5050
tests/ui/check-cfg/nested-cfg.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown`
44LL | #[cfg(unknown)]
55 | ^^^^^^^
66 |
7 = help: expected names are: `FALSE` and `test` and 32 more
7 = help: expected names are: `FALSE` and `test` and 33 more
88 = help: to expect this configuration use `--check-cfg=cfg(unknown)`
99 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1010 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/check-cfg/raw-keywords.edition2015.stderr+1-1
......@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition name: `r#false`
1414LL | #[cfg(r#false)]
1515 | ^^^^^^^
1616 |
17 = help: expected names are: `async`, `edition2015`, `edition2021`, and `r#true` and 32 more
17 = help: expected names are: `async`, `edition2015`, `edition2021`, and `r#true` and 33 more
1818 = help: to expect this configuration use `--check-cfg=cfg(r#false)`
1919 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
2020
tests/ui/check-cfg/raw-keywords.edition2021.stderr+1-1
......@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition name: `r#false`
1414LL | #[cfg(r#false)]
1515 | ^^^^^^^
1616 |
17 = help: expected names are: `r#async`, `edition2015`, `edition2021`, and `r#true` and 32 more
17 = help: expected names are: `r#async`, `edition2015`, `edition2021`, and `r#true` and 33 more
1818 = help: to expect this configuration use `--check-cfg=cfg(r#false)`
1919 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
2020
tests/ui/check-cfg/report-in-external-macros.cargo.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_lib_cfg`
44LL | cfg_macro::my_lib_macro!();
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
66 |
7 = help: expected names are: `feature` and 32 more
7 = help: expected names are: `feature` and 33 more
88 = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
99 = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
1010 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
tests/ui/check-cfg/report-in-external-macros.rustc.stderr+1-1
......@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_lib_cfg`
44LL | cfg_macro::my_lib_macro!();
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
66 |
7 = help: expected names are: `feature` and 32 more
7 = help: expected names are: `feature` and 33 more
88 = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
99 = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
1010 = help: to expect this configuration use `--check-cfg=cfg(my_lib_cfg)`
tests/ui/check-cfg/well-known-names.stderr+1
......@@ -28,6 +28,7 @@ LL | #[cfg(list_all_well_known_cfgs)]
2828`target_has_atomic`
2929`target_has_atomic_load_store`
3030`target_has_atomic_primitive_alignment`
31`target_has_threads`
3132`target_object_format`
3233`target_os`
3334`target_pointer_width`
tests/ui/check-cfg/well-known-values.rs+3
......@@ -15,6 +15,7 @@
1515#![feature(cfg_target_has_atomic)]
1616#![feature(cfg_target_thread_local)]
1717#![feature(cfg_target_object_format)]
18#![feature(cfg_target_has_threads)]
1819#![feature(cfg_ub_checks)]
1920#![feature(fmt_debug)]
2021
......@@ -68,6 +69,8 @@
6869 //~^ WARN unexpected `cfg` condition value
6970 target_has_atomic_primitive_alignment = "_UNEXPECTED_VALUE",
7071 //~^ WARN unexpected `cfg` condition value
72 target_has_threads = "_UNEXPECTED_VALUE",
73 //~^ WARN unexpected `cfg` condition value
7174 target_object_format = "_UNEXPECTED_VALUE",
7275 //~^ WARN unexpected `cfg` condition value
7376 target_os = "_UNEXPECTED_VALUE",
tests/ui/check-cfg/well-known-values.stderr+41-30
......@@ -1,5 +1,5 @@
11warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
2 --> $DIR/well-known-values.rs:29:5
2 --> $DIR/well-known-values.rs:30:5
33 |
44LL | clippy = "_UNEXPECTED_VALUE",
55 | ^^^^^^----------------------
......@@ -11,7 +11,7 @@ LL | clippy = "_UNEXPECTED_VALUE",
1111 = note: `#[warn(unexpected_cfgs)]` on by default
1212
1313warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
14 --> $DIR/well-known-values.rs:31:5
14 --> $DIR/well-known-values.rs:32:5
1515 |
1616LL | debug_assertions = "_UNEXPECTED_VALUE",
1717 | ^^^^^^^^^^^^^^^^----------------------
......@@ -22,7 +22,7 @@ LL | debug_assertions = "_UNEXPECTED_VALUE",
2222 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
2323
2424warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
25 --> $DIR/well-known-values.rs:33:5
25 --> $DIR/well-known-values.rs:34:5
2626 |
2727LL | doc = "_UNEXPECTED_VALUE",
2828 | ^^^----------------------
......@@ -33,7 +33,7 @@ LL | doc = "_UNEXPECTED_VALUE",
3333 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
3434
3535warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
36 --> $DIR/well-known-values.rs:35:5
36 --> $DIR/well-known-values.rs:36:5
3737 |
3838LL | doctest = "_UNEXPECTED_VALUE",
3939 | ^^^^^^^----------------------
......@@ -44,7 +44,7 @@ LL | doctest = "_UNEXPECTED_VALUE",
4444 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
4545
4646warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
47 --> $DIR/well-known-values.rs:37:5
47 --> $DIR/well-known-values.rs:38:5
4848 |
4949LL | fmt_debug = "_UNEXPECTED_VALUE",
5050 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -53,7 +53,7 @@ LL | fmt_debug = "_UNEXPECTED_VALUE",
5353 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
5454
5555warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
56 --> $DIR/well-known-values.rs:39:5
56 --> $DIR/well-known-values.rs:40:5
5757 |
5858LL | miri = "_UNEXPECTED_VALUE",
5959 | ^^^^----------------------
......@@ -64,7 +64,7 @@ LL | miri = "_UNEXPECTED_VALUE",
6464 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
6565
6666warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
67 --> $DIR/well-known-values.rs:41:5
67 --> $DIR/well-known-values.rs:42:5
6868 |
6969LL | overflow_checks = "_UNEXPECTED_VALUE",
7070 | ^^^^^^^^^^^^^^^----------------------
......@@ -75,7 +75,7 @@ LL | overflow_checks = "_UNEXPECTED_VALUE",
7575 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
7676
7777warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
78 --> $DIR/well-known-values.rs:43:5
78 --> $DIR/well-known-values.rs:44:5
7979 |
8080LL | panic = "_UNEXPECTED_VALUE",
8181 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -84,7 +84,7 @@ LL | panic = "_UNEXPECTED_VALUE",
8484 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
8585
8686warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
87 --> $DIR/well-known-values.rs:45:5
87 --> $DIR/well-known-values.rs:46:5
8888 |
8989LL | proc_macro = "_UNEXPECTED_VALUE",
9090 | ^^^^^^^^^^----------------------
......@@ -95,7 +95,7 @@ LL | proc_macro = "_UNEXPECTED_VALUE",
9595 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
9696
9797warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
98 --> $DIR/well-known-values.rs:47:5
98 --> $DIR/well-known-values.rs:48:5
9999 |
100100LL | relocation_model = "_UNEXPECTED_VALUE",
101101 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -104,7 +104,7 @@ LL | relocation_model = "_UNEXPECTED_VALUE",
104104 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
105105
106106warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
107 --> $DIR/well-known-values.rs:49:5
107 --> $DIR/well-known-values.rs:50:5
108108 |
109109LL | rustfmt = "_UNEXPECTED_VALUE",
110110 | ^^^^^^^----------------------
......@@ -115,7 +115,7 @@ LL | rustfmt = "_UNEXPECTED_VALUE",
115115 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
116116
117117warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
118 --> $DIR/well-known-values.rs:51:5
118 --> $DIR/well-known-values.rs:52:5
119119 |
120120LL | sanitize = "_UNEXPECTED_VALUE",
121121 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -124,7 +124,7 @@ LL | sanitize = "_UNEXPECTED_VALUE",
124124 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
125125
126126warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
127 --> $DIR/well-known-values.rs:53:5
127 --> $DIR/well-known-values.rs:54:5
128128 |
129129LL | target_abi = "_UNEXPECTED_VALUE",
130130 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -133,7 +133,7 @@ LL | target_abi = "_UNEXPECTED_VALUE",
133133 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
134134
135135warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
136 --> $DIR/well-known-values.rs:55:5
136 --> $DIR/well-known-values.rs:56:5
137137 |
138138LL | target_arch = "_UNEXPECTED_VALUE",
139139 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -142,7 +142,7 @@ LL | target_arch = "_UNEXPECTED_VALUE",
142142 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
143143
144144warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
145 --> $DIR/well-known-values.rs:57:5
145 --> $DIR/well-known-values.rs:58:5
146146 |
147147LL | target_endian = "_UNEXPECTED_VALUE",
148148 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -151,7 +151,7 @@ LL | target_endian = "_UNEXPECTED_VALUE",
151151 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
152152
153153warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
154 --> $DIR/well-known-values.rs:59:5
154 --> $DIR/well-known-values.rs:60:5
155155 |
156156LL | target_env = "_UNEXPECTED_VALUE",
157157 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -160,7 +160,7 @@ LL | target_env = "_UNEXPECTED_VALUE",
160160 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
161161
162162warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
163 --> $DIR/well-known-values.rs:61:5
163 --> $DIR/well-known-values.rs:62:5
164164 |
165165LL | target_family = "_UNEXPECTED_VALUE",
166166 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -169,7 +169,7 @@ LL | target_family = "_UNEXPECTED_VALUE",
169169 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
170170
171171warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
172 --> $DIR/well-known-values.rs:65:5
172 --> $DIR/well-known-values.rs:66:5
173173 |
174174LL | target_has_atomic = "_UNEXPECTED_VALUE",
175175 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -178,7 +178,7 @@ LL | target_has_atomic = "_UNEXPECTED_VALUE",
178178 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
179179
180180warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
181 --> $DIR/well-known-values.rs:67:5
181 --> $DIR/well-known-values.rs:68:5
182182 |
183183LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE",
184184 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -187,7 +187,7 @@ LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE",
187187 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
188188
189189warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
190 --> $DIR/well-known-values.rs:69:5
190 --> $DIR/well-known-values.rs:70:5
191191 |
192192LL | target_has_atomic_primitive_alignment = "_UNEXPECTED_VALUE",
193193 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -196,7 +196,18 @@ LL | target_has_atomic_primitive_alignment = "_UNEXPECTED_VALUE",
196196 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
197197
198198warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
199 --> $DIR/well-known-values.rs:71:5
199 --> $DIR/well-known-values.rs:72:5
200 |
201LL | target_has_threads = "_UNEXPECTED_VALUE",
202 | ^^^^^^^^^^^^^^^^^^----------------------
203 | |
204 | help: remove the value
205 |
206 = note: no expected value for `target_has_threads`
207 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
208
209warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
210 --> $DIR/well-known-values.rs:74:5
200211 |
201212LL | target_object_format = "_UNEXPECTED_VALUE",
202213 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -205,7 +216,7 @@ LL | target_object_format = "_UNEXPECTED_VALUE",
205216 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
206217
207218warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
208 --> $DIR/well-known-values.rs:73:5
219 --> $DIR/well-known-values.rs:76:5
209220 |
210221LL | target_os = "_UNEXPECTED_VALUE",
211222 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -214,7 +225,7 @@ LL | target_os = "_UNEXPECTED_VALUE",
214225 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
215226
216227warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
217 --> $DIR/well-known-values.rs:75:5
228 --> $DIR/well-known-values.rs:78:5
218229 |
219230LL | target_pointer_width = "_UNEXPECTED_VALUE",
220231 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -223,7 +234,7 @@ LL | target_pointer_width = "_UNEXPECTED_VALUE",
223234 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
224235
225236warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
226 --> $DIR/well-known-values.rs:77:5
237 --> $DIR/well-known-values.rs:80:5
227238 |
228239LL | target_thread_local = "_UNEXPECTED_VALUE",
229240 | ^^^^^^^^^^^^^^^^^^^----------------------
......@@ -234,7 +245,7 @@ LL | target_thread_local = "_UNEXPECTED_VALUE",
234245 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
235246
236247warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
237 --> $DIR/well-known-values.rs:79:5
248 --> $DIR/well-known-values.rs:82:5
238249 |
239250LL | target_vendor = "_UNEXPECTED_VALUE",
240251 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -243,7 +254,7 @@ LL | target_vendor = "_UNEXPECTED_VALUE",
243254 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
244255
245256warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
246 --> $DIR/well-known-values.rs:81:5
257 --> $DIR/well-known-values.rs:84:5
247258 |
248259LL | ub_checks = "_UNEXPECTED_VALUE",
249260 | ^^^^^^^^^----------------------
......@@ -254,7 +265,7 @@ LL | ub_checks = "_UNEXPECTED_VALUE",
254265 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
255266
256267warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
257 --> $DIR/well-known-values.rs:83:5
268 --> $DIR/well-known-values.rs:86:5
258269 |
259270LL | unix = "_UNEXPECTED_VALUE",
260271 | ^^^^----------------------
......@@ -265,7 +276,7 @@ LL | unix = "_UNEXPECTED_VALUE",
265276 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
266277
267278warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
268 --> $DIR/well-known-values.rs:85:5
279 --> $DIR/well-known-values.rs:88:5
269280 |
270281LL | windows = "_UNEXPECTED_VALUE",
271282 | ^^^^^^^----------------------
......@@ -276,7 +287,7 @@ LL | windows = "_UNEXPECTED_VALUE",
276287 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
277288
278289warning: unexpected `cfg` condition value: `linuz`
279 --> $DIR/well-known-values.rs:91:7
290 --> $DIR/well-known-values.rs:94:7
280291 |
281292LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
282293 | ^^^^^^^^^^^^-------
......@@ -286,5 +297,5 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
286297 = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qnx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
287298 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
288299
289warning: 29 warnings emitted
300warning: 30 warnings emitted
290301
tests/ui/closures/closure_requires_expectation.rs created+41
......@@ -0,0 +1,41 @@
1//@ check-pass
2
3// `slot` is an out reference.
4// We move `state` into a closure, i.e. the closure holds a &'long mut ().
5//
6// We move it out of the closure again though, in two steps.
7// We first assign it to `temp`.
8// `temp` has an expected type, so rust inserts a reborrow.
9//
10// We then move it again, into `slot`, moving it out of the closure.
11// The reborrow could've resulted in `temp` having a shorter lifetime.
12// Only in borrowck do we require the lifetime in `temp` to also be `'long`.
13//
14// However, when we analyze upvars, *we don't know that yet*.
15// The reborrow gets treated as: a borrow. And the closure gets inferred to be an FnMut.
16// This would make the assignment invalid, you cannot move out of an FnMut!
17//
18// The reason this compiles is that the closure is checked with an `FnOnce` expectation,
19// which makes it so despite the upvars not indicating it should be, the closure becomes FnOnce
20// and borrowck is happy that we're moving out of the closure.
21//
22// Note that the `move` keyword only influences how the upvars are moved into the closure.
23// It doesn't change whether the closure can be called more than once.
24// This example compiles without `move` keyword as long as `state` is moved into the closure in
25// some way. This can alternatively be implemented with `let temp = temp` (without expectation),
26// since that doesn't insert a reborrow.
27fn wrap<'short, 'long>(slot: &'short mut &'long mut (), state: &'long mut ()) {
28 fnonce_requirement(move || {
29 let temp: &mut _ = /* rust inserts `&mut *` */ state;
30 *slot = temp;
31 })
32}
33
34fn fnonce_requirement<F>(wrap: F)
35where
36 F: FnOnce(),
37{
38 todo!()
39}
40
41fn main() {}
tests/ui/codegen/bitvec-to-bools-opt-miscompile.rs created+38
......@@ -0,0 +1,38 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/2989>.
2//@ run-pass
3
4#![allow(non_camel_case_types)]
5
6trait methods { //~ WARN trait `methods` is never used
7 fn to_bytes(&self) -> Vec<u8>;
8}
9
10impl methods for () {
11 fn to_bytes(&self) -> Vec<u8> {
12 Vec::new()
13 }
14}
15
16// the position of this function is significant! - if it comes before methods
17// then it works, if it comes after it then it doesn't!
18fn to_bools(bitv: Storage) -> Vec<bool> {
19 (0..8).map(|i| {
20 let w = i / 64;
21 let b = i % 64;
22 let x = 1 & (bitv.storage[w] >> b);
23 x == 1
24 }).collect()
25}
26
27struct Storage { storage: Vec<u64> }
28
29pub fn main() {
30 let bools = vec![false, false, true, false, false, true, true, false];
31 let bools2 = to_bools(Storage{storage: vec![0b01100100]});
32
33 for i in 0..8 {
34 println!("{} => {} vs {}", i, bools[i], bools2[i]);
35 }
36
37 assert_eq!(bools, bools2);
38}
tests/ui/codegen/bitvec-to-bools-opt-miscompile.stderr created+10
......@@ -0,0 +1,10 @@
1warning: trait `methods` is never used
2 --> $DIR/bitvec-to-bools-opt-miscompile.rs:6:7
3 |
4LL | trait methods {
5 | ^^^^^^^
6 |
7 = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
8
9warning: 1 warning emitted
10
tests/ui/codegen/box-deref-segfault-misopt.rs created+16
......@@ -0,0 +1,16 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/30081>.
2//! Misoptimization caused this to segfault.
3//@ run-pass
4
5pub enum Instruction {
6 Increment(i8),
7 Loop(Box<Box<()>>),
8}
9
10fn main() {
11 let instrs: Option<(u8, Box<Instruction>)> = None;
12 instrs.into_iter()
13 .map(|(_, instr)| instr)
14 .map(|instr| match *instr { _other => {} })
15 .last();
16}
tests/ui/coercion/generic-fn-items-in-array-literal.rs created+13
......@@ -0,0 +1,13 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/43923>
2//@ run-pass
3#![allow(dead_code)]
4#![allow(unused_variables)]
5struct A<T: ?Sized> { ptr: T }
6
7fn foo<T>(x: &A<[T]>) {}
8
9fn main() {
10 let a = foo;
11 let b = A { ptr: [a, a, a] };
12 a(&A { ptr: [()] });
13}
tests/ui/const-generics/min_adt_const_params/tuple_with_infer_arg.rs created+10
......@@ -0,0 +1,10 @@
1//@ check-pass
2
3#![feature(min_adt_const_params)]
4#![feature(min_generic_const_args)]
5
6struct S<const X: (u32, u32)>;
7
8fn main() {
9 let _: S<{ (1, _) }> = S::<{ (1, 2) }>;
10}
tests/ui/consts/static-mut-refs.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22#![allow(dead_code)]
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77// Checks that mutable static items can have mutable slices and other references
tests/ui/coroutine/static-mut-reference-across-yield.rs+1-1
......@@ -1,7 +1,7 @@
11//@ build-pass
22
33#![feature(coroutines, stmt_expr_attributes)]
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77static mut A: [i32; 5] = [1, 2, 3, 4, 5];
tests/ui/drop/conditional-drop-10734.rs+1-1
......@@ -3,7 +3,7 @@
33//@ run-pass
44#![allow(non_upper_case_globals)]
55
6// FIXME(static_mut_refs): this could use an atomic
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99static mut drop_count: usize = 0;
tests/ui/drop/destructor-run-for-expression-4734.rs+1-1
......@@ -4,7 +4,7 @@
44// Ensures that destructors are run for expressions of the form "e;" where
55// `e` is a type which requires a destructor.
66
7// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
7// FIXME(static_mut_refs): use raw pointers instead of references
88#![allow(static_mut_refs)]
99#![allow(path_statements)]
1010
tests/ui/drop/destructor-run-for-let-ignore-6892.rs+1-1
......@@ -4,7 +4,7 @@
44// Ensures that destructors are run for expressions of the form "let _ = e;"
55// where `e` is a type which requires a destructor.
66
7// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
7// FIXME(static_mut_refs): use raw pointers instead of references
88#![allow(static_mut_refs)]
99
1010struct Foo;
tests/ui/drop/drop-count-assertion-16151.rs+1-1
......@@ -1,7 +1,7 @@
11// https://github.com/rust-lang/rust/issues/16151
22//@ run-pass
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77use std::mem;
tests/ui/drop/drop-struct-as-object.rs+1-1
......@@ -5,7 +5,7 @@
55// Test that destructor on a struct runs successfully after the struct
66// is boxed and converted to an object.
77
8// FIXME(static_mut_refs): this could use an atomic
8// FIXME(static_mut_refs): use raw pointers instead of references
99#![allow(static_mut_refs)]
1010
1111static mut value: usize = 0;
tests/ui/drop/generic-drop-trait-bound-15858.rs+1-1
......@@ -1,7 +1,7 @@
11//! Regression test for https://github.com/rust-lang/rust/issues/15858
22
33//@ run-pass
4// FIXME(static_mut_refs): this could use an atomic
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66static mut DROP_RAN: bool = false;
77
tests/ui/drop/issue-23338-ensure-param-drop-order.rs+1-1
......@@ -1,6 +1,6 @@
11//@ run-pass
22#![allow(non_upper_case_globals)]
3// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
3// FIXME(static_mut_refs): use raw pointers instead of references
44#![allow(static_mut_refs)]
55
66// This test is ensuring that parameters are indeed dropped after
tests/ui/drop/issue-23611-enum-swap-in-drop.rs+1-1
......@@ -1,6 +1,6 @@
11//@ run-pass
22#![allow(non_upper_case_globals)]
3// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
3// FIXME(static_mut_refs): use raw pointers instead of references
44#![allow(static_mut_refs)]
55
66// Issue 23611: this test is ensuring that, for an instance `X` of the
tests/ui/drop/issue-48962.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22#![allow(unused_must_use)]
33// Test that we are able to reinitialize box with moved referent
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77static mut ORDER: [usize; 3] = [0, 0, 0];
tests/ui/drop/move-closure-drop-on-unwind.rs created+45
......@@ -0,0 +1,45 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/29946>.
2//! Test `FnOnce` impl closure's value gets properly dropped
3//! (during unwind as well).
4
5//@ run-pass
6//@ needs-unwind
7//@ ignore-backends: gcc
8
9use std::panic;
10
11impl<'a> panic::UnwindSafe for Foo<'a> {}
12impl<'a> panic::RefUnwindSafe for Foo<'a> {}
13
14struct Foo<'a>(&'a mut bool);
15
16impl<'a> Drop for Foo<'a> {
17 fn drop(&mut self) {
18 *self.0 = true;
19 }
20}
21
22fn f<T: FnOnce()>(t: T) {
23 t()
24}
25
26fn main() {
27 let mut ran_drop = false;
28 {
29 let x = Foo(&mut ran_drop);
30 let x = move || { let _ = x; };
31 f(x);
32 }
33 assert!(ran_drop);
34
35 let mut ran_drop = false;
36 {
37 let x = Foo(&mut ran_drop);
38 let result = panic::catch_unwind(move || {
39 let x = move || { let _ = x; panic!() };
40 f(x);
41 });
42 assert!(result.is_err());
43 }
44 assert!(ran_drop);
45}
tests/ui/drop/panic-during-slice-init.rs created+27
......@@ -0,0 +1,27 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/30018>.
2//! This is very similar to the original reported test, except that the
3//! panic is wrapped in a spawned thread to isolate the expected error
4//! result from the SIGTRAP injected by the drop-flag consistency checking.
5
6//@ run-pass
7//@ needs-unwind
8//@ needs-threads
9//@ ignore-backends: gcc
10
11struct Foo;
12
13impl Drop for Foo {
14 fn drop(&mut self) {}
15}
16
17fn foo() -> Foo {
18 panic!();
19}
20
21fn main() {
22 use std::thread;
23 let handle = thread::spawn(|| {
24 let _ = &[foo()];
25 });
26 let _ = handle.join();
27}
tests/ui/drop/repeat-drop.rs+1-1
......@@ -3,7 +3,7 @@
33
44#![allow(dropping_references, dropping_copy_types)]
55
6// FIXME(static_mut_refs): this could use an atomic
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99static mut CHECK: usize = 0;
tests/ui/drop/same-alloca-reassigned-match-binding-16151.rs+1-1
......@@ -2,7 +2,7 @@
22
33//@ run-pass
44
5// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
5// FIXME(static_mut_refs): use raw pointers instead of references
66#![allow(static_mut_refs)]
77
88use std::mem;
tests/ui/drop/static-issue-17302.rs+1-1
......@@ -1,6 +1,6 @@
11//@ run-pass
22
3// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
3// FIXME(static_mut_refs): use raw pointers instead of references
44#![allow(static_mut_refs)]
55
66static mut DROPPED: [bool; 2] = [false, false];
tests/ui/dst/tuple-with-unsized-tail-field.rs created+13
......@@ -0,0 +1,13 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/33241>
2//@ check-pass
3
4use std::fmt;
5
6// CoerceUnsized is not implemented for tuples. You can still create
7// an unsized tuple by transmuting a trait object.
8fn any<T>() -> T { unreachable!() }
9
10fn main() {
11 let t: &(u8, dyn fmt::Debug) = any();
12 println!("{:?}", &t.1);
13}
tests/ui/enum/unsized-field-in-enum-variant.rs created+7
......@@ -0,0 +1,7 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/35988>
2enum E {
3 V([Box<E>]),
4 //~^ ERROR the size for values of type
5}
6
7fn main() {}
tests/ui/enum/unsized-field-in-enum-variant.stderr created+21
......@@ -0,0 +1,21 @@
1error[E0277]: the size for values of type `[Box<E>]` cannot be known at compilation time
2 --> $DIR/unsized-field-in-enum-variant.rs:3:7
3 |
4LL | V([Box<E>]),
5 | ^^^^^^^^ doesn't have a size known at compile-time
6 |
7 = help: the trait `Sized` is not implemented for `[Box<E>]`
8 = note: no field of an enum variant may have a dynamically sized type
9 = help: change the field's type to have a statically known size
10help: borrowed types always have a statically known size
11 |
12LL | V(&[Box<E>]),
13 | +
14help: the `Box` type always has a statically known size and allocates its contents in the heap
15 |
16LL | V(Box<[Box<E>]>),
17 | ++++ +
18
19error: aborting due to 1 previous error
20
21For more information about this error, try `rustc --explain E0277`.
tests/ui/error-emitter/multibyte-char-in-diagnostic-source-line.rs created+5
......@@ -0,0 +1,5 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/44023>
2pub fn main () {}
3
4fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types
5}
tests/ui/error-emitter/multibyte-char-in-diagnostic-source-line.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0308]: mismatched types
2 --> $DIR/multibyte-char-in-diagnostic-source-line.rs:4:36
3 |
4LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize {
5 | ------------------------ ^^^^^ expected `isize`, found `()`
6 | |
7 | implicitly returns `()` as its body has no tail or `return` expression
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0308`.
tests/ui/feature-gates/auxiliary/unstable-crate-import-gated-in-2018-edition.rs created+4
......@@ -0,0 +1,4 @@
1//! Auxiliary crate for regression test of <https://github.com/rust-lang/rust/issues/52489>
2#![crate_type = "lib"]
3#![unstable(feature = "unstable_crate_import_gated_in_2018_edition", issue = "none")]
4#![feature(staged_api)]
tests/ui/feature-gates/feature-gate-cfg-target-has-threads.rs created+5
......@@ -0,0 +1,5 @@
1#[cfg(target_has_threads)]
2//~^ ERROR `cfg(target_has_threads)` is experimental and subject to change
3fn bar() {}
4
5fn main() {}
tests/ui/feature-gates/feature-gate-cfg-target-has-threads.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0658]: `cfg(target_has_threads)` is experimental and subject to change
2 --> $DIR/feature-gate-cfg-target-has-threads.rs:1:7
3 |
4LL | #[cfg(target_has_threads)]
5 | ^^^^^^^^^^^^^^^^^^
6 |
7 = help: add `#![feature(cfg_target_has_threads)]` to the crate attributes to enable
8 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0658`.
tests/ui/feature-gates/unstable-crate-import-gated-in-2018-edition.rs created+9
......@@ -0,0 +1,9 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/52489>
2//@ edition:2018
3//@ aux-build:unstable-crate-import-gated-in-2018-edition.rs
4//@ compile-flags: --extern unstable_crate_import_gated_in_2018_edition
5
6use unstable_crate_import_gated_in_2018_edition;
7//~^ ERROR use of unstable library feature `unstable_crate_import_gated_in_2018_edition`
8
9fn main() {}
tests/ui/feature-gates/unstable-crate-import-gated-in-2018-edition.stderr created+12
......@@ -0,0 +1,12 @@
1error[E0658]: use of unstable library feature `unstable_crate_import_gated_in_2018_edition`
2 --> $DIR/unstable-crate-import-gated-in-2018-edition.rs:6:5
3 |
4LL | use unstable_crate_import_gated_in_2018_edition;
5 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 |
7 = help: add `#![feature(unstable_crate_import_gated_in_2018_edition)]` to the crate attributes to enable
8 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0658`.
tests/ui/fmt/format-enum-with-recursive-variant.rs created+37
......@@ -0,0 +1,37 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/3556>
2//@ run-pass
3#![allow(dead_code)]
4
5#[derive(Debug)]
6enum Token {
7 Text(String),
8 ETag(Vec<String>, String),
9 UTag(Vec<String>, String),
10 Section(Vec<String>, bool, Vec<Token>, String,
11 String, String, String, String),
12 IncompleteSection(Vec<String>, bool, String, bool),
13 Partial(String, String, String),
14}
15
16fn check_strs(actual: &str, expected: &str) -> bool
17{
18 if actual != expected
19 {
20 println!("Found {}, but expected {}", actual, expected);
21 return false;
22 }
23 return true;
24}
25
26pub fn main()
27{
28 let t = Token::Text("foo".to_string());
29 let u = Token::Section(vec!["alpha".to_string()],
30 true,
31 vec![t],
32 "foo".to_string(),
33 "foo".to_string(), "foo".to_string(), "foo".to_string(),
34 "foo".to_string());
35 let v = format!("{:?}", u); // this is the line that causes the seg fault
36 assert!(!v.is_empty());
37}
tests/ui/fn_traits/fn-trait-ufcs-call-in-impl.rs created+15
......@@ -0,0 +1,15 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/43431>
2#![feature(fn_traits)]
3
4trait CallSingle<A, B> {
5 fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B;
6}
7
8impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
9 fn call(&self, a: A) -> B {
10 <Self as Fn(A) -> B>::call(self, (a,))
11 //~^ ERROR associated item constraints are not allowed here
12 }
13}
14
15fn main() {}
tests/ui/fn_traits/fn-trait-ufcs-call-in-impl.stderr created+9
......@@ -0,0 +1,9 @@
1error[E0229]: associated item constraints are not allowed here
2 --> $DIR/fn-trait-ufcs-call-in-impl.rs:10:27
3 |
4LL | <Self as Fn(A) -> B>::call(self, (a,))
5 | ^ associated item constraint not allowed here
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0229`.
tests/ui/fn_traits/overloaded-fnonce-resolution.rs created+33
......@@ -0,0 +1,33 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/45510>
2// Test overloaded resolution of fn_traits.
3//@ run-pass
4
5#![feature(fn_traits)]
6#![feature(unboxed_closures)]
7
8#[derive(Debug, PartialEq, Eq)]
9struct Ishmael;
10#[derive(Debug, PartialEq, Eq)]
11struct Maybe;
12struct CallMe;
13
14impl FnOnce<(Ishmael,)> for CallMe {
15 type Output = Ishmael;
16 extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> Ishmael {
17 println!("Split your lungs with blood and thunder!");
18 Ishmael
19 }
20}
21
22impl FnOnce<(Maybe,)> for CallMe {
23 type Output = Maybe;
24 extern "rust-call" fn call_once(self, _args: (Maybe,)) -> Maybe {
25 println!("So we just met, and this is crazy");
26 Maybe
27 }
28}
29
30fn main() {
31 assert_eq!(CallMe(Ishmael), Ishmael);
32 assert_eq!(CallMe(Maybe), Maybe);
33}
tests/ui/fn_traits/parenthesized-fn-trait-in-qualified-path.rs created+7
......@@ -0,0 +1,7 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/39687>
2#![feature(fn_traits)]
3
4fn main() {
5 <fn() as Fn()>::call;
6 //~^ ERROR associated item constraints are not allowed here [E0229]
7}
tests/ui/fn_traits/parenthesized-fn-trait-in-qualified-path.stderr created+9
......@@ -0,0 +1,9 @@
1error[E0229]: associated item constraints are not allowed here
2 --> $DIR/parenthesized-fn-trait-in-qualified-path.rs:5:14
3 |
4LL | <fn() as Fn()>::call;
5 | ^^^^ associated item constraint not allowed here
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0229`.
tests/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs+1-1
......@@ -2,7 +2,7 @@
22// This test verifies that temporaries created for `while`'s and `if`
33// conditions are dropped after the condition is evaluated.
44
5// FIXME(static_mut_refs): this could use an atomic
5// FIXME(static_mut_refs): use raw pointers instead of references
66#![allow(static_mut_refs)]
77
88struct Temporary;
tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs+1-1
......@@ -3,7 +3,7 @@
33// The `foo` module attempts to maintains an invariant that each `S`
44// has a unique `u64` id.
55
6// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99use self::foo::S;
tests/ui/issues/auxiliary/issue-52489.rs deleted-3
......@@ -1,3 +0,0 @@
1#![crate_type = "lib"]
2#![unstable(feature = "issue_52489_unstable", issue = "none")]
3#![feature(staged_api)]
tests/ui/issues/issue-29668.rs deleted-16
......@@ -1,16 +0,0 @@
1//@ run-pass
2// Functions can return unnameable types
3
4mod m1 {
5 mod m2 {
6 #[derive(Debug)]
7 pub struct A;
8 }
9 use self::m2::A;
10 pub fn x() -> A { A }
11}
12
13fn main() {
14 let x = m1::x();
15 println!("{:?}", x);
16}
tests/ui/issues/issue-29743.rs deleted-7
......@@ -1,7 +0,0 @@
1//@ check-pass
2
3fn main() {
4 let mut i = [1, 2, 3];
5 i[i[0]] = 0;
6 i[i[0] - 1] = 0;
7}
tests/ui/issues/issue-29861.rs deleted-21
......@@ -1,21 +0,0 @@
1pub trait MakeRef<'a> {
2 type Ref;
3}
4impl<'a, T: 'a> MakeRef<'a> for T {
5 type Ref = &'a T;
6}
7
8pub trait MakeRef2 {
9 type Ref2;
10}
11impl<'a, T: 'a> MakeRef2 for T {
12//~^ ERROR the lifetime parameter `'a` is not constrained
13 type Ref2 = <T as MakeRef<'a>>::Ref;
14}
15
16fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") }
17//~^ ERROR temporary value dropped while borrowed
18
19fn main() {
20 println!("{}", foo());
21}
tests/ui/issues/issue-29861.stderr deleted-21
......@@ -1,21 +0,0 @@
1error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
2 --> $DIR/issue-29861.rs:11:6
3 |
4LL | impl<'a, T: 'a> MakeRef2 for T {
5 | ^^ unconstrained lifetime parameter
6
7error[E0716]: temporary value dropped while borrowed
8 --> $DIR/issue-29861.rs:16:43
9 |
10LL | fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") }
11 | ^^^^^^^^^^^^^^^^^^^ -- borrow later used here
12 | | |
13 | | temporary value is freed at the end of this statement
14 | creates a temporary value which is freed while still in use
15 |
16 = note: consider using a `let` binding to create a longer lived value
17
18error: aborting due to 2 previous errors
19
20Some errors have detailed explanations: E0207, E0716.
21For more information about an error, try `rustc --explain E0207`.
tests/ui/issues/issue-2989.rs deleted-36
......@@ -1,36 +0,0 @@
1//@ run-pass
2#![allow(non_camel_case_types)]
3
4trait methods { //~ WARN trait `methods` is never used
5 fn to_bytes(&self) -> Vec<u8>;
6}
7
8impl methods for () {
9 fn to_bytes(&self) -> Vec<u8> {
10 Vec::new()
11 }
12}
13
14// the position of this function is significant! - if it comes before methods
15// then it works, if it comes after it then it doesn't!
16fn to_bools(bitv: Storage) -> Vec<bool> {
17 (0..8).map(|i| {
18 let w = i / 64;
19 let b = i % 64;
20 let x = 1 & (bitv.storage[w] >> b);
21 x == 1
22 }).collect()
23}
24
25struct Storage { storage: Vec<u64> }
26
27pub fn main() {
28 let bools = vec![false, false, true, false, false, true, true, false];
29 let bools2 = to_bools(Storage{storage: vec![0b01100100]});
30
31 for i in 0..8 {
32 println!("{} => {} vs {}", i, bools[i], bools2[i]);
33 }
34
35 assert_eq!(bools, bools2);
36}
tests/ui/issues/issue-2989.stderr deleted-10
......@@ -1,10 +0,0 @@
1warning: trait `methods` is never used
2 --> $DIR/issue-2989.rs:4:7
3 |
4LL | trait methods {
5 | ^^^^^^^
6 |
7 = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
8
9warning: 1 warning emitted
10
tests/ui/issues/issue-29948.rs deleted-41
......@@ -1,41 +0,0 @@
1//@ run-pass
2//@ needs-unwind
3//@ ignore-backends: gcc
4
5use std::panic;
6
7impl<'a> panic::UnwindSafe for Foo<'a> {}
8impl<'a> panic::RefUnwindSafe for Foo<'a> {}
9
10struct Foo<'a>(&'a mut bool);
11
12impl<'a> Drop for Foo<'a> {
13 fn drop(&mut self) {
14 *self.0 = true;
15 }
16}
17
18fn f<T: FnOnce()>(t: T) {
19 t()
20}
21
22fn main() {
23 let mut ran_drop = false;
24 {
25 let x = Foo(&mut ran_drop);
26 let x = move || { let _ = x; };
27 f(x);
28 }
29 assert!(ran_drop);
30
31 let mut ran_drop = false;
32 {
33 let x = Foo(&mut ran_drop);
34 let result = panic::catch_unwind(move || {
35 let x = move || { let _ = x; panic!() };
36 f(x);
37 });
38 assert!(result.is_err());
39 }
40 assert!(ran_drop);
41}
tests/ui/issues/issue-30018-panic.rs deleted-27
......@@ -1,27 +0,0 @@
1//@ run-pass
2// Regression test for Issue #30018. This is very similar to the
3// original reported test, except that the panic is wrapped in a
4// spawned thread to isolate the expected error result from the
5// SIGTRAP injected by the drop-flag consistency checking.
6
7//@ needs-unwind
8//@ needs-threads
9//@ ignore-backends: gcc
10
11struct Foo;
12
13impl Drop for Foo {
14 fn drop(&mut self) {}
15}
16
17fn foo() -> Foo {
18 panic!();
19}
20
21fn main() {
22 use std::thread;
23 let handle = thread::spawn(|| {
24 let _ = &[foo()];
25 });
26 let _ = handle.join();
27}
tests/ui/issues/issue-30081.rs deleted-15
......@@ -1,15 +0,0 @@
1//@ run-pass
2// This used to segfault #30081
3
4pub enum Instruction {
5 Increment(i8),
6 Loop(Box<Box<()>>),
7}
8
9fn main() {
10 let instrs: Option<(u8, Box<Instruction>)> = None;
11 instrs.into_iter()
12 .map(|(_, instr)| instr)
13 .map(|instr| match *instr { _other => {} })
14 .last();
15}
tests/ui/issues/issue-3021-b.rs deleted-14
......@@ -1,14 +0,0 @@
1fn siphash(k0 : u64) {
2
3 struct SipHash {
4 v0: u64,
5 }
6
7 impl SipHash {
8 pub fn reset(&mut self) {
9 self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
10 }
11 }
12}
13
14fn main() {}
tests/ui/issues/issue-3021-b.stderr deleted-11
......@@ -1,11 +0,0 @@
1error[E0434]: can't capture dynamic environment in a fn item
2 --> $DIR/issue-3021-b.rs:9:22
3 |
4LL | self.v0 = k0 ^ 0x736f6d6570736575;
5 | ^^
6 |
7 = help: use the `|| { ... }` closure form instead
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0434`.
tests/ui/issues/issue-3021-d.rs deleted-28
......@@ -1,28 +0,0 @@
1trait SipHash {
2 fn result(&self) -> u64;
3 fn reset(&self);
4}
5
6fn siphash(k0 : u64, k1 : u64) {
7 struct SipState {
8 v0: u64,
9 v1: u64,
10 }
11
12 fn mk_result(st : &SipState) -> u64 {
13
14 let v0 = st.v0;
15 let v1 = st.v1;
16 return v0 ^ v1;
17 }
18
19 impl SipHash for SipState {
20 fn reset(&self) {
21 self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
22 self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR can't capture dynamic environment
23 }
24 fn result(&self) -> u64 { return mk_result(self); }
25 }
26}
27
28fn main() {}
tests/ui/issues/issue-3021-d.stderr deleted-19
......@@ -1,19 +0,0 @@
1error[E0434]: can't capture dynamic environment in a fn item
2 --> $DIR/issue-3021-d.rs:21:23
3 |
4LL | self.v0 = k0 ^ 0x736f6d6570736575;
5 | ^^
6 |
7 = help: use the `|| { ... }` closure form instead
8
9error[E0434]: can't capture dynamic environment in a fn item
10 --> $DIR/issue-3021-d.rs:22:23
11 |
12LL | self.v1 = k1 ^ 0x646f72616e646f6d;
13 | ^^
14 |
15 = help: use the `|| { ... }` closure form instead
16
17error: aborting due to 2 previous errors
18
19For more information about this error, try `rustc --explain E0434`.
tests/ui/issues/issue-33241.rs deleted-12
......@@ -1,12 +0,0 @@
1//@ check-pass
2
3use std::fmt;
4
5// CoerceUnsized is not implemented for tuples. You can still create
6// an unsized tuple by transmuting a trait object.
7fn any<T>() -> T { unreachable!() }
8
9fn main() {
10 let t: &(u8, dyn fmt::Debug) = any();
11 println!("{:?}", &t.1);
12}
tests/ui/issues/issue-3556.rs deleted-36
......@@ -1,36 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3
4#[derive(Debug)]
5enum Token {
6 Text(String),
7 ETag(Vec<String>, String),
8 UTag(Vec<String>, String),
9 Section(Vec<String>, bool, Vec<Token>, String,
10 String, String, String, String),
11 IncompleteSection(Vec<String>, bool, String, bool),
12 Partial(String, String, String),
13}
14
15fn check_strs(actual: &str, expected: &str) -> bool
16{
17 if actual != expected
18 {
19 println!("Found {}, but expected {}", actual, expected);
20 return false;
21 }
22 return true;
23}
24
25pub fn main()
26{
27 let t = Token::Text("foo".to_string());
28 let u = Token::Section(vec!["alpha".to_string()],
29 true,
30 vec![t],
31 "foo".to_string(),
32 "foo".to_string(), "foo".to_string(), "foo".to_string(),
33 "foo".to_string());
34 let v = format!("{:?}", u); // this is the line that causes the seg fault
35 assert!(!v.is_empty());
36}
tests/ui/issues/issue-35988.rs deleted-6
......@@ -1,6 +0,0 @@
1enum E {
2 V([Box<E>]),
3 //~^ ERROR the size for values of type
4}
5
6fn main() {}
tests/ui/issues/issue-35988.stderr deleted-21
......@@ -1,21 +0,0 @@
1error[E0277]: the size for values of type `[Box<E>]` cannot be known at compilation time
2 --> $DIR/issue-35988.rs:2:7
3 |
4LL | V([Box<E>]),
5 | ^^^^^^^^ doesn't have a size known at compile-time
6 |
7 = help: the trait `Sized` is not implemented for `[Box<E>]`
8 = note: no field of an enum variant may have a dynamically sized type
9 = help: change the field's type to have a statically known size
10help: borrowed types always have a statically known size
11 |
12LL | V(&[Box<E>]),
13 | +
14help: the `Box` type always has a statically known size and allocates its contents in the heap
15 |
16LL | V(Box<[Box<E>]>),
17 | ++++ +
18
19error: aborting due to 1 previous error
20
21For more information about this error, try `rustc --explain E0277`.
tests/ui/issues/issue-37733.rs deleted-7
......@@ -1,7 +0,0 @@
1//@ build-pass
2#![allow(dead_code)]
3type A = for<> fn();
4
5type B = for<'a,> fn();
6
7pub fn main() {}
tests/ui/issues/issue-39687.rs deleted-6
......@@ -1,6 +0,0 @@
1#![feature(fn_traits)]
2
3fn main() {
4 <fn() as Fn()>::call;
5 //~^ ERROR associated item constraints are not allowed here [E0229]
6}
tests/ui/issues/issue-39687.stderr deleted-9
......@@ -1,9 +0,0 @@
1error[E0229]: associated item constraints are not allowed here
2 --> $DIR/issue-39687.rs:4:14
3 |
4LL | <fn() as Fn()>::call;
5 | ^^^^ associated item constraint not allowed here
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0229`.
tests/ui/issues/issue-43431.rs deleted-14
......@@ -1,14 +0,0 @@
1#![feature(fn_traits)]
2
3trait CallSingle<A, B> {
4 fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B;
5}
6
7impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
8 fn call(&self, a: A) -> B {
9 <Self as Fn(A) -> B>::call(self, (a,))
10 //~^ ERROR associated item constraints are not allowed here
11 }
12}
13
14fn main() {}
tests/ui/issues/issue-43431.stderr deleted-9
......@@ -1,9 +0,0 @@
1error[E0229]: associated item constraints are not allowed here
2 --> $DIR/issue-43431.rs:9:27
3 |
4LL | <Self as Fn(A) -> B>::call(self, (a,))
5 | ^ associated item constraint not allowed here
6
7error: aborting due to 1 previous error
8
9For more information about this error, try `rustc --explain E0229`.
tests/ui/issues/issue-43923.rs deleted-12
......@@ -1,12 +0,0 @@
1//@ run-pass
2#![allow(dead_code)]
3#![allow(unused_variables)]
4struct A<T: ?Sized> { ptr: T }
5
6fn foo<T>(x: &A<[T]>) {}
7
8fn main() {
9 let a = foo;
10 let b = A { ptr: [a, a, a] };
11 a(&A { ptr: [()] });
12}
tests/ui/issues/issue-44023.rs deleted-4
......@@ -1,4 +0,0 @@
1pub fn main () {}
2
3fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types
4}
tests/ui/issues/issue-44023.stderr deleted-11
......@@ -1,11 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/issue-44023.rs:3:36
3 |
4LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize {
5 | ------------------------ ^^^^^ expected `isize`, found `()`
6 | |
7 | implicitly returns `()` as its body has no tail or `return` expression
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0308`.
tests/ui/issues/issue-45510.rs deleted-32
......@@ -1,32 +0,0 @@
1// Test overloaded resolution of fn_traits.
2//@ run-pass
3
4#![feature(fn_traits)]
5#![feature(unboxed_closures)]
6
7#[derive(Debug, PartialEq, Eq)]
8struct Ishmael;
9#[derive(Debug, PartialEq, Eq)]
10struct Maybe;
11struct CallMe;
12
13impl FnOnce<(Ishmael,)> for CallMe {
14 type Output = Ishmael;
15 extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> Ishmael {
16 println!("Split your lungs with blood and thunder!");
17 Ishmael
18 }
19}
20
21impl FnOnce<(Maybe,)> for CallMe {
22 type Output = Maybe;
23 extern "rust-call" fn call_once(self, _args: (Maybe,)) -> Maybe {
24 println!("So we just met, and this is crazy");
25 Maybe
26 }
27}
28
29fn main() {
30 assert_eq!(CallMe(Ishmael), Ishmael);
31 assert_eq!(CallMe(Maybe), Maybe);
32}
tests/ui/issues/issue-52489.rs deleted-8
......@@ -1,8 +0,0 @@
1//@ edition:2018
2//@ aux-build:issue-52489.rs
3//@ compile-flags:--extern issue_52489
4
5use issue_52489;
6//~^ ERROR use of unstable library feature `issue_52489_unstable`
7
8fn main() {}
tests/ui/issues/issue-52489.stderr deleted-12
......@@ -1,12 +0,0 @@
1error[E0658]: use of unstable library feature `issue_52489_unstable`
2 --> $DIR/issue-52489.rs:5:5
3 |
4LL | use issue_52489;
5 | ^^^^^^^^^^^
6 |
7 = help: add `#![feature(issue_52489_unstable)]` to the crate attributes to enable
8 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
9
10error: aborting due to 1 previous error
11
12For more information about this error, try `rustc --explain E0658`.
tests/ui/linkage-attr/link-section-placement.rs+1-1
......@@ -3,7 +3,7 @@
33//@ run-pass
44
55#![feature(cfg_target_object_format)]
6// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88#![allow(non_upper_case_globals)]
99
tests/ui/linkage-attr/linkage-attr-mutable-static.rs+1-1
......@@ -2,7 +2,7 @@
22//! them at runtime, so deny mutable statics with #[linkage].
33
44#![feature(linkage)]
5// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
5// FIXME(static_mut_refs): use raw pointers instead of references
66#![allow(static_mut_refs)]
77
88fn main() {
tests/ui/lto/lto-still-runs-thread-dtors.rs+1-1
......@@ -4,7 +4,7 @@
44//@ needs-threads
55//@ ignore-backends: gcc
66
7// FIXME(static_mut_refs): this could use an atomic
7// FIXME(static_mut_refs): use raw pointers instead of references
88#![allow(static_mut_refs)]
99
1010use std::thread;
tests/ui/macros/cfg.stderr+1-1
......@@ -46,7 +46,7 @@ warning: unexpected `cfg` condition name: `foo`
4646LL | cfg!(foo);
4747 | ^^^
4848 |
49 = help: expected names are: `FALSE` and `test` and 32 more
49 = help: expected names are: `FALSE` and `test` and 33 more
5050 = help: to expect this configuration use `--check-cfg=cfg(foo)`
5151 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
5252 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/macros/cfg_select.stderr+1-1
......@@ -169,7 +169,7 @@ warning: unexpected `cfg` condition name: `a`
169169LL | a + 1 => {}
170170 | ^ help: found config with similar value: `target_feature = "a"`
171171 |
172 = help: expected names are: `FALSE` and `test` and 32 more
172 = help: expected names are: `FALSE` and `test` and 33 more
173173 = help: to expect this configuration use `--check-cfg=cfg(a)`
174174 = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
175175 = note: `#[warn(unexpected_cfgs)]` on by default
tests/ui/methods/method-self-arg-trait.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22// Test method calls with self as an argument
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77static mut COUNT: u64 = 1;
tests/ui/methods/method-self-arg.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22// Test method calls with self as an argument
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77static mut COUNT: usize = 1;
tests/ui/mir/mir_early_return_scope.rs+1-1
......@@ -1,6 +1,6 @@
11//@ run-pass
22#![allow(unused_variables)]
3// FIXME(static_mut_refs): this could use an atomic
3// FIXME(static_mut_refs): use raw pointers instead of references
44#![allow(static_mut_refs)]
55static mut DROP: bool = false;
66
tests/ui/nll/issue-69114-static-mut-ty.rs+1-1
......@@ -1,6 +1,6 @@
11// Check that borrowck ensures that `static mut` items have the expected type.
22
3// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
3// FIXME(static_mut_refs): use raw pointers instead of references
44#![allow(static_mut_refs)]
55
66static FOO: u8 = 42;
tests/ui/numbers-arithmetic/shift-near-oflo.rs+1-1
......@@ -1,7 +1,7 @@
11//@ run-pass
22//@ compile-flags: -C debug-assertions
33
4// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
4// FIXME(static_mut_refs): use raw pointers instead of references
55#![allow(static_mut_refs)]
66
77// Check that we do *not* overflow on a number of edge cases.
tests/ui/parser/accept-lifetime-list-empty-or-trailing-comma.rs created+8
......@@ -0,0 +1,8 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/37733>
2//@ build-pass
3#![allow(dead_code)]
4type A = for<> fn();
5
6type B = for<'a,> fn();
7
8pub fn main() {}
tests/ui/privacy/fn-returns-unnameable-type.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/29668>.
2//! Test functions can return unnameable types.
3//@ run-pass
4
5mod m1 {
6 mod m2 {
7 #[derive(Debug)]
8 pub struct A;
9 }
10 use self::m2::A;
11 pub fn x() -> A { A }
12}
13
14fn main() {
15 let x = m1::x();
16 println!("{:?}", x);
17}
tests/ui/resolve/impl-method-cant-capture-env.rs created+17
......@@ -0,0 +1,17 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/3021>.
2//! Ensure upvars from fn cannot be used in impl method block body.
3
4fn siphash(k0 : u64) {
5
6 struct SipHash {
7 v0: u64,
8 }
9
10 impl SipHash {
11 pub fn reset(&mut self) {
12 self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
13 }
14 }
15}
16
17fn main() {}
tests/ui/resolve/impl-method-cant-capture-env.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0434]: can't capture dynamic environment in a fn item
2 --> $DIR/impl-method-cant-capture-env.rs:12:22
3 |
4LL | self.v0 = k0 ^ 0x736f6d6570736575;
5 | ^^
6 |
7 = help: use the `|| { ... }` closure form instead
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0434`.
tests/ui/resolve/impl-trait-for-type-cant-capture-env.rs created+21
......@@ -0,0 +1,21 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/3021>.
2//! Test accessing upvars in impl trait for type method is forbidden.
3
4trait SipHash {
5 fn reset(&self);
6}
7
8fn siphash(k0 : u64) {
9 struct SipState {
10 v0: u64,
11 }
12
13 impl SipHash for SipState {
14 fn reset(&self) {
15 self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
16 }
17 }
18 panic!();
19}
20
21fn main() {}
tests/ui/resolve/impl-trait-for-type-cant-capture-env.stderr created+11
......@@ -0,0 +1,11 @@
1error[E0434]: can't capture dynamic environment in a fn item
2 --> $DIR/impl-trait-for-type-cant-capture-env.rs:15:22
3 |
4LL | self.v0 = k0 ^ 0x736f6d6570736575;
5 | ^^
6 |
7 = help: use the `|| { ... }` closure form instead
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0434`.
tests/ui/resolve/issue-3021-c.rs deleted-9
......@@ -1,9 +0,0 @@
1fn siphash<T>() {
2
3 trait U {
4 fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer item
5 //~^ ERROR can't use generic parameters from outer item
6 }
7}
8
9fn main() {}
tests/ui/resolve/issue-3021-c.stderr deleted-37
......@@ -1,37 +0,0 @@
1error[E0401]: can't use generic parameters from outer item
2 --> $DIR/issue-3021-c.rs:4:24
3 |
4LL | fn siphash<T>() {
5 | - type parameter from outer item
6LL |
7LL | trait U {
8 | - generic parameter used in this inner trait
9LL | fn g(&self, x: T) -> T;
10 | ^ use of generic parameter from outer item
11 |
12 = note: nested items are independent from their parent item for everything except for privacy and name resolution
13help: try introducing a local generic parameter here
14 |
15LL | trait U<T> {
16 | +++
17
18error[E0401]: can't use generic parameters from outer item
19 --> $DIR/issue-3021-c.rs:4:30
20 |
21LL | fn siphash<T>() {
22 | - type parameter from outer item
23LL |
24LL | trait U {
25 | - generic parameter used in this inner trait
26LL | fn g(&self, x: T) -> T;
27 | ^ use of generic parameter from outer item
28 |
29 = note: nested items are independent from their parent item for everything except for privacy and name resolution
30help: try introducing a local generic parameter here
31 |
32LL | trait U<T> {
33 | +++
34
35error: aborting due to 2 previous errors
36
37For more information about this error, try `rustc --explain E0401`.
tests/ui/resolve/issue-3021.rs deleted-18
......@@ -1,18 +0,0 @@
1trait SipHash {
2 fn reset(&self);
3}
4
5fn siphash(k0 : u64) {
6 struct SipState {
7 v0: u64,
8 }
9
10 impl SipHash for SipState {
11 fn reset(&self) {
12 self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
13 }
14 }
15 panic!();
16}
17
18fn main() {}
tests/ui/resolve/issue-3021.stderr deleted-11
......@@ -1,11 +0,0 @@
1error[E0434]: can't capture dynamic environment in a fn item
2 --> $DIR/issue-3021.rs:12:22
3 |
4LL | self.v0 = k0 ^ 0x736f6d6570736575;
5 | ^^
6 |
7 = help: use the `|| { ... }` closure form instead
8
9error: aborting due to 1 previous error
10
11For more information about this error, try `rustc --explain E0434`.
tests/ui/resolve/outer-generic-in-trait-method.rs created+12
......@@ -0,0 +1,12 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/3021>.
2//! Test we can't use outer generic param in trait method defined in fn body.
3
4fn siphash<T>() {
5
6 trait U {
7 fn g(&self, x: T) -> T; //~ ERROR can't use generic parameters from outer item
8 //~^ ERROR can't use generic parameters from outer item
9 }
10}
11
12fn main() {}
tests/ui/resolve/outer-generic-in-trait-method.stderr created+37
......@@ -0,0 +1,37 @@
1error[E0401]: can't use generic parameters from outer item
2 --> $DIR/outer-generic-in-trait-method.rs:7:24
3 |
4LL | fn siphash<T>() {
5 | - type parameter from outer item
6LL |
7LL | trait U {
8 | - generic parameter used in this inner trait
9LL | fn g(&self, x: T) -> T;
10 | ^ use of generic parameter from outer item
11 |
12 = note: nested items are independent from their parent item for everything except for privacy and name resolution
13help: try introducing a local generic parameter here
14 |
15LL | trait U<T> {
16 | +++
17
18error[E0401]: can't use generic parameters from outer item
19 --> $DIR/outer-generic-in-trait-method.rs:7:30
20 |
21LL | fn siphash<T>() {
22 | - type parameter from outer item
23LL |
24LL | trait U {
25 | - generic parameter used in this inner trait
26LL | fn g(&self, x: T) -> T;
27 | ^ use of generic parameter from outer item
28 |
29 = note: nested items are independent from their parent item for everything except for privacy and name resolution
30help: try introducing a local generic parameter here
31 |
32LL | trait U<T> {
33 | +++
34
35error: aborting due to 2 previous errors
36
37For more information about this error, try `rustc --explain E0401`.
tests/ui/resolve/trait-impl-cant-capture-env.rs created+31
......@@ -0,0 +1,31 @@
1//! Regression test for <https://github.com/rust-lang/rust/issues/3021>.
2//! Ensure upvars from fn cannot be used in impl method block body.
3
4trait SipHash {
5 fn result(&self) -> u64;
6 fn reset(&self);
7}
8
9fn siphash(k0 : u64, k1 : u64) {
10 struct SipState {
11 v0: u64,
12 v1: u64,
13 }
14
15 fn mk_result(st : &SipState) -> u64 {
16
17 let v0 = st.v0;
18 let v1 = st.v1;
19 return v0 ^ v1;
20 }
21
22 impl SipHash for SipState {
23 fn reset(&self) {
24 self.v0 = k0 ^ 0x736f6d6570736575; //~ ERROR can't capture dynamic environment
25 self.v1 = k1 ^ 0x646f72616e646f6d; //~ ERROR can't capture dynamic environment
26 }
27 fn result(&self) -> u64 { return mk_result(self); }
28 }
29}
30
31fn main() {}
tests/ui/resolve/trait-impl-cant-capture-env.stderr created+19
......@@ -0,0 +1,19 @@
1error[E0434]: can't capture dynamic environment in a fn item
2 --> $DIR/trait-impl-cant-capture-env.rs:24:23
3 |
4LL | self.v0 = k0 ^ 0x736f6d6570736575;
5 | ^^
6 |
7 = help: use the `|| { ... }` closure form instead
8
9error[E0434]: can't capture dynamic environment in a fn item
10 --> $DIR/trait-impl-cant-capture-env.rs:25:23
11 |
12LL | self.v1 = k1 ^ 0x646f72616e646f6d;
13 | ^^
14 |
15 = help: use the `|| { ... }` closure form instead
16
17error: aborting due to 2 previous errors
18
19For more information about this error, try `rustc --explain E0434`.
tests/ui/self/where-for-self.rs+1-1
......@@ -2,7 +2,7 @@
22// Test that we can quantify lifetimes outside a constraint (i.e., including
33// the self type) in a where clause.
44
5// FIXME(static_mut_refs): this could use an atomic
5// FIXME(static_mut_refs): use raw pointers instead of references
66#![allow(static_mut_refs)]
77
88static mut COUNT: u32 = 1;
tests/ui/stats/input-stats.stderr+4-4
......@@ -27,7 +27,7 @@ ast-stats Pat 560 (NN.N%) 7 80
2727ast-stats - Struct 80 (NN.N%) 1
2828ast-stats - Wild 80 (NN.N%) 1
2929ast-stats - Ident 400 (NN.N%) 5
30ast-stats GenericParam 480 (NN.N%) 5 96
30ast-stats GenericParam 400 (NN.N%) 5 80
3131ast-stats GenericBound 352 (NN.N%) 4 88
3232ast-stats - Trait 352 (NN.N%) 4
3333ast-stats AssocItem 320 (NN.N%) 4 80
......@@ -50,14 +50,14 @@ ast-stats Local 96 (NN.N%) 1 96
5050ast-stats Arm 96 (NN.N%) 2 48
5151ast-stats ForeignItem 80 (NN.N%) 1 80
5252ast-stats - Fn 80 (NN.N%) 1
53ast-stats WherePredicate 72 (NN.N%) 1 72
54ast-stats - BoundPredicate 72 (NN.N%) 1
53ast-stats WherePredicate 56 (NN.N%) 1 56
54ast-stats - BoundPredicate 56 (NN.N%) 1
5555ast-stats ExprField 48 (NN.N%) 1 48
5656ast-stats GenericArgs 40 (NN.N%) 1 40
5757ast-stats - AngleBracketed 40 (NN.N%) 1
5858ast-stats Crate 40 (NN.N%) 1 40
5959ast-stats ----------------------------------------------------------------
60ast-stats Total 7_624 127
60ast-stats Total 7_528 127
6161ast-stats ================================================================
6262hir-stats ================================================================
6363hir-stats HIR STATS: input_stats
tests/ui/thread-local/thread-local-issue-37508.rs+1-1
......@@ -4,7 +4,7 @@
44//
55// Regression test for issue #37508
66
7// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
7// FIXME(static_mut_refs): use raw pointers instead of references
88#![allow(static_mut_refs)]
99
1010#![no_main]
tests/ui/traits/impl.rs+1-1
......@@ -3,7 +3,7 @@
33
44//@ aux-build:traitimpl.rs
55
6// FIXME(static_mut_refs): this could use an atomic
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99extern crate traitimpl;
tests/ui/union/union-drop-assign.rs+1-1
......@@ -3,7 +3,7 @@
33
44// Drop works for union itself.
55
6// FIXME(static_mut_refs): this could use an atomic
6// FIXME(static_mut_refs): use raw pointers instead of references
77#![allow(static_mut_refs)]
88
99use std::mem::ManuallyDrop;
tests/ui/union/union-drop.rs+1-1
......@@ -2,7 +2,7 @@
22
33#![allow(dead_code)]
44#![allow(unused_variables)]
5// FIXME(static_mut_refs): this could use an atomic
5// FIXME(static_mut_refs): use raw pointers instead of references
66#![allow(static_mut_refs)]
77
88// Drop works for union itself.