| author | bors <bors@rust-lang.org> 2026-07-06 18:54:19 UTC |
| committer | bors <bors@rust-lang.org> 2026-07-06 18:54:19 UTC |
| log | c4af71034e89a431eeee91125a31ad001379faac |
| tree | c008f1eb6e980c3c5aa61f648765eee6a32a549c |
| parent | 36714a9983d6ba11203d8bb87a1b372247fbcf06 |
| parent | 2847dbc72bda323bf461ccc97b5ab42851b367ff |
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 { |
| 407 | 407 | } |
| 408 | 408 | } |
| 409 | 409 | |
| 410 | pub type GenericBounds = Vec<GenericBound>; | |
| 410 | pub type GenericBounds = ThinVec<GenericBound>; | |
| 411 | 411 | |
| 412 | 412 | /// Specifies the enforced ordering for generic parameters. In the future, |
| 413 | 413 | /// if we wanted to relax this order, we could override `PartialEq` and |
| ... | ... | @@ -1534,7 +1534,7 @@ impl Expr { |
| 1534 | 1534 | let (Some(lhs), Some(rhs)) = (lhs.to_bound(), rhs.to_bound()) else { |
| 1535 | 1535 | return None; |
| 1536 | 1536 | }; |
| 1537 | TyKind::TraitObject(vec![lhs, rhs], TraitObjectSyntax::None) | |
| 1537 | TyKind::TraitObject(thin_vec![lhs, rhs], TraitObjectSyntax::None) | |
| 1538 | 1538 | } |
| 1539 | 1539 | |
| 1540 | 1540 | ExprKind::Underscore => TyKind::Infer, |
| ... | ... | @@ -1868,7 +1868,7 @@ pub enum ExprKind { |
| 1868 | 1868 | /// |
| 1869 | 1869 | /// Usually not written directly in user code but |
| 1870 | 1870 | /// indirectly via the macro `core::mem::offset_of!(...)`. |
| 1871 | OffsetOf(Box<Ty>, Vec<Ident>), | |
| 1871 | OffsetOf(Box<Ty>, ThinVec<Ident>), | |
| 1872 | 1872 | |
| 1873 | 1873 | /// A macro invocation; pre-expansion. |
| 1874 | 1874 | MacCall(Box<MacCall>), |
| ... | ... | @@ -4391,27 +4391,37 @@ mod size_asserts { |
| 4391 | 4391 | // tidy-alphabetical-start |
| 4392 | 4392 | static_assert_size!(AssocItem, 80); |
| 4393 | 4393 | static_assert_size!(AssocItemKind, 16); |
| 4394 | static_assert_size!(AttrKind, 16); | |
| 4394 | 4395 | static_assert_size!(Attribute, 32); |
| 4395 | 4396 | static_assert_size!(Block, 32); |
| 4396 | 4397 | static_assert_size!(Expr, 72); |
| 4397 | 4398 | static_assert_size!(ExprKind, 40); |
| 4398 | 4399 | static_assert_size!(Fn, 192); |
| 4400 | static_assert_size!(FnDecl, 24); | |
| 4401 | static_assert_size!(FnHeader, 76); | |
| 4402 | static_assert_size!(FnSig, 96); | |
| 4399 | 4403 | static_assert_size!(ForeignItem, 80); |
| 4400 | 4404 | static_assert_size!(ForeignItemKind, 16); |
| 4401 | 4405 | static_assert_size!(GenericArg, 24); |
| 4406 | static_assert_size!(GenericArgs, 40); | |
| 4402 | 4407 | static_assert_size!(GenericBound, 88); |
| 4408 | static_assert_size!(GenericParam, 80); | |
| 4403 | 4409 | static_assert_size!(Generics, 40); |
| 4404 | 4410 | static_assert_size!(Impl, 80); |
| 4405 | 4411 | static_assert_size!(Item, 152); |
| 4406 | 4412 | static_assert_size!(ItemKind, 88); |
| 4413 | static_assert_size!(Lifetime, 16); | |
| 4407 | 4414 | static_assert_size!(LitKind, 24); |
| 4408 | 4415 | static_assert_size!(Local, 96); |
| 4416 | static_assert_size!(MetaItem, 88); | |
| 4417 | static_assert_size!(MetaItemKind, 40); | |
| 4409 | 4418 | static_assert_size!(MetaItemLit, 40); |
| 4410 | 4419 | static_assert_size!(Param, 40); |
| 4411 | 4420 | static_assert_size!(Pat, 80); |
| 4412 | 4421 | static_assert_size!(PatKind, 56); |
| 4413 | 4422 | static_assert_size!(Path, 24); |
| 4414 | 4423 | static_assert_size!(PathSegment, 24); |
| 4424 | static_assert_size!(QSelf, 24); | |
| 4415 | 4425 | static_assert_size!(Stmt, 32); |
| 4416 | 4426 | static_assert_size!(StmtKind, 16); |
| 4417 | 4427 | static_assert_size!(TraitImplHeader, 72); |
compiler/rustc_ast/src/visit.rs+2| ... | ... | @@ -386,6 +386,8 @@ macro_rules! common_visitor_and_walkers { |
| 386 | 386 | impl_visitable_list!(<$($lt)? $($mut)?> |
| 387 | 387 | ThinVec<AngleBracketedArg>, |
| 388 | 388 | ThinVec<Attribute>, |
| 389 | ThinVec<GenericBound>, | |
| 390 | ThinVec<Ident>, | |
| 389 | 391 | ThinVec<(Ident, Option<Ident>)>, |
| 390 | 392 | ThinVec<(NodeId, Path)>, |
| 391 | 393 | ThinVec<PathSegment>, |
compiler/rustc_attr_parsing/src/attributes/doc.rs+6-5| ... | ... | @@ -348,8 +348,11 @@ impl DocParser { |
| 348 | 348 | // If it's a list, then only `any()` and `none()` are allowed and they must not |
| 349 | 349 | // contain any item. |
| 350 | 350 | 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) | |
| 353 | 356 | && let ArgParser::List(list) = sub_item.args() |
| 354 | 357 | && list.mixed().count() == 0 |
| 355 | 358 | { |
| ... | ... | @@ -371,9 +374,7 @@ impl DocParser { |
| 371 | 374 | } else { |
| 372 | 375 | cx.emit_lint( |
| 373 | 376 | rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, |
| 374 | DocAutoCfgHideShowUnexpectedItem { | |
| 375 | attr_name: sub_item.ident().unwrap().name, | |
| 376 | }, | |
| 377 | DocAutoCfgHideShowUnexpectedItem { attr_name: ident.name }, | |
| 377 | 378 | sub_item.span(), |
| 378 | 379 | ); |
| 379 | 380 | } |
compiler/rustc_builtin_macros/src/deriving/debug.rs+1-1| ... | ... | @@ -167,7 +167,7 @@ fn show_substructure(cx: &ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> |
| 167 | 167 | let ty_dyn_debug = cx.ty( |
| 168 | 168 | span, |
| 169 | 169 | ast::TyKind::TraitObject( |
| 170 | vec![cx.trait_bound(path_debug, false)], | |
| 170 | thin_vec![cx.trait_bound(path_debug, false)], | |
| 171 | 171 | ast::TraitObjectSyntax::Dyn, |
| 172 | 172 | ), |
| 173 | 173 | ); |
compiler/rustc_builtin_macros/src/deriving/generic/mod.rs+3-3| ... | ... | @@ -617,7 +617,7 @@ impl<'a> TraitDef<'a> { |
| 617 | 617 | ident, |
| 618 | 618 | generics: Generics::default(), |
| 619 | 619 | after_where_clause: ast::WhereClause::default(), |
| 620 | bounds: Vec::new(), | |
| 620 | bounds: ThinVec::new(), | |
| 621 | 621 | ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)), |
| 622 | 622 | })), |
| 623 | 623 | tokens: None, |
| ... | ... | @@ -639,7 +639,7 @@ impl<'a> TraitDef<'a> { |
| 639 | 639 | // Extra restrictions on the generics parameters to the |
| 640 | 640 | // type being derived upon. |
| 641 | 641 | let span = param.ident.span.with_ctxt(ctxt); |
| 642 | let bounds: Vec<_> = self | |
| 642 | let bounds: ThinVec<_> = self | |
| 643 | 643 | .additional_bounds |
| 644 | 644 | .iter() |
| 645 | 645 | .map(|p| { |
| ... | ... | @@ -723,7 +723,7 @@ impl<'a> TraitDef<'a> { |
| 723 | 723 | { |
| 724 | 724 | continue; |
| 725 | 725 | } |
| 726 | let mut bounds: Vec<_> = self | |
| 726 | let mut bounds: ThinVec<_> = self | |
| 727 | 727 | .additional_bounds |
| 728 | 728 | .iter() |
| 729 | 729 | .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}; |
| 22 | 22 | use rustc_middle::ty::TyCtxt; |
| 23 | 23 | use rustc_session::Session; |
| 24 | 24 | use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath}; |
| 25 | use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym}; | |
| 25 | use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext}; | |
| 26 | 26 | use rustc_target::spec::{CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel}; |
| 27 | 27 | use tracing::{debug, trace}; |
| 28 | 28 | |
| ... | ... | @@ -209,14 +209,8 @@ pub(crate) fn target_machine_factory( |
| 209 | 209 | |
| 210 | 210 | let code_model = to_llvm_code_model(sess.code_model()); |
| 211 | 211 | |
| 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); | |
| 220 | 214 | |
| 221 | 215 | let triple = SmallCStr::new(&versioned_llvm_target(sess)); |
| 222 | 216 | 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}; |
| 24 | 24 | use tracing::debug; |
| 25 | 25 | |
| 26 | 26 | use super::apple; |
| 27 | use crate::errors; | |
| 27 | 28 | |
| 28 | 29 | /// The default metadata loader. This is used by cg_llvm and cg_clif. |
| 29 | 30 | /// |
| ... | ... | @@ -370,7 +371,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { |
| 370 | 371 | if let Some(ref cpu) = sess.opts.cg.target_cpu { |
| 371 | 372 | ef_avr_arch(cpu) |
| 372 | 373 | } else { |
| 373 | bug!("AVR CPU not explicitly specified") | |
| 374 | sess.dcx().emit_fatal(errors::CpuRequired) | |
| 374 | 375 | } |
| 375 | 376 | } |
| 376 | 377 | 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> { |
| 63 | 63 | result_place: Option<PlaceValue<Bx::Value>>, |
| 64 | 64 | source_info: SourceInfo, |
| 65 | 65 | ) -> 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 | ||
| 66 | 77 | let span = source_info.span; |
| 67 | 78 | |
| 68 | 79 | let name = bx.tcx().item_name(instance.def_id()); |
compiler/rustc_data_structures/src/intern.rs+30-48| ... | ... | @@ -1,4 +1,3 @@ |
| 1 | use std::cmp::Ordering; | |
| 2 | 1 | use std::fmt::{self, Debug}; |
| 3 | 2 | use std::hash::{Hash, Hasher}; |
| 4 | 3 | use std::ops::Deref; |
| ... | ... | @@ -11,26 +10,40 @@ mod private { |
| 11 | 10 | pub struct PrivateZst; |
| 12 | 11 | } |
| 13 | 12 | |
| 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. | |
| 15 | 16 | /// |
| 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.) | |
| 21 | 22 | /// |
| 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. | |
| 25 | 35 | #[rustc_pass_by_value] |
| 26 | 36 | pub struct Interned<'a, T>(pub &'a T, pub private::PrivateZst); |
| 27 | 37 | |
| 28 | 38 | impl<'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. | |
| 34 | 47 | #[inline] |
| 35 | 48 | pub const fn new_unchecked(t: &'a T) -> Self { |
| 36 | 49 | Interned(t, private::PrivateZst) |
| ... | ... | @@ -64,41 +77,10 @@ impl<'a, T> PartialEq for Interned<'a, T> { |
| 64 | 77 | |
| 65 | 78 | impl<'a, T> Eq for Interned<'a, T> {} |
| 66 | 79 | |
| 67 | impl<'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 | ||
| 81 | impl<'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 | ||
| 95 | impl<'a, T> Hash for Interned<'a, T> | |
| 96 | where | |
| 97 | T: Hash, | |
| 98 | { | |
| 80 | impl<'a, T> Hash for Interned<'a, T> { | |
| 99 | 81 | #[inline] |
| 100 | 82 | fn hash<H: Hasher>(&self, s: &mut H) { |
| 101 | // Pointer hashing is sufficient, due to the uniqueness constraint. | |
| 83 | // Pointer hashing is sufficient. | |
| 102 | 84 | ptr::hash(self.0, s) |
| 103 | 85 | } |
| 104 | 86 | } |
compiler/rustc_data_structures/src/intern/tests.rs+1-26| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | use super::*; |
| 2 | 2 | |
| 3 | #[allow(unused)] | |
| 3 | 4 | #[derive(Debug)] |
| 4 | 5 | struct S(u32); |
| 5 | 6 | |
| ... | ... | @@ -11,22 +12,6 @@ impl PartialEq for S { |
| 11 | 12 | |
| 12 | 13 | impl Eq for S {} |
| 13 | 14 | |
| 14 | impl 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 | ||
| 22 | impl 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 | ||
| 30 | 15 | #[test] |
| 31 | 16 | fn test_uniq() { |
| 32 | 17 | let s1 = S(1); |
| ... | ... | @@ -45,14 +30,4 @@ fn test_uniq() { |
| 45 | 30 | assert_eq!(v1, v1); |
| 46 | 31 | assert_eq!(v3a, v3b); |
| 47 | 32 | 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 | |
| 58 | 33 | } |
compiler/rustc_feature/src/builtin_attrs.rs+1| ... | ... | @@ -50,6 +50,7 @@ const GATED_CFGS: &[GatedCfg] = &[ |
| 50 | 50 | sym::cfg_target_has_reliable_f16_f128, |
| 51 | 51 | Features::cfg_target_has_reliable_f16_f128, |
| 52 | 52 | ), |
| 53 | (sym::target_has_threads, sym::cfg_target_has_threads, Features::cfg_target_has_threads), | |
| 53 | 54 | (sym::target_object_format, sym::cfg_target_object_format, Features::cfg_target_object_format), |
| 54 | 55 | ]; |
| 55 | 56 |
compiler/rustc_feature/src/unstable.rs+2| ... | ... | @@ -254,6 +254,8 @@ declare_features! ( |
| 254 | 254 | (unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None), |
| 255 | 255 | /// Allows checking whether or not the backend correctly supports unstable float types. |
| 256 | 256 | (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), | |
| 257 | 259 | /// Allows identifying the `compiler_builtins` crate. |
| 258 | 260 | (internal, compiler_builtins, "1.13.0", None), |
| 259 | 261 | /// Allows skipping `ConstParamTy_` trait implementation checks |
compiler/rustc_hir/src/hir.rs+1-1| ... | ... | @@ -511,7 +511,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { |
| 511 | 511 | #[derive(Clone, Copy, Debug, StableHash)] |
| 512 | 512 | #[repr(u8, C)] |
| 513 | 513 | pub enum ConstArgKind<'hir, Unambig = ()> { |
| 514 | Tup(&'hir [&'hir ConstArg<'hir, Unambig>]), | |
| 514 | Tup(&'hir [&'hir ConstArg<'hir>]), | |
| 515 | 515 | /// **Note:** Currently this is only used for bare const params |
| 516 | 516 | /// (`N` where `fn foo<const N: usize>(...)`), |
| 517 | 517 | /// 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>>( |
| 1088 | 1088 | try_visit!(visitor.visit_id(*hir_id)); |
| 1089 | 1089 | match kind { |
| 1090 | 1090 | ConstArgKind::Tup(exprs) => { |
| 1091 | walk_list!(visitor, visit_const_arg, *exprs); | |
| 1091 | walk_list!(visitor, visit_const_arg_unambig, *exprs); | |
| 1092 | 1092 | V::Result::output() |
| 1093 | 1093 | } |
| 1094 | 1094 | ConstArgKind::Struct(qpath, field_exprs) => { |
compiler/rustc_middle/src/ty/inhabitedness/mod.rs+1-1| ... | ... | @@ -93,7 +93,7 @@ impl<'tcx> VariantDef { |
| 93 | 93 | match field.vis { |
| 94 | 94 | Visibility::Public => pred, |
| 95 | 95 | Visibility::Restricted(from) => { |
| 96 | pred.or(tcx, InhabitedPredicate::NotInModule(from)) | |
| 96 | InhabitedPredicate::NotInModule(from).or(tcx, pred) | |
| 97 | 97 | } |
| 98 | 98 | } |
| 99 | 99 | }), |
compiler/rustc_monomorphize/src/collector.rs+9-2| ... | ... | @@ -995,11 +995,18 @@ fn visit_instance_use<'tcx>( |
| 995 | 995 | output.push(create_fn_mono_item(tcx, panic_instance, source)); |
| 996 | 996 | } |
| 997 | 997 | } 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)) | |
| 999 | 1000 | { |
| 1000 | 1001 | // Codegen the fallback body of intrinsics with fallback bodies. |
| 1001 | 1002 | // 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. | |
| 1003 | 1010 | let instance = ty::Instance::new_raw(instance.def_id(), instance.args); |
| 1004 | 1011 | if tcx.should_codegen_locally(instance) { |
| 1005 | 1012 | 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> { |
| 1154 | 1154 | /// Parse the field access used in offset_of, matched by `$(e:expr)+`. |
| 1155 | 1155 | /// Currently returns a list of idents. However, it should be possible in |
| 1156 | 1156 | /// 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(); | |
| 1159 | 1159 | let mut trailing_dot = None; |
| 1160 | 1160 | |
| 1161 | 1161 | loop { |
compiler/rustc_parse/src/parser/generics.rs+6-6| ... | ... | @@ -26,7 +26,7 @@ impl<'a> Parser<'a> { |
| 26 | 26 | /// BOUND = LT_BOUND (e.g., `'a`) |
| 27 | 27 | /// ``` |
| 28 | 28 | fn parse_lt_param_bounds(&mut self) -> GenericBounds { |
| 29 | let mut lifetimes = Vec::new(); | |
| 29 | let mut lifetimes = ThinVec::new(); | |
| 30 | 30 | while self.check_lifetime() { |
| 31 | 31 | lifetimes.push(ast::GenericBound::Outlives(self.expect_lifetime())); |
| 32 | 32 | |
| ... | ... | @@ -86,7 +86,7 @@ impl<'a> Parser<'a> { |
| 86 | 86 | } |
| 87 | 87 | self.parse_generic_bounds()? |
| 88 | 88 | } else { |
| 89 | Vec::new() | |
| 89 | ThinVec::new() | |
| 90 | 90 | }; |
| 91 | 91 | |
| 92 | 92 | let default = if self.eat(exp!(Eq)) { Some(self.parse_ty()?) } else { None }; |
| ... | ... | @@ -125,7 +125,7 @@ impl<'a> Parser<'a> { |
| 125 | 125 | ident, |
| 126 | 126 | id: ast::DUMMY_NODE_ID, |
| 127 | 127 | attrs: preceding_attrs, |
| 128 | bounds: Vec::new(), | |
| 128 | bounds: ThinVec::new(), | |
| 129 | 129 | kind: GenericParamKind::Const { ty, span, default: None }, |
| 130 | 130 | is_placeholder: false, |
| 131 | 131 | colon_span: None, |
| ... | ... | @@ -148,7 +148,7 @@ impl<'a> Parser<'a> { |
| 148 | 148 | ident, |
| 149 | 149 | id: ast::DUMMY_NODE_ID, |
| 150 | 150 | attrs: preceding_attrs, |
| 151 | bounds: Vec::new(), | |
| 151 | bounds: ThinVec::new(), | |
| 152 | 152 | kind: GenericParamKind::Const { ty, span, default }, |
| 153 | 153 | is_placeholder: false, |
| 154 | 154 | colon_span: None, |
| ... | ... | @@ -189,7 +189,7 @@ impl<'a> Parser<'a> { |
| 189 | 189 | ident, |
| 190 | 190 | id: ast::DUMMY_NODE_ID, |
| 191 | 191 | attrs: preceding_attrs, |
| 192 | bounds: Vec::new(), | |
| 192 | bounds: ThinVec::new(), | |
| 193 | 193 | kind: GenericParamKind::Const { ty, span, default }, |
| 194 | 194 | is_placeholder: false, |
| 195 | 195 | colon_span: None, |
| ... | ... | @@ -225,7 +225,7 @@ impl<'a> Parser<'a> { |
| 225 | 225 | let (colon_span, bounds) = if this.eat(exp!(Colon)) { |
| 226 | 226 | (Some(this.prev_token.span), this.parse_lt_param_bounds()) |
| 227 | 227 | } else { |
| 228 | (None, Vec::new()) | |
| 228 | (None, ThinVec::new()) | |
| 229 | 229 | }; |
| 230 | 230 | |
| 231 | 231 | 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> { |
| 1148 | 1148 | // Parse optional colon and supertrait bounds. |
| 1149 | 1149 | let had_colon = self.eat(exp!(Colon)); |
| 1150 | 1150 | 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() }; | |
| 1152 | 1152 | |
| 1153 | 1153 | let span_before_eq = self.prev_token.span; |
| 1154 | 1154 | if self.eat(exp!(Eq)) { |
| ... | ... | @@ -1266,7 +1266,8 @@ impl<'a> Parser<'a> { |
| 1266 | 1266 | let mut generics = self.parse_generics()?; |
| 1267 | 1267 | |
| 1268 | 1268 | // 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() }; | |
| 1270 | 1271 | generics.where_clause = self.parse_where_clause()?; |
| 1271 | 1272 | |
| 1272 | 1273 | 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> { |
| 576 | 576 | lo.to(self.prev_token.span), |
| 577 | 577 | parens, |
| 578 | 578 | ); |
| 579 | let bounds = vec![GenericBound::Trait(poly_trait_ref)]; | |
| 579 | let bounds = thin_vec![GenericBound::Trait(poly_trait_ref)]; | |
| 580 | 580 | self.parse_remaining_bounds(bounds, parse_plus) |
| 581 | 581 | } |
| 582 | 582 | |
| ... | ... | @@ -1080,7 +1080,7 @@ impl<'a> Parser<'a> { |
| 1080 | 1080 | /// Only if `allow_plus` this parses a `+`-separated list of bounds (trailing `+` is admitted). |
| 1081 | 1081 | /// Otherwise, this only parses a single bound or none. |
| 1082 | 1082 | 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(); | |
| 1084 | 1084 | |
| 1085 | 1085 | // In addition to looping while we find generic bounds: |
| 1086 | 1086 | // We continue even if we find a keyword. This is necessary for error recovery on, |
| ... | ... | @@ -1432,7 +1432,7 @@ impl<'a> Parser<'a> { |
| 1432 | 1432 | // Someone has written something like `&dyn (Trait + Other)`. The correct code |
| 1433 | 1433 | // would be `&(dyn Trait + Other)` |
| 1434 | 1434 | if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) { |
| 1435 | let bounds = vec![]; | |
| 1435 | let bounds = thin_vec![]; | |
| 1436 | 1436 | self.parse_remaining_bounds(bounds, true)?; |
| 1437 | 1437 | self.expect(exp!(CloseParen))?; |
| 1438 | 1438 | self.dcx().emit_err(errors::IncorrectParensTraitBounds { |
| ... | ... | @@ -1617,7 +1617,7 @@ impl<'a> Parser<'a> { |
| 1617 | 1617 | id: lt.id, |
| 1618 | 1618 | ident: lt.ident, |
| 1619 | 1619 | attrs: ast::AttrVec::new(), |
| 1620 | bounds: Vec::new(), | |
| 1620 | bounds: ThinVec::new(), | |
| 1621 | 1621 | is_placeholder: false, |
| 1622 | 1622 | kind: ast::GenericParamKind::Lifetime, |
| 1623 | 1623 | colon_span: None, |
compiler/rustc_resolve/src/imports.rs+4-15| ... | ... | @@ -210,23 +210,10 @@ pub(crate) struct ImportData<'ra> { |
| 210 | 210 | pub on_unknown_attr: Option<OnUnknownData>, |
| 211 | 211 | } |
| 212 | 212 | |
| 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. | |
| 215 | 215 | pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>; |
| 216 | 216 | |
| 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. | |
| 221 | impl 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 | ||
| 230 | 217 | impl<'ra> ImportData<'ra> { |
| 231 | 218 | pub(crate) fn is_glob(&self) -> bool { |
| 232 | 219 | matches!(self.kind, ImportKind::Glob { .. }) |
| ... | ... | @@ -291,6 +278,8 @@ pub(crate) struct NameResolution<'ra> { |
| 291 | 278 | pub orig_ident_span: Span, |
| 292 | 279 | } |
| 293 | 280 | |
| 281 | /// `Interned` is used because values of this type have "identity" and compare as unequal even if | |
| 282 | /// they have the same contents. | |
| 294 | 283 | pub(crate) type NameResolutionRef<'ra> = Interned<'ra, CmRefCell<NameResolution<'ra>>>; |
| 295 | 284 | |
| 296 | 285 | impl<'ra> NameResolution<'ra> { |
compiler/rustc_resolve/src/late/diagnostics.rs+2-2| ... | ... | @@ -28,7 +28,7 @@ use rustc_session::{Session, lint}; |
| 28 | 28 | use rustc_span::edit_distance::{edit_distance, find_best_match_for_name}; |
| 29 | 29 | use rustc_span::edition::Edition; |
| 30 | 30 | use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; |
| 31 | use thin_vec::ThinVec; | |
| 31 | use thin_vec::{ThinVec, thin_vec}; | |
| 32 | 32 | use tracing::debug; |
| 33 | 33 | |
| 34 | 34 | use super::NoConstantGenericsReason; |
| ... | ... | @@ -4522,7 +4522,7 @@ fn mk_where_bound_predicate( |
| 4522 | 4522 | let new_where_bound_predicate = ast::WhereBoundPredicate { |
| 4523 | 4523 | bound_generic_params: ThinVec::new(), |
| 4524 | 4524 | bounded_ty: Box::new(ty.clone()), |
| 4525 | bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef { | |
| 4525 | bounds: thin_vec![ast::GenericBound::Trait(ast::PolyTraitRef { | |
| 4526 | 4526 | bound_generic_params: ThinVec::new(), |
| 4527 | 4527 | modifiers: ast::TraitBoundModifiers::NONE, |
| 4528 | 4528 | trait_ref: ast::TraitRef { |
compiler/rustc_resolve/src/lib.rs+9-30| ... | ... | @@ -683,8 +683,8 @@ struct ModuleData<'ra> { |
| 683 | 683 | self_decl: Option<Decl<'ra>>, |
| 684 | 684 | } |
| 685 | 685 | |
| 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. | |
| 688 | 688 | #[derive(Clone, Copy, PartialEq, Eq, Hash)] |
| 689 | 689 | #[rustc_pass_by_value] |
| 690 | 690 | struct Module<'ra>(Interned<'ra, ModuleData<'ra>>); |
| ... | ... | @@ -699,19 +699,6 @@ struct LocalModule<'ra>(Interned<'ra, ModuleData<'ra>>); |
| 699 | 699 | #[rustc_pass_by_value] |
| 700 | 700 | struct ExternModule<'ra>(Interned<'ra, ModuleData<'ra>>); |
| 701 | 701 | |
| 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. | |
| 706 | impl 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 | ||
| 715 | 702 | impl<'ra> ModuleData<'ra> { |
| 716 | 703 | fn new( |
| 717 | 704 | parent: Option<Module<'ra>>, |
| ... | ... | @@ -916,6 +903,7 @@ impl<'ra> LocalModule<'ra> { |
| 916 | 903 | assert!(kind.is_local()); |
| 917 | 904 | let parent = parent.map(|m| m.to_module()); |
| 918 | 905 | 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". | |
| 919 | 907 | LocalModule(Interned::new_unchecked(arenas.modules.alloc(data))) |
| 920 | 908 | } |
| 921 | 909 | |
| ... | ... | @@ -937,6 +925,7 @@ impl<'ra> ExternModule<'ra> { |
| 937 | 925 | assert!(!kind.is_local()); |
| 938 | 926 | let parent = parent.map(|m| m.to_module()); |
| 939 | 927 | 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". | |
| 940 | 929 | ExternModule(Interned::new_unchecked(arenas.modules.alloc(data))) |
| 941 | 930 | } |
| 942 | 931 | |
| ... | ... | @@ -1001,23 +990,10 @@ struct DeclData<'ra> { |
| 1001 | 990 | parent_module: Option<Module<'ra>>, |
| 1002 | 991 | } |
| 1003 | 992 | |
| 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. | |
| 1006 | 995 | type Decl<'ra> = Interned<'ra, DeclData<'ra>>; |
| 1007 | 996 | |
| 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. | |
| 1012 | impl 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 | ||
| 1021 | 997 | /// Name declaration kind. |
| 1022 | 998 | #[derive(Debug)] |
| 1023 | 999 | enum DeclKind<'ra> { |
| ... | ... | @@ -1585,12 +1561,15 @@ impl<'ra> ResolverArenas<'ra> { |
| 1585 | 1561 | } |
| 1586 | 1562 | |
| 1587 | 1563 | fn alloc_decl(&'ra self, data: DeclData<'ra>) -> Decl<'ra> { |
| 1564 | // SAFETY: `Interned` is valid because values of this type have "identity". | |
| 1588 | 1565 | Interned::new_unchecked(self.dropless.alloc(data)) |
| 1589 | 1566 | } |
| 1590 | 1567 | fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> { |
| 1568 | // SAFETY: `Interned` is valid because values of this type have "identity". | |
| 1591 | 1569 | Interned::new_unchecked(self.imports.alloc(import)) |
| 1592 | 1570 | } |
| 1593 | 1571 | fn alloc_name_resolution(&'ra self, orig_ident_span: Span) -> NameResolutionRef<'ra> { |
| 1572 | // SAFETY: `Interned` is valid because values of this type have "identity". | |
| 1594 | 1573 | Interned::new_unchecked( |
| 1595 | 1574 | self.name_resolutions.alloc(CmRefCell::new(NameResolution::new(orig_ident_span))), |
| 1596 | 1575 | ) |
compiler/rustc_session/src/config/cfg.rs+6| ... | ... | @@ -149,6 +149,7 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) { |
| 149 | 149 | | (sym::target_pointer_width, Some(_)) |
| 150 | 150 | | (sym::target_vendor, None | Some(_)) |
| 151 | 151 | | (sym::target_has_atomic, Some(_)) |
| 152 | | (sym::target_has_threads, None | Some(_)) | |
| 152 | 153 | | (sym::target_has_atomic_primitive_alignment, Some(_)) |
| 153 | 154 | | (sym::target_has_atomic_load_store, Some(_)) |
| 154 | 155 | | (sym::target_has_reliable_f16, None | Some(_)) |
| ... | ... | @@ -303,6 +304,10 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg { |
| 303 | 304 | } |
| 304 | 305 | } |
| 305 | 306 | |
| 307 | if !sess.target.singlethread(&sess.target_features) { | |
| 308 | ins_none!(sym::target_has_threads); | |
| 309 | } | |
| 310 | ||
| 306 | 311 | ins_sym!(sym::target_os, sess.target.os.desc_symbol()); |
| 307 | 312 | ins_sym!(sym::target_pointer_width, sym::integer(sess.target.pointer_width)); |
| 308 | 313 | |
| ... | ... | @@ -485,6 +490,7 @@ impl CheckCfg { |
| 485 | 490 | ins!(sym::target_has_atomic_primitive_alignment, empty_values).extend(atomic_values); |
| 486 | 491 | |
| 487 | 492 | ins!(sym::target_thread_local, no_values); |
| 493 | ins!(sym::target_has_threads, no_values); | |
| 488 | 494 | |
| 489 | 495 | ins!(sym::ub_checks, no_values); |
| 490 | 496 | ins!(sym::contract_checks, no_values); |
compiler/rustc_session/src/options.rs+3| ... | ... | @@ -2419,6 +2419,9 @@ options! { |
| 2419 | 2419 | fmt_debug: FmtDebug = (FmtDebug::Full, parse_fmt_debug, [TRACKED], |
| 2420 | 2420 | "how detailed `#[derive(Debug)]` should be. `full` prints types recursively, \ |
| 2421 | 2421 | `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)."), | |
| 2422 | 2425 | force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], |
| 2423 | 2426 | "force all crates to be `rustc_private` unstable (default: no)"), |
| 2424 | 2427 | function_return: FunctionReturn = (FunctionReturn::default(), parse_function_return, [TRACKED], |
compiler/rustc_span/src/symbol.rs+2| ... | ... | @@ -598,6 +598,7 @@ symbols! { |
| 598 | 598 | cfg_target_has_atomic, |
| 599 | 599 | cfg_target_has_atomic_equal_alignment, |
| 600 | 600 | cfg_target_has_reliable_f16_f128, |
| 601 | cfg_target_has_threads, | |
| 601 | 602 | cfg_target_object_format, |
| 602 | 603 | cfg_target_thread_local, |
| 603 | 604 | cfg_target_vendor, |
| ... | ... | @@ -2084,6 +2085,7 @@ symbols! { |
| 2084 | 2085 | target_has_reliable_f16_math, |
| 2085 | 2086 | target_has_reliable_f128, |
| 2086 | 2087 | target_has_reliable_f128_math, |
| 2088 | target_has_threads, | |
| 2087 | 2089 | target_object_format, |
| 2088 | 2090 | target_os, |
| 2089 | 2091 | target_pointer_width, |
compiler/rustc_target/src/spec/mod.rs+26-144| ... | ... | @@ -40,11 +40,11 @@ |
| 40 | 40 | use core::result::Result; |
| 41 | 41 | use std::borrow::Cow; |
| 42 | 42 | use std::collections::BTreeMap; |
| 43 | use std::hash::{Hash, Hasher}; | |
| 43 | use std::fmt; | |
| 44 | use std::hash::Hash; | |
| 44 | 45 | use std::ops::{Deref, DerefMut}; |
| 45 | 46 | use std::path::{Path, PathBuf}; |
| 46 | 47 | use std::str::FromStr; |
| 47 | use std::{fmt, io}; | |
| 48 | 48 | |
| 49 | 49 | use rustc_abi::{ |
| 50 | 50 | Align, CVariadicStatus, CanonAbi, Endian, ExternAbi, Integer, Size, TargetDataLayout, |
| ... | ... | @@ -52,9 +52,7 @@ use rustc_abi::{ |
| 52 | 52 | }; |
| 53 | 53 | use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; |
| 54 | 54 | use rustc_error_messages::{DiagArgValue, IntoDiagArg, into_diag_arg_using_display}; |
| 55 | use rustc_fs_util::try_canonicalize; | |
| 56 | 55 | use rustc_macros::{BlobDecodable, Decodable, Encodable, StableHash}; |
| 57 | use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; | |
| 58 | 56 | use rustc_span::{Symbol, kw, sym}; |
| 59 | 57 | use serde_json::Value; |
| 60 | 58 | use tracing::debug; |
| ... | ... | @@ -67,11 +65,13 @@ pub mod crt_objects; |
| 67 | 65 | mod abi_map; |
| 68 | 66 | mod base; |
| 69 | 67 | mod json; |
| 68 | mod tuple; | |
| 70 | 69 | |
| 71 | 70 | pub use abi_map::{AbiMap, AbiMapping}; |
| 72 | 71 | pub use base::apple; |
| 73 | 72 | pub use base::avr::ef_avr_arch; |
| 74 | 73 | pub use json::json_schema; |
| 74 | pub use tuple::TargetTuple; | |
| 75 | 75 | |
| 76 | 76 | /// Linker is called through a C/C++ compiler. |
| 77 | 77 | #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] |
| ... | ... | @@ -2256,6 +2256,26 @@ impl Target { |
| 2256 | 2256 | } |
| 2257 | 2257 | } |
| 2258 | 2258 | } |
| 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 | } | |
| 2259 | 2279 | } |
| 2260 | 2280 | |
| 2261 | 2281 | pub trait HasTargetSpec { |
| ... | ... | @@ -2571,7 +2591,8 @@ pub struct TargetOptions { |
| 2571 | 2591 | pub requires_lto: bool, |
| 2572 | 2592 | |
| 2573 | 2593 | /// 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, | |
| 2575 | 2596 | |
| 2576 | 2597 | /// Whether library functions call lowering/optimization is disabled in LLVM |
| 2577 | 2598 | /// for this target unconditionally. |
| ... | ... | @@ -3893,142 +3914,3 @@ impl Target { |
| 3893 | 3914 | Symbol::intern(&self.vendor) |
| 3894 | 3915 | } |
| 3895 | 3916 | } |
| 3896 | ||
| 3897 | /// Either a target tuple string or a path to a JSON file. | |
| 3898 | #[derive(Clone, Debug)] | |
| 3899 | pub 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 | |
| 3911 | impl 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 | |
| 3925 | impl 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 | |
| 3942 | impl<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 | ||
| 3958 | impl<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 | ||
| 3974 | impl 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 | ||
| 4028 | impl fmt::Display for TargetTuple { | |
| 4029 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| 4030 | write!(f, "{}", self.debug_tuple()) | |
| 4031 | } | |
| 4032 | } | |
| 4033 | ||
| 4034 | into_diag_arg_using_display!(&TargetTuple); |
compiler/rustc_target/src/spec/tuple.rs created+146| ... | ... | @@ -0,0 +1,146 @@ |
| 1 | use std::hash::{Hash, Hasher}; | |
| 2 | use std::path::{Path, PathBuf}; | |
| 3 | use std::{fmt, io}; | |
| 4 | ||
| 5 | use rustc_error_messages::into_diag_arg_using_display; | |
| 6 | use rustc_fs_util::try_canonicalize; | |
| 7 | use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; | |
| 8 | ||
| 9 | /// Either a target tuple string or a path to a JSON file. | |
| 10 | #[derive(Clone, Debug)] | |
| 11 | pub 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 | |
| 23 | impl 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 | |
| 37 | impl 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 | |
| 54 | impl<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 | ||
| 70 | impl<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 | ||
| 86 | impl 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 | ||
| 140 | impl fmt::Display for TargetTuple { | |
| 141 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| 142 | write!(f, "{}", self.debug_tuple()) | |
| 143 | } | |
| 144 | } | |
| 145 | ||
| 146 | into_diag_arg_using_display!(&TargetTuple); |
library/core/src/ptr/const_ptr.rs+2-1| ... | ... | @@ -1497,9 +1497,10 @@ impl<T> *const [T] { |
| 1497 | 1497 | /// Returns a raw pointer to an element or subslice, without doing bounds |
| 1498 | 1498 | /// checking. |
| 1499 | 1499 | /// |
| 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 | |
| 1501 | 1501 | /// is *[undefined behavior]* even if the resulting pointer is not used. |
| 1502 | 1502 | /// |
| 1503 | /// [out-of-bounds index]: #method.add | |
| 1503 | 1504 | /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html |
| 1504 | 1505 | /// |
| 1505 | 1506 | /// # Examples |
library/core/src/ptr/non_null.rs+2-1| ... | ... | @@ -1573,9 +1573,10 @@ impl<T> NonNull<[T]> { |
| 1573 | 1573 | /// Returns a raw pointer to an element or subslice, without doing bounds |
| 1574 | 1574 | /// checking. |
| 1575 | 1575 | /// |
| 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 | |
| 1577 | 1577 | /// is *[undefined behavior]* even if the resulting pointer is not used. |
| 1578 | 1578 | /// |
| 1579 | /// [out-of-bounds index]: #method.add | |
| 1579 | 1580 | /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html |
| 1580 | 1581 | /// |
| 1581 | 1582 | /// # Examples |
library/std/src/collections/hash/set/tests.rs+26-8| ... | ... | @@ -418,14 +418,32 @@ fn test_retain() { |
| 418 | 418 | } |
| 419 | 419 | |
| 420 | 420 | #[test] |
| 421 | fn 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); | |
| 421 | fn 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] | |
| 431 | fn 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] | |
| 440 | fn 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()); | |
| 429 | 447 | } |
| 430 | 448 | |
| 431 | 449 | #[test] |
library/std/src/io/mod.rs+2-2| ... | ... | @@ -1295,7 +1295,7 @@ pub trait Read { |
| 1295 | 1295 | /// Ok(()) |
| 1296 | 1296 | /// } |
| 1297 | 1297 | /// ``` |
| 1298 | #[unstable(feature = "read_le", issue = "156983")] | |
| 1298 | #[unstable(feature = "read_le", issue = "156984")] | |
| 1299 | 1299 | #[inline] |
| 1300 | 1300 | fn read_le<T: FromEndianBytes>(&mut self) -> Result<T> |
| 1301 | 1301 | where |
| ... | ... | @@ -1328,7 +1328,7 @@ pub trait Read { |
| 1328 | 1328 | /// Ok(()) |
| 1329 | 1329 | /// } |
| 1330 | 1330 | /// ``` |
| 1331 | #[unstable(feature = "read_le", issue = "156983")] | |
| 1331 | #[unstable(feature = "read_le", issue = "156984")] | |
| 1332 | 1332 | #[inline] |
| 1333 | 1333 | fn read_be<T: FromEndianBytes>(&mut self) -> Result<T> |
| 1334 | 1334 | where |
library/std/src/lib.rs+2| ... | ... | @@ -276,6 +276,7 @@ |
| 276 | 276 | #![feature(asm_experimental_arch)] |
| 277 | 277 | #![feature(autodiff)] |
| 278 | 278 | #![feature(cfg_sanitizer_cfi)] |
| 279 | #![feature(cfg_target_has_threads)] | |
| 279 | 280 | #![feature(cfg_target_thread_local)] |
| 280 | 281 | #![feature(cfi_encoding)] |
| 281 | 282 | #![feature(const_trait_impl)] |
| ... | ... | @@ -286,6 +287,7 @@ |
| 286 | 287 | #![feature(doc_masked)] |
| 287 | 288 | #![feature(doc_notable_trait)] |
| 288 | 289 | #![feature(dropck_eyepatch)] |
| 290 | #![feature(exact_div)] | |
| 289 | 291 | #![feature(f16)] |
| 290 | 292 | #![feature(f128)] |
| 291 | 293 | #![feature(ffi_const)] |
library/std/src/sync/mod.rs+1-1| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | //! Consider the following code, operating on some global static variables: |
| 10 | 10 | //! |
| 11 | 11 | //! ```rust |
| 12 | //! // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 12 | //! // FIXME(static_mut_refs): use raw pointers instead of references | |
| 13 | 13 | //! #![allow(static_mut_refs)] |
| 14 | 14 | //! |
| 15 | 15 | //! 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 | |
| 2 | 2 | #![allow(static_mut_refs)] |
| 3 | 3 | |
| 4 | 4 | use 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 | |
| 2 | 2 | #![allow(static_mut_refs)] |
| 3 | 3 | |
| 4 | 4 | use 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> { |
| 234 | 234 | unsafe { |
| 235 | 235 | let mut mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, libc::getpid(), libc::KERN_PROC_ARGV]; |
| 236 | 236 | 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 | ||
| 242 | 251 | if argv[0].is_null() { |
| 243 | 252 | return Err(io::const_error!(io::ErrorKind::Uncategorized, "no current exe available")); |
| 244 | 253 | } |
| 245 | 254 | 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. | |
| 247 | 257 | crate::fs::canonicalize(OsStr::from_bytes(argv0)) |
| 248 | 258 | } 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. | |
| 249 | 262 | Ok(PathBuf::from(OsStr::from_bytes(argv0))) |
| 250 | 263 | } |
| 251 | 264 | } |
library/std/src/sys/sync/condvar/no_threads.rs+3| ... | ... | @@ -2,6 +2,9 @@ use crate::sys::sync::Mutex; |
| 2 | 2 | use crate::thread::sleep; |
| 3 | 3 | use crate::time::Duration; |
| 4 | 4 | |
| 5 | #[cfg(target_has_threads)] | |
| 6 | compile_error!("Using no_threads implementation on a target with threads"); | |
| 7 | ||
| 5 | 8 | pub struct Condvar {} |
| 6 | 9 | |
| 7 | 10 | impl Condvar { |
library/std/src/sys/sync/mutex/no_threads.rs+3| ... | ... | @@ -1,5 +1,8 @@ |
| 1 | 1 | use crate::cell::Cell; |
| 2 | 2 | |
| 3 | #[cfg(target_has_threads)] | |
| 4 | compile_error!("Using no_threads implementation on a target with threads"); | |
| 5 | ||
| 3 | 6 | pub struct Mutex { |
| 4 | 7 | // This platform has no threads, so we can use a Cell here. |
| 5 | 8 | locked: Cell<bool>, |
library/std/src/sys/sync/once/no_threads.rs+3| ... | ... | @@ -2,6 +2,9 @@ use crate::cell::Cell; |
| 2 | 2 | use crate::sync as public; |
| 3 | 3 | use crate::sync::once::OnceExclusiveState; |
| 4 | 4 | |
| 5 | #[cfg(target_has_threads)] | |
| 6 | compile_error!("Using no_threads implementation on a target with threads"); | |
| 7 | ||
| 5 | 8 | pub struct Once { |
| 6 | 9 | state: Cell<State>, |
| 7 | 10 | } |
library/std/src/sys/sync/rwlock/no_threads.rs+3| ... | ... | @@ -1,5 +1,8 @@ |
| 1 | 1 | use crate::cell::Cell; |
| 2 | 2 | |
| 3 | #[cfg(target_has_threads)] | |
| 4 | compile_error!("Using no_threads implementation on a target with threads"); | |
| 5 | ||
| 3 | 6 | pub struct RwLock { |
| 4 | 7 | // This platform has no threads, so we can use a Cell here. |
| 5 | 8 | mode: Cell<isize>, |
library/std/src/sys/thread_local/no_threads.rs+3| ... | ... | @@ -5,6 +5,9 @@ use crate::cell::{Cell, UnsafeCell}; |
| 5 | 5 | use crate::mem::MaybeUninit; |
| 6 | 6 | use crate::ptr; |
| 7 | 7 | |
| 8 | #[cfg(target_has_threads)] | |
| 9 | compile_error!("Using no_threads implementation on a target with threads"); | |
| 10 | ||
| 8 | 11 | #[doc(hidden)] |
| 9 | 12 | #[allow_internal_unstable(thread_local_internals)] |
| 10 | 13 | #[allow_internal_unsafe] |
library/std/src/thread/local.rs+9-2| ... | ... | @@ -620,10 +620,17 @@ impl<T: 'static> LocalKey<Cell<T>> { |
| 620 | 620 | |
| 621 | 621 | /// Updates the contained value using a function. |
| 622 | 622 | /// |
| 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 | /// | |
| 623 | 631 | /// # Examples |
| 624 | 632 | /// |
| 625 | 633 | /// ``` |
| 626 | /// #![feature(local_key_cell_update)] | |
| 627 | 634 | /// use std::cell::Cell; |
| 628 | 635 | /// |
| 629 | 636 | /// thread_local! { |
| ... | ... | @@ -633,7 +640,7 @@ impl<T: 'static> LocalKey<Cell<T>> { |
| 633 | 640 | /// X.update(|x| x + 1); |
| 634 | 641 | /// assert_eq!(X.get(), 6); |
| 635 | 642 | /// ``` |
| 636 | #[unstable(feature = "local_key_cell_update", issue = "143989")] | |
| 643 | #[stable(feature = "local_key_cell_update", since = "CURRENT_RUSTC_VERSION")] | |
| 637 | 644 | pub fn update(&'static self, f: impl FnOnce(T) -> T) |
| 638 | 645 | where |
| 639 | 646 | T: Copy, |
library/std/tests/thread_local/tests.rs+1-1| ... | ... | @@ -110,7 +110,7 @@ fn smoke_dtor() { |
| 110 | 110 | |
| 111 | 111 | #[test] |
| 112 | 112 | fn circular() { |
| 113 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 113 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 114 | 114 | #![allow(static_mut_refs)] |
| 115 | 115 | |
| 116 | 116 | struct S1(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>); |
src/bootstrap/Cargo.lock+12| ... | ... | @@ -71,6 +71,7 @@ dependencies = [ |
| 71 | 71 | "tracing-subscriber", |
| 72 | 72 | "walkdir", |
| 73 | 73 | "windows 0.61.1", |
| 74 | "windows-registry", | |
| 74 | 75 | "xz2", |
| 75 | 76 | ] |
| 76 | 77 | |
| ... | ... | @@ -1095,6 +1096,17 @@ dependencies = [ |
| 1095 | 1096 | "windows-link 0.2.1", |
| 1096 | 1097 | ] |
| 1097 | 1098 | |
| 1099 | [[package]] | |
| 1100 | name = "windows-registry" | |
| 1101 | version = "0.6.1" | |
| 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 1103 | checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" | |
| 1104 | dependencies = [ | |
| 1105 | "windows-link 0.2.1", | |
| 1106 | "windows-result 0.4.1", | |
| 1107 | "windows-strings 0.5.1", | |
| 1108 | ] | |
| 1109 | ||
| 1098 | 1110 | [[package]] |
| 1099 | 1111 | name = "windows-result" |
| 1100 | 1112 | version = "0.3.2" |
src/bootstrap/Cargo.toml+3| ... | ... | @@ -66,6 +66,9 @@ tracing = { version = "0.1", optional = true, features = ["attributes"] } |
| 66 | 66 | tracing-chrome = { version = "0.7", optional = true } |
| 67 | 67 | tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter", "fmt", "registry", "std"] } |
| 68 | 68 | |
| 69 | [target.'cfg(windows)'.dependencies.windows-registry] | |
| 70 | version = "0.6" | |
| 71 | ||
| 69 | 72 | [target.'cfg(windows)'.dependencies.junction] |
| 70 | 73 | version = "1.3.0" |
| 71 | 74 |
src/bootstrap/src/core/build_steps/compile.rs+1-1| ... | ... | @@ -1917,7 +1917,7 @@ pub fn compiler_file( |
| 1917 | 1917 | return PathBuf::new(); |
| 1918 | 1918 | } |
| 1919 | 1919 | let mut cmd = command(compiler); |
| 1920 | cmd.args(builder.cc_handled_clags(target, c)); | |
| 1920 | cmd.args(builder.cc_handled_cflags(target, c)); | |
| 1921 | 1921 | cmd.args(builder.cc_unhandled_cflags(target, GitRepo::Rustc, c)); |
| 1922 | 1922 | cmd.arg(format!("-print-file-name={file}")); |
| 1923 | 1923 | 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( |
| 800 | 800 | // Needs `suppressed_compiler_flag_prefixes` to be gone, and hence |
| 801 | 801 | // https://github.com/llvm/llvm-project/issues/88780 to be fixed. |
| 802 | 802 | for flag in builder |
| 803 | .cc_handled_clags(target, CLang::C) | |
| 803 | .cc_handled_cflags(target, CLang::C) | |
| 804 | 804 | .into_iter() |
| 805 | 805 | .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::C)) |
| 806 | 806 | .filter(|flag| !suppressed_compiler_flag_prefixes.iter().any(|p| flag.starts_with(p))) |
| ... | ... | @@ -821,7 +821,7 @@ fn configure_cmake( |
| 821 | 821 | cfg.define("CMAKE_C_FLAGS", cflags); |
| 822 | 822 | let mut cxxflags = ccflags.cxxflags.clone(); |
| 823 | 823 | for flag in builder |
| 824 | .cc_handled_clags(target, CLang::Cxx) | |
| 824 | .cc_handled_cflags(target, CLang::Cxx) | |
| 825 | 825 | .into_iter() |
| 826 | 826 | .chain(builder.cc_unhandled_cflags(target, GitRepo::Llvm, CLang::Cxx)) |
| 827 | 827 | .filter(|flag| { |
src/bootstrap/src/core/build_steps/test.rs+2-2| ... | ... | @@ -2682,9 +2682,9 @@ Please disable assertions with `rust.debug-assertions = false`. |
| 2682 | 2682 | // Only pass correct values for these flags for the `run-make` suite as it |
| 2683 | 2683 | // requires that a C++ compiler was configured which isn't always the case. |
| 2684 | 2684 | 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); | |
| 2686 | 2686 | 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); | |
| 2688 | 2688 | cxxflags.extend(builder.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx)); |
| 2689 | 2689 | cmd.arg("--cc") |
| 2690 | 2690 | .arg(builder.cc(target)) |
src/bootstrap/src/core/builder/cargo.rs+34-10| ... | ... | @@ -78,6 +78,26 @@ impl Rustflags { |
| 78 | 78 | } |
| 79 | 79 | } |
| 80 | 80 | |
| 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>. | |
| 88 | pub(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 | ||
| 81 | 101 | /// Flags that are passed to the `rustc` shim binary. These flags will only be applied when |
| 82 | 102 | /// compiling host code, i.e. when `--target` is unset. |
| 83 | 103 | #[derive(Debug, Default)] |
| ... | ... | @@ -480,21 +500,25 @@ impl From<Cargo> for BootstrapCommand { |
| 480 | 500 | |
| 481 | 501 | cargo.command.args(cargo.args); |
| 482 | 502 | |
| 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. | |
| 487 | 507 | cargo.command.env_remove("RUSTFLAGS"); |
| 508 | cargo.command.env_remove("CARGO_ENCODED_RUSTFLAGS"); | |
| 488 | 509 | cargo.command.env_remove("RUSTDOCFLAGS"); |
| 510 | cargo.command.env_remove("CARGO_ENCODED_RUSTDOCFLAGS"); | |
| 489 | 511 | |
| 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); | |
| 493 | 516 | } |
| 494 | 517 | |
| 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); | |
| 498 | 522 | } |
| 499 | 523 | |
| 500 | 524 | 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 { |
| 3349 | 3349 | fn host_target() -> String { |
| 3350 | 3350 | get_host_target().to_string() |
| 3351 | 3351 | } |
| 3352 | ||
| 3353 | #[test] | |
| 3354 | fn 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 { |
| 7 | 7 | pub(crate) cdb: PathBuf, |
| 8 | 8 | } |
| 9 | 9 | |
| 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. | |
| 12 | 11 | pub(crate) fn discover_cdb(target: TargetSelection) -> Option<Cdb> { |
| 13 | 12 | if !cfg!(windows) || !target.ends_with("-pc-windows-msvc") { |
| 14 | 13 | return None; |
| 15 | 14 | } |
| 16 | 15 | |
| 17 | let pf86 = | |
| 18 | PathBuf::from(env::var_os("ProgramFiles(x86)").or_else(|| env::var_os("ProgramFiles"))?); | |
| 19 | 16 | let cdb_arch = if cfg!(target_arch = "x86") { |
| 20 | 17 | "x86" |
| 21 | 18 | } else if cfg!(target_arch = "x86_64") { |
| ... | ... | @@ -28,14 +25,28 @@ pub(crate) fn discover_cdb(target: TargetSelection) -> Option<Cdb> { |
| 28 | 25 | return None; // No compatible CDB.exe in the Windows 10 SDK |
| 29 | 26 | }; |
| 30 | 27 | |
| 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 | } | |
| 35 | 31 | |
| 36 | if !path.exists() { | |
| 37 | return None; | |
| 38 | } | |
| 32 | #[cfg(windows)] | |
| 33 | fn 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 | } | |
| 39 | 41 | |
| 40 | Some(Cdb { cdb: path }) | |
| 42 | #[cfg(not(windows))] | |
| 43 | fn discover_cdb_registry(_cdb_arch: &'static str) -> Option<PathBuf> { | |
| 44 | None | |
| 45 | } | |
| 46 | ||
| 47 | fn 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) | |
| 41 | 52 | } |
src/bootstrap/src/lib.rs+1-1| ... | ... | @@ -1280,7 +1280,7 @@ impl Build { |
| 1280 | 1280 | |
| 1281 | 1281 | /// Returns C flags that `cc-rs` thinks should be enabled for the |
| 1282 | 1282 | /// 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> { | |
| 1284 | 1284 | if self.config.dry_run() { |
| 1285 | 1285 | return Vec::new(); |
| 1286 | 1286 | } |
src/bootstrap/src/utils/cc_detect.rs+2-2| ... | ... | @@ -119,7 +119,7 @@ pub fn fill_target_compiler(build: &mut Build, target: TargetSelection) { |
| 119 | 119 | .or_else(|| cfg.try_get_archiver().map(|c| PathBuf::from(c.get_program())).ok()); |
| 120 | 120 | |
| 121 | 121 | 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); | |
| 123 | 123 | cflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::C)); |
| 124 | 124 | |
| 125 | 125 | // 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) { |
| 146 | 146 | build.do_if_verbose(|| println!("CC_{} = {:?}", target.triple, build.cc(target))); |
| 147 | 147 | build.do_if_verbose(|| println!("CFLAGS_{} = {cflags:?}", target.triple)); |
| 148 | 148 | 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); | |
| 150 | 150 | cxxflags.extend(build.cc_unhandled_cflags(target, GitRepo::Rustc, CLang::Cxx)); |
| 151 | 151 | build.do_if_verbose(|| println!("CXX_{} = {cxx:?}", target.triple)); |
| 152 | 152 | 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 \ |
| 26 | 26 | --enable-profiler \ |
| 27 | 27 | --enable-compiler-docs" |
| 28 | 28 | ENV 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 @@ |
| 1 | 8c75e93c5c7671c29f3e8c096b7acf56822ed23a | |
| 1 | 7fb284d9037fa54f6a9b24261c82b394472cbfd7 |
src/doc/rustc-dev-guide/src/SUMMARY.md+1| ... | ... | @@ -193,6 +193,7 @@ |
| 193 | 193 | - [Sharing the trait solver with rust-analyzer](./solve/sharing-crates-with-rust-analyzer.md) |
| 194 | 194 | - [`Unsize` and `CoerceUnsized` traits](./traits/unsize.md) |
| 195 | 195 | - [Having separate `Trait` and `Projection` bounds](./traits/separate-projection-bounds.md) |
| 196 | - [Well-formedness](./analysis/well-formed.md) | |
| 196 | 197 | - [Variance](./variance.md) |
| 197 | 198 | - [Coherence checking](./coherence.md) |
| 198 | 199 | - [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]. | |
| 6 | Something is _well-formed_ when its structure follows rules. | |
| 7 | When 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 | ||
| 11 | To check that something is well-formed is to perform a "Well-formedness check". | |
| 12 | ||
| 13 | In 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 | ||
| 23 | See: [What Well-Formedness Isn't](#what-well-formedness-isnt). | |
| 24 | ||
| 25 | ## Well-formedness of type-level terms | |
| 26 | ||
| 27 | Term well-formedness checking begins with building a list of things that need to be true for a term to be well-formed. | |
| 28 | We call these "Obligations"[^obligations]. | |
| 29 | ||
| 30 | Type-Level Terms are considered well-formed when their associated obligations are satisfied by the trait solver. | |
| 31 | ||
| 32 | ### Obligations for well-formedness | |
| 33 | ||
| 34 | Specific obligations are things like `String: Clone`, `A: usize`, or `<T as Iterator>::Item: Debug`. | |
| 35 | ||
| 36 | On 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 | ||
| 44 | Here is an example of a well-formed type-level term: | |
| 45 | ||
| 46 | ```rust,ignore | |
| 47 | Vec<String> | |
| 48 | --- | |
| 49 | // Obligations to fulfill | |
| 50 | Vec<T> where T: Sized | |
| 51 | // Trait solver says `String: Sized` is true, so this is well-formed. | |
| 52 | Vec<String> where String: Sized | |
| 53 | ``` | |
| 54 | ||
| 55 | When we compute the obligations for `Vec<String>`, we'll find that `Vec<T>` generates the obligation `T: Sized`. | |
| 56 | We substitute `T` with `String` in `Vec<String>`, so we find the obligation `String: Sized` which the trait solver will determine to be satisfied. | |
| 57 | ||
| 58 | The following **is not** well-formed: | |
| 59 | ||
| 60 | ```rust,ignore | |
| 61 | Vec<str> | |
| 62 | --- | |
| 63 | // Obligations to fulfill | |
| 64 | Vec<T> where T: Sized | |
| 65 | // Trait solver says `str: Sized` is not true, so this is not well-formed. | |
| 66 | Vec<str> where str: Sized | |
| 67 | ``` | |
| 68 | ||
| 69 | The 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`. | |
| 70 | This obligation will be determined by the trait solver to be _unsatisfied_. | |
| 71 | ||
| 72 | #### Determining obligations | |
| 73 | ||
| 74 | In 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 | ||
| 78 | Obligations 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. | |
| 79 | See: [`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 | ||
| 85 | A type alias is considered well-formed if its where clauses are satisfied. | |
| 86 | The underlying type undergoes well-formedness checking at most definition and instantiation sites, but there are exceptions. | |
| 87 | ||
| 88 | ### Const generic arguments | |
| 89 | ||
| 90 | Term well-formedness is responsible for getting "type checking" obligations of const generic terms[^tyck-const-generics]. | |
| 91 | Let's look at the following use of const generics: | |
| 92 | ||
| 93 | ```rust,ignore | |
| 94 | fn use_const_generics<const U: usize>() { /* ... */ } | |
| 95 | // call site | |
| 96 | use_const_generics::<6>(); | |
| 97 | --- | |
| 98 | // call site wfck obligations | |
| 99 | const 6: usize | |
| 100 | ``` | |
| 101 | ||
| 102 | The call site will provide us with the obligation `6: usize` during well-formedness checking. | |
| 103 | This 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 | ||
| 107 | Items are, generally speaking, "Things that get defined". | |
| 108 | Item-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 | |
| 112 | fn 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 | --- | |
| 117 | Vec<str>: Sized // Generated | |
| 118 | Vec<[u8]>: Sized // Not done at item-wfck. Done elsewhere. | |
| 119 | ``` | |
| 120 | ||
| 121 | Item-wfck has more responsibilities than only collecting the obligations of its internal type-level terms and passing them to the trait solver. | |
| 122 | We 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 | ||
| 130 | Trait bounds are a common Obligation. | |
| 131 | Global and Trivial trait bounds are kinds of trait bounds where we already have enough information to determine if they are true or false. | |
| 132 | Item-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 | ||
| 137 | Consider the following function definition: | |
| 138 | ||
| 139 | ```rust,ignore | |
| 140 | fn apartment_complex<T>(block: T, name: String) where String: Clone { /* ... */ } | |
| 141 | --- | |
| 142 | String: 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 | ||
| 146 | This produces a trait bound obligation `String: Clone` that is _Global_ (no generic parameters) and _Trivial_ (didn't require normalization to be well-formedness checked). | |
| 147 | The 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 | ||
| 149 | False trivial bounds are simply trivial bounds that do not hold. | |
| 150 | The following is a basic example: | |
| 151 | ||
| 152 | ```rust,ignore | |
| 153 | fn apartment_simple<T>(block: T, name: String) where String: Copy { /* ... */ } | |
| 154 | --- | |
| 155 | String: Copy // Trivial bound again, but this one is false! | |
| 156 | ``` | |
| 157 | ||
| 158 | Here we have a trivial bound that does not hold, because `String` is not `Copy`. | |
| 159 | ||
| 160 | #### Trivial bounds are not always global | |
| 161 | ||
| 162 | Trivial Bounds are not a subset of Global Bounds. | |
| 163 | A 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 | ||
| 169 | When 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 | ||
| 173 | Well-formedness checking is not a coherent "stage" of type checking. | |
| 174 | There 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. | |
| 175 | Ideally, we would never skip or defer well-formedness checking. | |
| 176 | ||
| 177 | ### We (sometimes) need normalization | |
| 178 | ||
| 179 | There are places where normalization of an Item happens before its Terms have gone through well-formedness checking. | |
| 180 | This 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 | ||
| 184 | We do not require the where clauses of trait objects to be well-formed when determining if that trait object is well-formed. | |
| 185 | These where clauses are proven when coercing into a trait object, but this remains a hole in well-formedness checking. | |
| 186 | ||
| 187 | As 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 | |
| 190 | trait Trait | |
| 191 | where | |
| 192 | for<'a> [u8]: Sized {} | |
| 193 | ||
| 194 | fn foo(_: &dyn Trait) {} | |
| 195 | --- | |
| 196 | // This doesn't end up being generated, because it happens within a trait object. | |
| 197 | [u8]: Sized | |
| 198 | ``` | |
| 199 | ||
| 200 | The above should not compile because `[u8]: Sized`, but this won't be checked until actual use: | |
| 201 | ||
| 202 | ```rust | |
| 203 | trait Trait | |
| 204 | where | |
| 205 | for<'a> [u8]: Sized {} | |
| 206 | ||
| 207 | fn foo(_: &dyn Trait) {} | |
| 208 | ||
| 209 | // We still need to specify the bound here, otherwise `[u8]: Sized` _is_ | |
| 210 | // checked as an obligation. | |
| 211 | impl Trait for u8 where for<'a> [u8]: Sized {} | |
| 212 | ||
| 213 | fn 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 | ||
| 222 | This exception does not apply to Const Generic Arguments in trait objects: | |
| 223 | ||
| 224 | ```rust,ignore | |
| 225 | trait Trait<const N: usize> {} | |
| 226 | fn foo<const B: bool>(_: &dyn Trait<B>) {} | |
| 227 | --- | |
| 228 | const N: usize | |
| 229 | const B: bool | |
| 230 | N = B // Substitution | |
| 231 | const B: usize + bool | |
| 232 | ``` | |
| 233 | ||
| 234 | The above doesn't compile, unlike the previous example we gave. | |
| 235 | We're doing _some_ well-formedness checking here when it comes to the const generic arguments. | |
| 236 | ||
| 237 | ### Binders / higher-ranked types | |
| 238 | ||
| 239 | Binders / 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 | |
| 242 | let _: 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 | ||
| 248 | Specifically, obligations involving variables from binders (`for<'a>`) are only checked when the binder is instantiated. | |
| 249 | Some things are stilled checked under the `for<'a>`, but we still skip a lot of things. | |
| 250 | ||
| 251 | A lot of unsoundness surrounds this behavior. | |
| 252 | See: [#25860](https://github.com/rust-lang/rust/issues/25860), [#84591](https://github.com/rust-lang/rust/issues/84591). | |
| 253 | ||
| 254 | Let's consider the following: | |
| 255 | ||
| 256 | ```rust,ignore | |
| 257 | for<'a, 'b> fn(&'a &'b ()) | |
| 258 | ``` | |
| 259 | ||
| 260 | The above HRB implies `'b: 'a` (a lifetime bound), rather than two completely separate lifetimes. | |
| 261 | This 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 | ||
| 265 | The 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 | ||
| 267 | The following free type alias passes type checking, at time of writing: | |
| 268 | ||
| 269 | ```rust,ignore | |
| 270 | type WorksButShouldNot = Vec<str>; | |
| 271 | --- | |
| 272 | // This should fail! But we skip the RHS of free type aliases | |
| 273 | str: Sized // Not generated | |
| 274 | ``` | |
| 275 | ||
| 276 | This shouldn't work, as both `T: Sized`, `str: Sized` are implied by `Vec<T>`. | |
| 277 | This "passes" item-wfck because the RHS of a free type alias doesn't go through well-formedness checking _until it's used_. | |
| 278 | Item-wfck is **deferred until use** for this specific case. | |
| 279 | ||
| 280 | For Const Generics we still do a small amount of well-formedness checking at the definition site of a free type alias. | |
| 281 | This is consistent with our current special-casing of const generic well-formedness checking when we skip over things like where bounds. | |
| 282 | ||
| 283 | This means that the following, despite being of a similar form to the above example, fails as it should: | |
| 284 | ||
| 285 | ```rust,ignore | |
| 286 | pub struct Consty<const A: bool>; | |
| 287 | type Alias = Consty<42>; | |
| 288 | --- | |
| 289 | // This *is* generated as an obligation, so this (correctly) fails. | |
| 290 | 42: 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 | ||
| 297 | Prefer "well-formed" over "wellformed", as this is consistent with logic literature. | |
| 298 | This also gets abbreviated to WF in other parts of the dev guide / docs. | |
| 299 | ||
| 300 | ## Informal usage | |
| 301 | ||
| 302 | In 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. | |
| 303 | This isn't necessarily in error, but it should be looked out for. | |
| 304 | ||
| 305 | ## What well-formedness isn't | |
| 306 | ||
| 307 | Well-formedness checking is not "number of parameters" or "parameter type" checking[^kind-checking]. | |
| 308 | Neither 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. | |
| 309 | These kinds of problems will get handled during HIR-ty Lowering[^hir-ty-lower], not wfck. | |
| 310 | ||
| 311 | Well-formedness doesn't check or validate lifetimes, this is handled in [MIR](../borrow-check.md). | |
| 312 | ||
| 313 | Well-formedness in the Rust compiler doesn't correspond to "correct syntax" as it does in logic. | |
| 314 | The term has a history of general use in a mathematical context of "follows a given set of rules". | |
| 315 | In 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 |
| 102 | 102 | <span id="trans">trans 👎</span> | Short for _translation_, the code to translate MIR into LLVM IR. **Renamed to** [codegen](#codegen). |
| 103 | 103 | <span id="ty">`Ty`</span> | The internal representation of a type. ([see more](../ty.md)) |
| 104 | 104 | <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. | |
| 105 | 106 | <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)) |
| 106 | 107 | <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_. |
| 107 | 108 | <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: |
| 18 | 18 | rustup +nightly component add enzyme |
| 19 | 19 | ``` |
| 20 | 20 | |
| 21 | ## Installation guide for Nix user. | |
| 21 | ## Installation guide for Nix | |
| 22 | ||
| 23 | On [Nix], you can declare a nightly Rust toolchain with the Enzyme component using the [oxalica rust-overlay]. | |
| 24 | ||
| 25 | For example: | |
| 26 | ||
| 27 | ```nix | |
| 28 | rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override { | |
| 29 | extensions = [ "enzyme" ]; | |
| 30 | }) | |
| 31 | ``` | |
| 32 | ||
| 33 | Alternatively, you can create a [toolchain file] that declares the Enzyme component such as | |
| 34 | ||
| 35 | ```toml | |
| 36 | [toolchain] | |
| 37 | channel = "nightly-2026-06-23" | |
| 38 | components = [ "enzyme" ] | |
| 39 | ``` | |
| 40 | ||
| 41 | and consume it in the overlay | |
| 22 | 42 | |
| 23 | This setup was recommended by a nix and autodiff user. | |
| 24 | It uses [`Overlay`]. | |
| 25 | Please verify for yourself if you are comfortable using that repository. | |
| 26 | In that case you might use the following nix configuration to get a rustc that supports `std::autodiff`. | |
| 27 | 43 | ```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 | } | |
| 44 | rust-bin.fromRustupToolchainFile ./rust-toolchain.toml | |
| 45 | 45 | ``` |
| 46 | 46 | |
| 47 | 47 | ## Build instructions |
| ... | ... | @@ -135,4 +135,6 @@ This will build Enzyme, and you can find it in `Enzyme/enzyme/build/lib/<LLD/Cla |
| 135 | 135 | (Endings might differ based on your OS). |
| 136 | 136 | |
| 137 | 137 | [`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 @@ |
| 1 | 1 | # `cfg(bootstrap)` in compiler dependencies |
| 2 | 2 | |
| 3 | The 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. | |
| 3 | The Rust compiler uses some external crates that can run into cyclic dependencies with the compiler itself: | |
| 4 | the compiler needs an updated crate to build, but the crate needs an updated compiler. | |
| 5 | This page describes how `#[cfg(bootstrap)]` can be used to break this cycle. | |
| 4 | 6 | |
| 5 | 7 | ## Enabling `#[cfg(bootstrap)]` |
| 6 | 8 | |
| ... | ... | @@ -38,7 +40,7 @@ As a concrete example we'll use a change where the `#[naked]` attribute was made |
| 38 | 40 | |
| 39 | 41 | ### Step 1: accept the new behavior in the compiler ([#139797](https://github.com/rust-lang/rust/pull/139797)) |
| 40 | 42 | |
| 41 | In this example it is possible to accept both the old and new behavior at the same time by disabling an error. | |
| 43 | In this example, it is possible to accept both the old and new behavior at the same time by disabling an error. | |
| 42 | 44 | |
| 43 | 45 | ### Step 2: update the crate ([#821](https://github.com/rust-lang/compiler-builtins/pull/821)) |
| 44 | 46 | |
| ... | ... | @@ -50,4 +52,5 @@ For `compiler-builtins` this meant a version bump, in other cases it may be a gi |
| 50 | 52 | |
| 51 | 53 | ### Step 4: remove the old behavior from the compiler ([#139753](https://github.com/rust-lang/rust/pull/139753)) |
| 52 | 54 | |
| 53 | The updated crate can now be used. In this example that meant that the old behavior could be removed. | |
| 55 | The updated crate can now be used. | |
| 56 | In 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 @@ |
| 1 | 1 | # Debugging bootstrap |
| 2 | 2 | |
| 3 | There are two main ways of debugging (and profiling bootstrap). The first is through println logging, and the second is through the `tracing` feature. | |
| 3 | There are two main ways of debugging (and profiling bootstrap). | |
| 4 | The first is through println logging, and the second is through the `tracing` feature. | |
| 4 | 5 | |
| 5 | 6 | ## `println` logging |
| 6 | 7 | |
| 7 | Bootstrap has extensive unstructured logging. Most of it is gated behind the `--verbose` flag (pass `-vv` for even more detail). | |
| 8 | Bootstrap has extensive unstructured logging. | |
| 9 | Most of it is gated behind the `--verbose` flag (pass `-vv` for even more detail). | |
| 8 | 10 | |
| 9 | If 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. | |
| 11 | If you want to see verbose output of executed Cargo commands and other kinds of detailed logs, pass `-v` or `-vv` when invoking bootstrap. | |
| 12 | Note that the logs are unstructured and may be overwhelming. | |
| 10 | 13 | |
| 11 | 14 | ``` |
| 12 | 15 | $ ./x dist rustc --dry-run -vv |
| ... | ... | @@ -27,7 +30,8 @@ Bootstrap has a conditional `tracing` feature, which provides the following feat |
| 27 | 30 | - 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. |
| 28 | 31 | - The generated `command-stats.txt` file is in a simple human-readable format. |
| 29 | 32 | |
| 30 | The 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`. | |
| 33 | The 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. | |
| 34 | For convenience, bootstrap will also create a symlink to the latest generated trace output directory at `<build-dir>/bootstrap-trace/latest`. | |
| 31 | 35 | |
| 32 | 36 | > 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. |
| 33 | 37 | |
| ... | ... | @@ -73,18 +77,24 @@ Build completed successfully in 0:00:00 |
| 73 | 77 | |
| 74 | 78 | #### Controlling tracing output |
| 75 | 79 | |
| 76 | The 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. | |
| 80 | The environment variable `BOOTSTRAP_TRACING` accepts a [`tracing_subscriber` filter][tracing-env-filter]. | |
| 81 | If you set `BOOTSTRAP_TRACING=trace`, you will enable all logs, but that can be overwhelming. | |
| 82 | You can thus use the filter to reduce the amount of data logged. | |
| 77 | 83 | |
| 78 | 84 | There are two orthogonal ways to control which kind of tracing logs you want: |
| 79 | 85 | |
| 80 | 86 | 1. You can specify the log **level**, e.g. `debug` or `trace`. |
| 81 | 87 | - If you select a level, all events/spans with an equal or higher priority level will be shown. |
| 82 | 88 | 2. 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: | |
| 84 | 91 | - `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. | |
| 88 | 98 | - Note that many I/O are currently not being traced. |
| 89 | 99 | |
| 90 | 100 | You 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 |
| 100 | 110 | ##### FIXME(#96176): specific tracing for `compiler()` vs `compiler_for()` |
| 101 | 111 | |
| 102 | 112 | The additional targets `COMPILER` and `COMPILER_FOR` are used to help trace what |
| 103 | `builder.compiler()` and `builder.compiler_for()` does. They should be removed | |
| 104 | if [#96176][cleanup-compiler-for] is resolved. | |
| 113 | `builder.compiler()` and `builder.compiler_for()` does. | |
| 114 | They should be removed if [#96176][cleanup-compiler-for] is resolved. | |
| 105 | 115 | |
| 106 | 116 | [cleanup-compiler-for]: https://github.com/rust-lang/rust/issues/96176 |
| 107 | 117 | |
| 108 | 118 | ### Using `tracing` in bootstrap |
| 109 | 119 | |
| 110 | Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. Examples: | |
| 120 | Both `tracing::*` macros and the `tracing::instrument` proc-macro attribute need to be gated behind `tracing` feature. | |
| 121 | Examples: | |
| 111 | 122 | |
| 112 | 123 | ```rs |
| 113 | 124 | #[cfg(feature = "tracing")] |
src/doc/rustc-dev-guide/src/building/bootstrapping/how-bootstrap-does-it.md+8-6| ... | ... | @@ -1,14 +1,16 @@ |
| 1 | 1 | # How Bootstrap does it |
| 2 | 2 | |
| 3 | 3 | The core concept in Bootstrap is a build [`Step`], which are chained together |
| 4 | by [`Builder::ensure`]. [`Builder::ensure`] takes a [`Step`] as input, and runs | |
| 5 | the [`Step`] if and only if it has not already been run. Let's take a closer | |
| 6 | look at [`Step`]. | |
| 4 | by [`Builder::ensure`]. | |
| 5 | [`Builder::ensure`] takes a [`Step`] as input, and runs | |
| 6 | the [`Step`] if and only if it has not already been run. | |
| 7 | Let's take a closer look at [`Step`]. | |
| 7 | 8 | |
| 8 | 9 | ## Synopsis of [`Step`] |
| 9 | 10 | |
| 10 | 11 | A [`Step`] represents a granular collection of actions involved in the process |
| 11 | of producing some artifact. It can be thought of like a rule in Makefiles. | |
| 12 | of producing some artifact. | |
| 13 | It can be thought of like a rule in Makefiles. | |
| 12 | 14 | The [`Step`] trait is defined as: |
| 13 | 15 | |
| 14 | 16 | ```rs,no_run |
| ... | ... | @@ -30,8 +32,8 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash { |
| 30 | 32 | - `run` is the function that is responsible for doing the work. |
| 31 | 33 | [`Builder::ensure`] invokes `run`. |
| 32 | 34 | - `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. | |
| 35 | 37 | - `make_run` is invoked only for things directly asked via the CLI and not |
| 36 | 38 | for steps which are dependencies of other steps. |
| 37 | 39 |
src/doc/rustc-dev-guide/src/building/bootstrapping/intro.md+9-11| ... | ... | @@ -1,14 +1,13 @@ |
| 1 | 1 | # Bootstrapping the compiler |
| 2 | 2 | |
| 3 | [*Bootstrapping*][boot] is the process of using a compiler to compile itself. | |
| 4 | More accurately, it means using an older compiler to compile a newer version | |
| 5 | of the same compiler. | |
| 3 | [*Bootstrapping*] is the process of using a compiler to compile itself. | |
| 4 | More accurately, it means using an older compiler to compile a newer version of the same compiler. | |
| 6 | 5 | |
| 7 | 6 | This raises a chicken-and-egg paradox: where did the first compiler come from? |
| 8 | It 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 | |
| 10 | only way to build a modern version of rustc is with a slightly less modern | |
| 11 | version. | |
| 7 | It must have been written in a different language. | |
| 8 | In Rust's case it was [written in OCaml]. | |
| 9 | However, it was abandoned long ago, and the | |
| 10 | only way to build a modern version of rustc is with a slightly less modern version. | |
| 12 | 11 | |
| 13 | 12 | This is exactly how `x.py` works: it downloads the current beta release of |
| 14 | 13 | rustc, then uses it to compile the new compiler. |
| ... | ... | @@ -17,8 +16,7 @@ In this section, we give a high-level overview of |
| 17 | 16 | [what Bootstrap does](./what-bootstrapping-does.md), followed by a high-level |
| 18 | 17 | introduction to [how Bootstrap does it](./how-bootstrap-does-it.md). |
| 19 | 18 | |
| 20 | Additionally, see [debugging bootstrap](./debugging-bootstrap.md) to learn | |
| 21 | about debugging methods. | |
| 19 | Additionally, see [debugging bootstrap](./debugging-bootstrap.md) to learn about debugging methods. | |
| 22 | 20 | |
| 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. |
| 236 | 236 | |
| 237 | 237 | For details, see [the chapter on tracing](./tracing.md). |
| 238 | 238 | |
| 239 | ## Narrowing (Bisecting) Regressions | |
| 239 | ## Narrowing (bisecting) regressions | |
| 240 | 240 | |
| 241 | 241 | The [cargo-bisect-rustc][bisect] tool can be used as a quick and easy way to |
| 242 | 242 | find 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. |
| 248 | 248 | [bisect]: https://github.com/rust-lang/cargo-bisect-rustc |
| 249 | 249 | [bisect-tutorial]: https://rust-lang.github.io/cargo-bisect-rustc/tutorial.html |
| 250 | 250 | |
| 251 | ## Downloading Artifacts from Rust's CI | |
| 251 | ## Downloading artifacts from Rust's CI | |
| 252 | 252 | |
| 253 | 253 | The [rustup-toolchain-install-master][rtim] tool by kennytm can be used to |
| 254 | 254 | download 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, |
| 257 | 257 | since it takes a very long time to execute. |
| 258 | 258 | See the [Testing with CI] chapter for using Rust's CI to test your changes. |
| 259 | 259 | |
| 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 | |
| 261 | 261 | |
| 262 | 262 | ### r+ |
| 263 | 263 | |
| ... | ... | @@ -425,7 +425,7 @@ Just a few things to keep in mind: |
| 425 | 425 | |
| 426 | 426 | - When contributing text to the guide, please contextualize the information with some time period |
| 427 | 427 | 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: | |
| 429 | 429 | |
| 430 | 430 | - A reason for why the text may be out of date other than "change", |
| 431 | 431 | as change is a constant across the project. |
| ... | ... | @@ -444,29 +444,29 @@ Just a few things to keep in mind: |
| 444 | 444 | For the action to pick the date, add a special annotation before specifying the date: |
| 445 | 445 | |
| 446 | 446 | ```md |
| 447 | <!-- date-check --> Nov 2025 | |
| 447 | <!-- date-check --> Jul 2026 | |
| 448 | 448 | ``` |
| 449 | 449 | |
| 450 | 450 | Example: |
| 451 | 451 | |
| 452 | 452 | ```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. | |
| 454 | 454 | ``` |
| 455 | 455 | |
| 456 | 456 | For cases where the date should not be part of the visible rendered output, |
| 457 | 457 | use the following instead: |
| 458 | 458 | |
| 459 | 459 | ```md |
| 460 | <!-- date-check: Nov 2025 --> | |
| 460 | <!-- date-check: Jul 2026 --> | |
| 461 | 461 | ``` |
| 462 | 462 | |
| 463 | 463 | - A link to a relevant WG, tracking issue, `rustc` rustdoc page, or similar, that may provide |
| 464 | 464 | further explanation for the change process or a way to verify that the information is not |
| 465 | 465 | outdated. |
| 466 | 466 | |
| 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. | |
| 470 | 470 | |
| 471 | 471 | #### ⚠️ Note: Where to contribute `rustc-dev-guide` changes |
| 472 | 472 |
src/doc/rustc-dev-guide/src/offload/installation.md+1-1| ... | ... | @@ -44,7 +44,7 @@ Run this test script for offload-specific tests: |
| 44 | 44 | ./x test --stage 1 tests/codegen-llvm/gpu_offload |
| 45 | 45 | ``` |
| 46 | 46 | |
| 47 | For testing the CI locally, you may use the commands outlined in [Testing with Docker](https://rustc-dev-guide.rust-lang.org/tests/docker.html): | |
| 47 | For testing the CI locally, you may use the commands outlined in [Testing with Docker](../tests/docker.md): | |
| 48 | 48 | ```console |
| 49 | 49 | cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux |
| 50 | 50 | ``` |
src/doc/rustc-dev-guide/src/tests/best-practices.md+1-1| ... | ... | @@ -171,7 +171,7 @@ place. |
| 171 | 171 | If a test suite can |
| 172 | 172 | randomly spuriously fail due to flaky tests, did the whole test suite pass or |
| 173 | 173 | 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. | |
| 175 | 175 | |
| 176 | 176 | ## Compiletest directives |
| 177 | 177 |
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. |
| 209 | 209 | > |
| 210 | 210 | > 3. Run the prescribed try jobs with `@bors try`. As aforementioned, this |
| 211 | 211 | > 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` | |
| 213 | 213 | > permissions. |
| 214 | 214 | > |
| 215 | 215 | > 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 |
| 8 | 8 | It 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. |
| 9 | 9 | |
| 10 | 10 | This is unfortunately quite difficult, as we may use a different candidate for norm than for the corresponding trait bound. |
| 11 | See [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). | |
| 11 | See [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). | |
| 12 | 12 | |
| 13 | 13 | There are also some other subtle reasons for why we can't do so. |
| 14 | 14 | The 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 | ||
| 3 | Configures codegen to always use the fallback body of an intrinsic, if it has one, | |
| 4 | instead of lowering the intrinsic in the codegen backend. | |
| 5 | ||
| 6 | This is useful for testing the fallback implementation. |
src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | #![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 | |
| 3 | 3 | #![allow(static_mut_refs)] |
| 4 | 4 | |
| 5 | 5 | #[derive(Debug)] |
src/tools/clippy/tests/ui/redundant_static_lifetimes.rs+1-1| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | #![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 | |
| 3 | 3 | #![allow(static_mut_refs)] |
| 4 | 4 | |
| 5 | 5 | #[derive(Debug)] |
src/tools/clippy/tests/ui/useless_conversion.fixed+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | #![deny(clippy::useless_conversion)] |
| 2 | 2 | #![allow(clippy::into_iter_on_ref)] |
| 3 | 3 | #![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 | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | use std::ops::ControlFlow; |
src/tools/clippy/tests/ui/useless_conversion.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | #![deny(clippy::useless_conversion)] |
| 2 | 2 | #![allow(clippy::into_iter_on_ref)] |
| 3 | 3 | #![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 | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | use std::ops::ControlFlow; |
src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@only-target: linux android |
| 2 | 2 | //@compile-flags: -Zmiri-disable-isolation |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | use std::mem::MaybeUninit; |
src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | //! the fallback path in `guard::key::enable`, which uses a *single* pthread_key |
| 6 | 6 | //! to manage a thread-local list of dtors to call. |
| 7 | 7 | |
| 8 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 8 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 9 | 9 | #![allow(static_mut_refs)] |
| 10 | 10 | |
| 11 | 11 | use std::{mem, ptr}; |
src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | 4 | //@run-native |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | use std::{io, thread}; |
src/tools/miri/tests/pass-dep/libc/libc-pipe.rs+1-1| ... | ... | @@ -69,7 +69,7 @@ fn test_pipe_threaded() { |
| 69 | 69 | thread2.join().unwrap(); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 72 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 73 | 73 | #[allow(static_mut_refs)] |
| 74 | 74 | fn test_race() { |
| 75 | 75 | static mut VAL: u8 = 0; |
src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | //@compile-flags: -Zmiri-deterministic-concurrency |
| 4 | 4 | //@run-native |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | use std::thread; |
src/tools/miri/tests/pass/atomic.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | //@[tree]compile-flags: -Zmiri-tree-borrows |
| 4 | 4 | //@compile-flags: -Zmiri-strict-provenance |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | use 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 | |
| 2 | 2 | #![allow(static_mut_refs)] |
| 3 | 3 | |
| 4 | 4 | use 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 | |
| 2 | 2 | #![allow(static_mut_refs)] |
| 3 | 3 | |
| 4 | 4 | use std::ptr::addr_of; |
src/tools/miri/tests/pass/tls/tls_static.rs+1-1| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | //! dereferencing the pointer on `t2` resolves to `t1`'s thread-local. In this |
| 9 | 9 | //! test, we also check that thread-locals act as per-thread statics. |
| 10 | 10 | |
| 11 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 11 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 12 | 12 | #![allow(static_mut_refs)] |
| 13 | 13 | #![feature(thread_local)] |
| 14 | 14 |
src/tools/tidy/src/issues.txt-2| ... | ... | @@ -2324,8 +2324,6 @@ ui/resolve/issue-2356.rs |
| 2324 | 2324 | ui/resolve/issue-23716.rs |
| 2325 | 2325 | ui/resolve/issue-24968.rs |
| 2326 | 2326 | ui/resolve/issue-26545.rs |
| 2327 | ui/resolve/issue-3021-c.rs | |
| 2328 | ui/resolve/issue-3021.rs | |
| 2329 | 2327 | ui/resolve/issue-30535.rs |
| 2330 | 2328 | ui/resolve/issue-3099-a.rs |
| 2331 | 2329 | ui/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) { |
| 51 | 51 | // The full-path doesn't exists, maybe it's a glob, let's add it to the glob set builder |
| 52 | 52 | // to be checked against all the file and directories in the repository. |
| 53 | 53 | 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 | ); | |
| 55 | 60 | glob_entries.push(clean_path.to_string()); |
| 56 | 61 | } else if is_in_submodule(Path::new(clean_path)) { |
| 57 | 62 | 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] | |
| 13 | pub 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] | |
| 29 | pub 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"] | |
| 5 | pub trait PointeeSized {} | |
| 6 | ||
| 7 | #[lang = "meta_sized"] | |
| 8 | pub trait MetaSized: PointeeSized {} | |
| 9 | ||
| 10 | #[lang = "sized"] | |
| 11 | trait Sized {} | |
| 12 | ||
| 13 | pub 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 | ||
| 6 | use run_make_support::rustc; | |
| 7 | ||
| 8 | fn 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 | |
| 7 | fn f() {} |
tests/rustdoc-ui/doc-auto-cfg-values-non-ident.stderr created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | error[E0565]: malformed `doc` attribute input | |
| 2 | --> $DIR/doc-auto-cfg-values-non-ident.rs:5:1 | |
| 3 | | | |
| 4 | LL | #[doc(auto_cfg(hide(a, values(::b))))] | |
| 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^^ | |
| 6 | | | | |
| 7 | | expected a valid identifier here | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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` |
| 4 | 4 | LL | #[doc(cfg(foo), cfg(bar))] |
| 5 | 5 | | ^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `FALSE` and `test` and 32 more | |
| 7 | = help: expected names are: `FALSE` and `test` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(foo)` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = note: `#[warn(unexpected_cfgs)]` on by default |
tests/ui/abi/statics/static-mut-foreign.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | // statics cannot. This ensures that there's some form of error if this is |
| 4 | 4 | // attempted. |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | use std::ffi::c_int; |
tests/ui/array-slice-vec/slice-panic-1.rs+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | |
| 6 | 6 | // Test that if a slicing expr[..] fails, the correct cleanups happen. |
| 7 | 7 | |
| 8 | // FIXME(static_mut_refs): this could use an atomic | |
| 8 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 9 | 9 | #![allow(static_mut_refs)] |
| 10 | 10 | |
| 11 | 11 | use std::thread; |
tests/ui/array-slice-vec/slice-panic-2.rs+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | |
| 6 | 6 | // Test that if a slicing expr[..] fails, the correct cleanups happen. |
| 7 | 7 | |
| 8 | // FIXME(static_mut_refs): this could use an atomic | |
| 8 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 9 | 9 | #![allow(static_mut_refs)] |
| 10 | 10 | |
| 11 | 11 | use std::thread; |
tests/ui/array-slice-vec/slice.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | |
| 4 | 4 | // Test slicing sugar. |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): this could use an atomic | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | extern 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 | ||
| 5 | pub trait MakeRef<'a> { | |
| 6 | type Ref; | |
| 7 | } | |
| 8 | impl<'a, T: 'a> MakeRef<'a> for T { | |
| 9 | type Ref = &'a T; | |
| 10 | } | |
| 11 | ||
| 12 | pub trait MakeRef2 { | |
| 13 | type Ref2; | |
| 14 | } | |
| 15 | impl<'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 | ||
| 20 | fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") } | |
| 21 | //~^ ERROR temporary value dropped while borrowed | |
| 22 | ||
| 23 | fn main() { | |
| 24 | println!("{}", foo()); | |
| 25 | } |
tests/ui/associated-types/unconstrained-lifetime-in-projection.stderr created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | error[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 | | | |
| 4 | LL | impl<'a, T: 'a> MakeRef2 for T { | |
| 5 | | ^^ unconstrained lifetime parameter | |
| 6 | ||
| 7 | error[E0716]: temporary value dropped while borrowed | |
| 8 | --> $DIR/unconstrained-lifetime-in-projection.rs:20:43 | |
| 9 | | | |
| 10 | LL | 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 | ||
| 18 | error: aborting due to 2 previous errors | |
| 19 | ||
| 20 | Some errors have detailed explanations: E0207, E0716. | |
| 21 | For 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 @@ |
| 1 | 1 | //@ build-pass |
| 2 | 2 | //@ edition:2018 |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | static 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")] | |
| 7 | macro_rules! foo { | |
| 8 | () => { | |
| 9 | 32 | |
| 10 | }; | |
| 11 | } | |
| 12 | ||
| 13 | #[recursion_limit = concat!("1", "2")] | |
| 14 | macro_rules! baz { | |
| 15 | () => { | |
| 16 | 32 | |
| 17 | }; | |
| 18 | } | |
| 19 | ||
| 20 | #[type_length_limit = concat!("1", "2")] | |
| 21 | macro_rules! qux { | |
| 22 | () => { | |
| 23 | 32 | |
| 24 | }; | |
| 25 | } | |
| 26 | ||
| 27 | #[windows_subsystem = concat!("cons", "ole")] | |
| 28 | macro_rules! bar { | |
| 29 | () => { | |
| 30 | 32 | |
| 31 | }; | |
| 32 | } | |
| 33 | ||
| 34 | fn main() {} |
tests/ui/binding/order-drop-with-match.rs+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | // in ORDER matching up to when it ran. |
| 6 | 6 | // Correct order is: matched, inner, outer |
| 7 | 7 | |
| 8 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 8 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 9 | 9 | #![allow(static_mut_refs)] |
| 10 | 10 | |
| 11 | 11 | static mut ORDER: [usize; 3] = [0, 0, 0]; |
tests/ui/binding/ref-pattern-drop-behavior-8860.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // https://github.com/rust-lang/rust/issues/8860 |
| 2 | 2 | //@ run-pass |
| 3 | // FIXME(static_mut_refs): this could use an atomic | |
| 3 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 4 | 4 | #![allow(static_mut_refs)] |
| 5 | 5 | #![allow(dead_code)] |
| 6 | 6 |
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 | ||
| 6 | fn 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 @@ |
| 8 | 8 | //@ revisions: target_object_format_ target_pointer_width_ target_vendor_ |
| 9 | 9 | //@ revisions: target_has_atomic_ target_has_atomic_primitive_alignment_ |
| 10 | 10 | //@ revisions: target_has_atomic_load_store_ target_thread_local_ relocation_model_ |
| 11 | //@ revisions: target_has_threads_ | |
| 11 | 12 | //@ revisions: fmt_debug_ |
| 12 | 13 | //@ revisions: reliable_f16_ reliable_f16_math_ reliable_f128_ reliable_f128_math_ |
| 13 | 14 | |
| ... | ... | @@ -34,6 +35,7 @@ |
| 34 | 35 | //@ [target_has_atomic_]compile-flags: --cfg target_has_atomic="32" |
| 35 | 36 | //@ [target_has_atomic_primitive_alignment_]compile-flags: --cfg target_has_atomic_primitive_alignment="32" |
| 36 | 37 | //@ [target_has_atomic_load_store_]compile-flags: --cfg target_has_atomic_load_store="32" |
| 38 | //@ [target_has_threads_]compile-flags: --cfg target_has_threads | |
| 37 | 39 | //@ [target_thread_local_]compile-flags: --cfg target_thread_local |
| 38 | 40 | //@ [relocation_model_]compile-flags: --cfg relocation_model="a" |
| 39 | 41 | //@ [fmt_debug_]compile-flags: --cfg fmt_debug="shallow" |
tests/ui/cfg/disallowed-cli-cfgs.target_has_threads_.stderr created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | error: 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 | ||
| 7 | error: 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` |
| 4 | 4 | LL | #[cfg(has_foo)] |
| 5 | 5 | | ^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `has_bar` and 32 more | |
| 7 | = help: expected names are: `has_bar` and 33 more | |
| 8 | 8 | = help: consider using a Cargo feature instead |
| 9 | 9 | = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: |
| 10 | 10 | [lints.rust] |
tests/ui/check-cfg/cargo-feature.none.stderr+1-1| ... | ... | @@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable` |
| 25 | 25 | LL | #[cfg(tokio_unstable)] |
| 26 | 26 | | ^^^^^^^^^^^^^^ |
| 27 | 27 | | |
| 28 | = help: expected names are: `docsrs`, `feature`, and `test` and 32 more | |
| 28 | = help: expected names are: `docsrs`, `feature`, and `test` and 33 more | |
| 29 | 29 | = help: consider using a Cargo feature instead |
| 30 | 30 | = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: |
| 31 | 31 | [lints.rust] |
tests/ui/check-cfg/cargo-feature.some.stderr+1-1| ... | ... | @@ -25,7 +25,7 @@ warning: unexpected `cfg` condition name: `tokio_unstable` |
| 25 | 25 | LL | #[cfg(tokio_unstable)] |
| 26 | 26 | | ^^^^^^^^^^^^^^ |
| 27 | 27 | | |
| 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 | |
| 29 | 29 | = help: consider using a Cargo feature instead |
| 30 | 30 | = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint: |
| 31 | 31 | [lints.rust] |
tests/ui/check-cfg/cfg-select.stderr+1-1| ... | ... | @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `invalid_cfg1` |
| 4 | 4 | LL | invalid_cfg1 => {} |
| 5 | 5 | | ^^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `FALSE` and `test` and 32 more | |
| 7 | = help: expected names are: `FALSE` and `test` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(invalid_cfg1)` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 4 | 4 | LL | #[cfg(value)] |
| 5 | 5 | | ^^^^^ |
| 6 | 6 | | |
| 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 | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(value)` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 4 | 4 | LL | #[cfg(my_value)] |
| 5 | 5 | | ^^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `bar` and `foo` and 32 more | |
| 7 | = help: expected names are: `bar` and `foo` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(my_value)` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 4 | 4 | LL | #[cfg(unknown_key = "value")] |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `feature` and 32 more | |
| 7 | = help: expected names are: `feature` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 4 | 4 | LL | #[cfg(unknown_key = "value")] |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `feature` and 32 more | |
| 7 | = help: expected names are: `feature` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 4 | 4 | LL | for<#[cfg(b)] c> u8:; |
| 5 | 5 | | ^ help: found config with similar value: `target_feature = "b"` |
| 6 | 6 | | |
| 7 | = help: expected names are: `FALSE`, `docsrs`, and `test` and 32 more | |
| 7 | = help: expected names are: `FALSE`, `docsrs`, and `test` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(b)` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 44 | 44 | LL | #[cfg_attr(uu, unix)] |
| 45 | 45 | | ^^ |
| 46 | 46 | | |
| 47 | = help: expected names are: `feature` and 32 more | |
| 47 | = help: expected names are: `feature` and 33 more | |
| 48 | 48 | = help: to expect this configuration use `--check-cfg=cfg(uu)` |
| 49 | 49 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 50 | 50 |
tests/ui/check-cfg/nested-cfg.stderr+1-1| ... | ... | @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown` |
| 4 | 4 | LL | #[cfg(unknown)] |
| 5 | 5 | | ^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `FALSE` and `test` and 32 more | |
| 7 | = help: expected names are: `FALSE` and `test` and 33 more | |
| 8 | 8 | = help: to expect this configuration use `--check-cfg=cfg(unknown)` |
| 9 | 9 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 10 | 10 | = 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` |
| 14 | 14 | LL | #[cfg(r#false)] |
| 15 | 15 | | ^^^^^^^ |
| 16 | 16 | | |
| 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 | |
| 18 | 18 | = help: to expect this configuration use `--check-cfg=cfg(r#false)` |
| 19 | 19 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 20 | 20 |
tests/ui/check-cfg/raw-keywords.edition2021.stderr+1-1| ... | ... | @@ -14,7 +14,7 @@ warning: unexpected `cfg` condition name: `r#false` |
| 14 | 14 | LL | #[cfg(r#false)] |
| 15 | 15 | | ^^^^^^^ |
| 16 | 16 | | |
| 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 | |
| 18 | 18 | = help: to expect this configuration use `--check-cfg=cfg(r#false)` |
| 19 | 19 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 20 | 20 |
tests/ui/check-cfg/report-in-external-macros.cargo.stderr+1-1| ... | ... | @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `my_lib_cfg` |
| 4 | 4 | LL | cfg_macro::my_lib_macro!(); |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `feature` and 32 more | |
| 7 | = help: expected names are: `feature` and 33 more | |
| 8 | 8 | = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate |
| 9 | 9 | = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg |
| 10 | 10 | = 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` |
| 4 | 4 | LL | cfg_macro::my_lib_macro!(); |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 6 | 6 | | |
| 7 | = help: expected names are: `feature` and 32 more | |
| 7 | = help: expected names are: `feature` and 33 more | |
| 8 | 8 | = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate |
| 9 | 9 | = help: try referring to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg |
| 10 | 10 | = 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)] |
| 28 | 28 | `target_has_atomic` |
| 29 | 29 | `target_has_atomic_load_store` |
| 30 | 30 | `target_has_atomic_primitive_alignment` |
| 31 | `target_has_threads` | |
| 31 | 32 | `target_object_format` |
| 32 | 33 | `target_os` |
| 33 | 34 | `target_pointer_width` |
tests/ui/check-cfg/well-known-values.rs+3| ... | ... | @@ -15,6 +15,7 @@ |
| 15 | 15 | #![feature(cfg_target_has_atomic)] |
| 16 | 16 | #![feature(cfg_target_thread_local)] |
| 17 | 17 | #![feature(cfg_target_object_format)] |
| 18 | #![feature(cfg_target_has_threads)] | |
| 18 | 19 | #![feature(cfg_ub_checks)] |
| 19 | 20 | #![feature(fmt_debug)] |
| 20 | 21 | |
| ... | ... | @@ -68,6 +69,8 @@ |
| 68 | 69 | //~^ WARN unexpected `cfg` condition value |
| 69 | 70 | target_has_atomic_primitive_alignment = "_UNEXPECTED_VALUE", |
| 70 | 71 | //~^ WARN unexpected `cfg` condition value |
| 72 | target_has_threads = "_UNEXPECTED_VALUE", | |
| 73 | //~^ WARN unexpected `cfg` condition value | |
| 71 | 74 | target_object_format = "_UNEXPECTED_VALUE", |
| 72 | 75 | //~^ WARN unexpected `cfg` condition value |
| 73 | 76 | target_os = "_UNEXPECTED_VALUE", |
tests/ui/check-cfg/well-known-values.stderr+41-30| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 2 | --> $DIR/well-known-values.rs:29:5 | |
| 2 | --> $DIR/well-known-values.rs:30:5 | |
| 3 | 3 | | |
| 4 | 4 | LL | clippy = "_UNEXPECTED_VALUE", |
| 5 | 5 | | ^^^^^^---------------------- |
| ... | ... | @@ -11,7 +11,7 @@ LL | clippy = "_UNEXPECTED_VALUE", |
| 11 | 11 | = note: `#[warn(unexpected_cfgs)]` on by default |
| 12 | 12 | |
| 13 | 13 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 14 | --> $DIR/well-known-values.rs:31:5 | |
| 14 | --> $DIR/well-known-values.rs:32:5 | |
| 15 | 15 | | |
| 16 | 16 | LL | debug_assertions = "_UNEXPECTED_VALUE", |
| 17 | 17 | | ^^^^^^^^^^^^^^^^---------------------- |
| ... | ... | @@ -22,7 +22,7 @@ LL | debug_assertions = "_UNEXPECTED_VALUE", |
| 22 | 22 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 23 | 23 | |
| 24 | 24 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 25 | --> $DIR/well-known-values.rs:33:5 | |
| 25 | --> $DIR/well-known-values.rs:34:5 | |
| 26 | 26 | | |
| 27 | 27 | LL | doc = "_UNEXPECTED_VALUE", |
| 28 | 28 | | ^^^---------------------- |
| ... | ... | @@ -33,7 +33,7 @@ LL | doc = "_UNEXPECTED_VALUE", |
| 33 | 33 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 34 | 34 | |
| 35 | 35 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 36 | --> $DIR/well-known-values.rs:35:5 | |
| 36 | --> $DIR/well-known-values.rs:36:5 | |
| 37 | 37 | | |
| 38 | 38 | LL | doctest = "_UNEXPECTED_VALUE", |
| 39 | 39 | | ^^^^^^^---------------------- |
| ... | ... | @@ -44,7 +44,7 @@ LL | doctest = "_UNEXPECTED_VALUE", |
| 44 | 44 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 45 | 45 | |
| 46 | 46 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 47 | --> $DIR/well-known-values.rs:37:5 | |
| 47 | --> $DIR/well-known-values.rs:38:5 | |
| 48 | 48 | | |
| 49 | 49 | LL | fmt_debug = "_UNEXPECTED_VALUE", |
| 50 | 50 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -53,7 +53,7 @@ LL | fmt_debug = "_UNEXPECTED_VALUE", |
| 53 | 53 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 54 | 54 | |
| 55 | 55 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 56 | --> $DIR/well-known-values.rs:39:5 | |
| 56 | --> $DIR/well-known-values.rs:40:5 | |
| 57 | 57 | | |
| 58 | 58 | LL | miri = "_UNEXPECTED_VALUE", |
| 59 | 59 | | ^^^^---------------------- |
| ... | ... | @@ -64,7 +64,7 @@ LL | miri = "_UNEXPECTED_VALUE", |
| 64 | 64 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 65 | 65 | |
| 66 | 66 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 67 | --> $DIR/well-known-values.rs:41:5 | |
| 67 | --> $DIR/well-known-values.rs:42:5 | |
| 68 | 68 | | |
| 69 | 69 | LL | overflow_checks = "_UNEXPECTED_VALUE", |
| 70 | 70 | | ^^^^^^^^^^^^^^^---------------------- |
| ... | ... | @@ -75,7 +75,7 @@ LL | overflow_checks = "_UNEXPECTED_VALUE", |
| 75 | 75 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 76 | 76 | |
| 77 | 77 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 78 | --> $DIR/well-known-values.rs:43:5 | |
| 78 | --> $DIR/well-known-values.rs:44:5 | |
| 79 | 79 | | |
| 80 | 80 | LL | panic = "_UNEXPECTED_VALUE", |
| 81 | 81 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -84,7 +84,7 @@ LL | panic = "_UNEXPECTED_VALUE", |
| 84 | 84 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 85 | 85 | |
| 86 | 86 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 87 | --> $DIR/well-known-values.rs:45:5 | |
| 87 | --> $DIR/well-known-values.rs:46:5 | |
| 88 | 88 | | |
| 89 | 89 | LL | proc_macro = "_UNEXPECTED_VALUE", |
| 90 | 90 | | ^^^^^^^^^^---------------------- |
| ... | ... | @@ -95,7 +95,7 @@ LL | proc_macro = "_UNEXPECTED_VALUE", |
| 95 | 95 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 96 | 96 | |
| 97 | 97 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 98 | --> $DIR/well-known-values.rs:47:5 | |
| 98 | --> $DIR/well-known-values.rs:48:5 | |
| 99 | 99 | | |
| 100 | 100 | LL | relocation_model = "_UNEXPECTED_VALUE", |
| 101 | 101 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -104,7 +104,7 @@ LL | relocation_model = "_UNEXPECTED_VALUE", |
| 104 | 104 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 105 | 105 | |
| 106 | 106 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 107 | --> $DIR/well-known-values.rs:49:5 | |
| 107 | --> $DIR/well-known-values.rs:50:5 | |
| 108 | 108 | | |
| 109 | 109 | LL | rustfmt = "_UNEXPECTED_VALUE", |
| 110 | 110 | | ^^^^^^^---------------------- |
| ... | ... | @@ -115,7 +115,7 @@ LL | rustfmt = "_UNEXPECTED_VALUE", |
| 115 | 115 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 116 | 116 | |
| 117 | 117 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 118 | --> $DIR/well-known-values.rs:51:5 | |
| 118 | --> $DIR/well-known-values.rs:52:5 | |
| 119 | 119 | | |
| 120 | 120 | LL | sanitize = "_UNEXPECTED_VALUE", |
| 121 | 121 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -124,7 +124,7 @@ LL | sanitize = "_UNEXPECTED_VALUE", |
| 124 | 124 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 125 | 125 | |
| 126 | 126 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 127 | --> $DIR/well-known-values.rs:53:5 | |
| 127 | --> $DIR/well-known-values.rs:54:5 | |
| 128 | 128 | | |
| 129 | 129 | LL | target_abi = "_UNEXPECTED_VALUE", |
| 130 | 130 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -133,7 +133,7 @@ LL | target_abi = "_UNEXPECTED_VALUE", |
| 133 | 133 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 134 | 134 | |
| 135 | 135 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 136 | --> $DIR/well-known-values.rs:55:5 | |
| 136 | --> $DIR/well-known-values.rs:56:5 | |
| 137 | 137 | | |
| 138 | 138 | LL | target_arch = "_UNEXPECTED_VALUE", |
| 139 | 139 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -142,7 +142,7 @@ LL | target_arch = "_UNEXPECTED_VALUE", |
| 142 | 142 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 143 | 143 | |
| 144 | 144 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 145 | --> $DIR/well-known-values.rs:57:5 | |
| 145 | --> $DIR/well-known-values.rs:58:5 | |
| 146 | 146 | | |
| 147 | 147 | LL | target_endian = "_UNEXPECTED_VALUE", |
| 148 | 148 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -151,7 +151,7 @@ LL | target_endian = "_UNEXPECTED_VALUE", |
| 151 | 151 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 152 | 152 | |
| 153 | 153 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 154 | --> $DIR/well-known-values.rs:59:5 | |
| 154 | --> $DIR/well-known-values.rs:60:5 | |
| 155 | 155 | | |
| 156 | 156 | LL | target_env = "_UNEXPECTED_VALUE", |
| 157 | 157 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -160,7 +160,7 @@ LL | target_env = "_UNEXPECTED_VALUE", |
| 160 | 160 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 161 | 161 | |
| 162 | 162 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 163 | --> $DIR/well-known-values.rs:61:5 | |
| 163 | --> $DIR/well-known-values.rs:62:5 | |
| 164 | 164 | | |
| 165 | 165 | LL | target_family = "_UNEXPECTED_VALUE", |
| 166 | 166 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -169,7 +169,7 @@ LL | target_family = "_UNEXPECTED_VALUE", |
| 169 | 169 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 170 | 170 | |
| 171 | 171 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 172 | --> $DIR/well-known-values.rs:65:5 | |
| 172 | --> $DIR/well-known-values.rs:66:5 | |
| 173 | 173 | | |
| 174 | 174 | LL | target_has_atomic = "_UNEXPECTED_VALUE", |
| 175 | 175 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -178,7 +178,7 @@ LL | target_has_atomic = "_UNEXPECTED_VALUE", |
| 178 | 178 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 179 | 179 | |
| 180 | 180 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 181 | --> $DIR/well-known-values.rs:67:5 | |
| 181 | --> $DIR/well-known-values.rs:68:5 | |
| 182 | 182 | | |
| 183 | 183 | LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", |
| 184 | 184 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -187,7 +187,7 @@ LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", |
| 187 | 187 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 188 | 188 | |
| 189 | 189 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 190 | --> $DIR/well-known-values.rs:69:5 | |
| 190 | --> $DIR/well-known-values.rs:70:5 | |
| 191 | 191 | | |
| 192 | 192 | LL | target_has_atomic_primitive_alignment = "_UNEXPECTED_VALUE", |
| 193 | 193 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -196,7 +196,18 @@ LL | target_has_atomic_primitive_alignment = "_UNEXPECTED_VALUE", |
| 196 | 196 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 197 | 197 | |
| 198 | 198 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 199 | --> $DIR/well-known-values.rs:71:5 | |
| 199 | --> $DIR/well-known-values.rs:72:5 | |
| 200 | | | |
| 201 | LL | 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 | ||
| 209 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` | |
| 210 | --> $DIR/well-known-values.rs:74:5 | |
| 200 | 211 | | |
| 201 | 212 | LL | target_object_format = "_UNEXPECTED_VALUE", |
| 202 | 213 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -205,7 +216,7 @@ LL | target_object_format = "_UNEXPECTED_VALUE", |
| 205 | 216 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 206 | 217 | |
| 207 | 218 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 208 | --> $DIR/well-known-values.rs:73:5 | |
| 219 | --> $DIR/well-known-values.rs:76:5 | |
| 209 | 220 | | |
| 210 | 221 | LL | target_os = "_UNEXPECTED_VALUE", |
| 211 | 222 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -214,7 +225,7 @@ LL | target_os = "_UNEXPECTED_VALUE", |
| 214 | 225 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 215 | 226 | |
| 216 | 227 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 217 | --> $DIR/well-known-values.rs:75:5 | |
| 228 | --> $DIR/well-known-values.rs:78:5 | |
| 218 | 229 | | |
| 219 | 230 | LL | target_pointer_width = "_UNEXPECTED_VALUE", |
| 220 | 231 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -223,7 +234,7 @@ LL | target_pointer_width = "_UNEXPECTED_VALUE", |
| 223 | 234 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 224 | 235 | |
| 225 | 236 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 226 | --> $DIR/well-known-values.rs:77:5 | |
| 237 | --> $DIR/well-known-values.rs:80:5 | |
| 227 | 238 | | |
| 228 | 239 | LL | target_thread_local = "_UNEXPECTED_VALUE", |
| 229 | 240 | | ^^^^^^^^^^^^^^^^^^^---------------------- |
| ... | ... | @@ -234,7 +245,7 @@ LL | target_thread_local = "_UNEXPECTED_VALUE", |
| 234 | 245 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 235 | 246 | |
| 236 | 247 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 237 | --> $DIR/well-known-values.rs:79:5 | |
| 248 | --> $DIR/well-known-values.rs:82:5 | |
| 238 | 249 | | |
| 239 | 250 | LL | target_vendor = "_UNEXPECTED_VALUE", |
| 240 | 251 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| ... | ... | @@ -243,7 +254,7 @@ LL | target_vendor = "_UNEXPECTED_VALUE", |
| 243 | 254 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 244 | 255 | |
| 245 | 256 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 246 | --> $DIR/well-known-values.rs:81:5 | |
| 257 | --> $DIR/well-known-values.rs:84:5 | |
| 247 | 258 | | |
| 248 | 259 | LL | ub_checks = "_UNEXPECTED_VALUE", |
| 249 | 260 | | ^^^^^^^^^---------------------- |
| ... | ... | @@ -254,7 +265,7 @@ LL | ub_checks = "_UNEXPECTED_VALUE", |
| 254 | 265 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 255 | 266 | |
| 256 | 267 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 257 | --> $DIR/well-known-values.rs:83:5 | |
| 268 | --> $DIR/well-known-values.rs:86:5 | |
| 258 | 269 | | |
| 259 | 270 | LL | unix = "_UNEXPECTED_VALUE", |
| 260 | 271 | | ^^^^---------------------- |
| ... | ... | @@ -265,7 +276,7 @@ LL | unix = "_UNEXPECTED_VALUE", |
| 265 | 276 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 266 | 277 | |
| 267 | 278 | warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` |
| 268 | --> $DIR/well-known-values.rs:85:5 | |
| 279 | --> $DIR/well-known-values.rs:88:5 | |
| 269 | 280 | | |
| 270 | 281 | LL | windows = "_UNEXPECTED_VALUE", |
| 271 | 282 | | ^^^^^^^---------------------- |
| ... | ... | @@ -276,7 +287,7 @@ LL | windows = "_UNEXPECTED_VALUE", |
| 276 | 287 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 277 | 288 | |
| 278 | 289 | warning: unexpected `cfg` condition value: `linuz` |
| 279 | --> $DIR/well-known-values.rs:91:7 | |
| 290 | --> $DIR/well-known-values.rs:94:7 | |
| 280 | 291 | | |
| 281 | 292 | LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` |
| 282 | 293 | | ^^^^^^^^^^^^------- |
| ... | ... | @@ -286,5 +297,5 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` |
| 286 | 297 | = 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` |
| 287 | 298 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 288 | 299 | |
| 289 | warning: 29 warnings emitted | |
| 300 | warning: 30 warnings emitted | |
| 290 | 301 |
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. | |
| 27 | fn 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 | ||
| 34 | fn fnonce_requirement<F>(wrap: F) | |
| 35 | where | |
| 36 | F: FnOnce(), | |
| 37 | { | |
| 38 | todo!() | |
| 39 | } | |
| 40 | ||
| 41 | fn 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 | ||
| 6 | trait methods { //~ WARN trait `methods` is never used | |
| 7 | fn to_bytes(&self) -> Vec<u8>; | |
| 8 | } | |
| 9 | ||
| 10 | impl 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! | |
| 18 | fn 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 | ||
| 27 | struct Storage { storage: Vec<u64> } | |
| 28 | ||
| 29 | pub 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 @@ |
| 1 | warning: trait `methods` is never used | |
| 2 | --> $DIR/bitvec-to-bools-opt-miscompile.rs:6:7 | |
| 3 | | | |
| 4 | LL | trait methods { | |
| 5 | | ^^^^^^^ | |
| 6 | | | |
| 7 | = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default | |
| 8 | ||
| 9 | warning: 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 | ||
| 5 | pub enum Instruction { | |
| 6 | Increment(i8), | |
| 7 | Loop(Box<Box<()>>), | |
| 8 | } | |
| 9 | ||
| 10 | fn 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)] | |
| 5 | struct A<T: ?Sized> { ptr: T } | |
| 6 | ||
| 7 | fn foo<T>(x: &A<[T]>) {} | |
| 8 | ||
| 9 | fn 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 | ||
| 6 | struct S<const X: (u32, u32)>; | |
| 7 | ||
| 8 | fn main() { | |
| 9 | let _: S<{ (1, _) }> = S::<{ (1, 2) }>; | |
| 10 | } |
tests/ui/consts/static-mut-refs.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | #![allow(dead_code)] |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | // 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 @@ |
| 1 | 1 | //@ build-pass |
| 2 | 2 | |
| 3 | 3 | #![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 | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | static mut A: [i32; 5] = [1, 2, 3, 4, 5]; |
tests/ui/drop/conditional-drop-10734.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | //@ run-pass |
| 4 | 4 | #![allow(non_upper_case_globals)] |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): this could use an atomic | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | static mut drop_count: usize = 0; |
tests/ui/drop/destructor-run-for-expression-4734.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // Ensures that destructors are run for expressions of the form "e;" where |
| 5 | 5 | // `e` is a type which requires a destructor. |
| 6 | 6 | |
| 7 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 7 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 8 | 8 | #![allow(static_mut_refs)] |
| 9 | 9 | #![allow(path_statements)] |
| 10 | 10 |
tests/ui/drop/destructor-run-for-let-ignore-6892.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // Ensures that destructors are run for expressions of the form "let _ = e;" |
| 5 | 5 | // where `e` is a type which requires a destructor. |
| 6 | 6 | |
| 7 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 7 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 8 | 8 | #![allow(static_mut_refs)] |
| 9 | 9 | |
| 10 | 10 | struct Foo; |
tests/ui/drop/drop-count-assertion-16151.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | // https://github.com/rust-lang/rust/issues/16151 |
| 2 | 2 | //@ run-pass |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | use std::mem; |
tests/ui/drop/drop-struct-as-object.rs+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | // Test that destructor on a struct runs successfully after the struct |
| 6 | 6 | // is boxed and converted to an object. |
| 7 | 7 | |
| 8 | // FIXME(static_mut_refs): this could use an atomic | |
| 8 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 9 | 9 | #![allow(static_mut_refs)] |
| 10 | 10 | |
| 11 | 11 | static mut value: usize = 0; |
tests/ui/drop/generic-drop-trait-bound-15858.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //! Regression test for https://github.com/rust-lang/rust/issues/15858 |
| 2 | 2 | |
| 3 | 3 | //@ run-pass |
| 4 | // FIXME(static_mut_refs): this could use an atomic | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | static mut DROP_RAN: bool = false; |
| 7 | 7 |
tests/ui/drop/issue-23338-ensure-param-drop-order.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | #![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 | |
| 4 | 4 | #![allow(static_mut_refs)] |
| 5 | 5 | |
| 6 | 6 | // 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 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | #![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 | |
| 4 | 4 | #![allow(static_mut_refs)] |
| 5 | 5 | |
| 6 | 6 | // 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 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | #![allow(unused_must_use)] |
| 3 | 3 | // 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 | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | static 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 | ||
| 9 | use std::panic; | |
| 10 | ||
| 11 | impl<'a> panic::UnwindSafe for Foo<'a> {} | |
| 12 | impl<'a> panic::RefUnwindSafe for Foo<'a> {} | |
| 13 | ||
| 14 | struct Foo<'a>(&'a mut bool); | |
| 15 | ||
| 16 | impl<'a> Drop for Foo<'a> { | |
| 17 | fn drop(&mut self) { | |
| 18 | *self.0 = true; | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn f<T: FnOnce()>(t: T) { | |
| 23 | t() | |
| 24 | } | |
| 25 | ||
| 26 | fn 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 | ||
| 11 | struct Foo; | |
| 12 | ||
| 13 | impl Drop for Foo { | |
| 14 | fn drop(&mut self) {} | |
| 15 | } | |
| 16 | ||
| 17 | fn foo() -> Foo { | |
| 18 | panic!(); | |
| 19 | } | |
| 20 | ||
| 21 | fn 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 @@ |
| 3 | 3 | |
| 4 | 4 | #![allow(dropping_references, dropping_copy_types)] |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): this could use an atomic | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | static mut CHECK: usize = 0; |
tests/ui/drop/same-alloca-reassigned-match-binding-16151.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | //@ run-pass |
| 4 | 4 | |
| 5 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 5 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 6 | 6 | #![allow(static_mut_refs)] |
| 7 | 7 | |
| 8 | 8 | use std::mem; |
tests/ui/drop/static-issue-17302.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | |
| 3 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 3 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 4 | 4 | #![allow(static_mut_refs)] |
| 5 | 5 | |
| 6 | 6 | static 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 | ||
| 4 | use std::fmt; | |
| 5 | ||
| 6 | // CoerceUnsized is not implemented for tuples. You can still create | |
| 7 | // an unsized tuple by transmuting a trait object. | |
| 8 | fn any<T>() -> T { unreachable!() } | |
| 9 | ||
| 10 | fn 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> | |
| 2 | enum E { | |
| 3 | V([Box<E>]), | |
| 4 | //~^ ERROR the size for values of type | |
| 5 | } | |
| 6 | ||
| 7 | fn main() {} |
tests/ui/enum/unsized-field-in-enum-variant.stderr created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | error[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 | | | |
| 4 | LL | 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 | |
| 10 | help: borrowed types always have a statically known size | |
| 11 | | | |
| 12 | LL | V(&[Box<E>]), | |
| 13 | | + | |
| 14 | help: the `Box` type always has a statically known size and allocates its contents in the heap | |
| 15 | | | |
| 16 | LL | V(Box<[Box<E>]>), | |
| 17 | | ++++ + | |
| 18 | ||
| 19 | error: aborting due to 1 previous error | |
| 20 | ||
| 21 | For 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> | |
| 2 | pub fn main () {} | |
| 3 | ||
| 4 | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types | |
| 5 | } |
tests/ui/error-emitter/multibyte-char-in-diagnostic-source-line.stderr created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/multibyte-char-in-diagnostic-source-line.rs:4:36 | |
| 3 | | | |
| 4 | LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { | |
| 5 | | ------------------------ ^^^^^ expected `isize`, found `()` | |
| 6 | | | | |
| 7 | | implicitly returns `()` as its body has no tail or `return` expression | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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 | |
| 3 | fn bar() {} | |
| 4 | ||
| 5 | fn main() {} |
tests/ui/feature-gates/feature-gate-cfg-target-has-threads.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[E0658]: `cfg(target_has_threads)` is experimental and subject to change | |
| 2 | --> $DIR/feature-gate-cfg-target-has-threads.rs:1:7 | |
| 3 | | | |
| 4 | LL | #[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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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 | ||
| 6 | use unstable_crate_import_gated_in_2018_edition; | |
| 7 | //~^ ERROR use of unstable library feature `unstable_crate_import_gated_in_2018_edition` | |
| 8 | ||
| 9 | fn main() {} |
tests/ui/feature-gates/unstable-crate-import-gated-in-2018-edition.stderr created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | error[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 | | | |
| 4 | LL | 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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For 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)] | |
| 6 | enum 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 | ||
| 16 | fn 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 | ||
| 26 | pub 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 | ||
| 4 | trait CallSingle<A, B> { | |
| 5 | fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B; | |
| 6 | } | |
| 7 | ||
| 8 | impl<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 | ||
| 15 | fn main() {} |
tests/ui/fn_traits/fn-trait-ufcs-call-in-impl.stderr created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | error[E0229]: associated item constraints are not allowed here | |
| 2 | --> $DIR/fn-trait-ufcs-call-in-impl.rs:10:27 | |
| 3 | | | |
| 4 | LL | <Self as Fn(A) -> B>::call(self, (a,)) | |
| 5 | | ^ associated item constraint not allowed here | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For 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)] | |
| 9 | struct Ishmael; | |
| 10 | #[derive(Debug, PartialEq, Eq)] | |
| 11 | struct Maybe; | |
| 12 | struct CallMe; | |
| 13 | ||
| 14 | impl 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 | ||
| 22 | impl 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 | ||
| 30 | fn 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 | ||
| 4 | fn 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 @@ |
| 1 | error[E0229]: associated item constraints are not allowed here | |
| 2 | --> $DIR/parenthesized-fn-trait-in-qualified-path.rs:5:14 | |
| 3 | | | |
| 4 | LL | <fn() as Fn()>::call; | |
| 5 | | ^^^^ associated item constraint not allowed here | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For 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 @@ |
| 2 | 2 | // This test verifies that temporaries created for `while`'s and `if` |
| 3 | 3 | // conditions are dropped after the condition is evaluated. |
| 4 | 4 | |
| 5 | // FIXME(static_mut_refs): this could use an atomic | |
| 5 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 6 | 6 | #![allow(static_mut_refs)] |
| 7 | 7 | |
| 8 | 8 | struct Temporary; |
tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | // The `foo` module attempts to maintains an invariant that each `S` |
| 4 | 4 | // has a unique `u64` id. |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | use 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 | ||
| 4 | mod 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 | ||
| 13 | fn 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 | ||
| 3 | fn 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 @@ |
| 1 | pub trait MakeRef<'a> { | |
| 2 | type Ref; | |
| 3 | } | |
| 4 | impl<'a, T: 'a> MakeRef<'a> for T { | |
| 5 | type Ref = &'a T; | |
| 6 | } | |
| 7 | ||
| 8 | pub trait MakeRef2 { | |
| 9 | type Ref2; | |
| 10 | } | |
| 11 | impl<'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 | ||
| 16 | fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") } | |
| 17 | //~^ ERROR temporary value dropped while borrowed | |
| 18 | ||
| 19 | fn main() { | |
| 20 | println!("{}", foo()); | |
| 21 | } |
tests/ui/issues/issue-29861.stderr deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates | |
| 2 | --> $DIR/issue-29861.rs:11:6 | |
| 3 | | | |
| 4 | LL | impl<'a, T: 'a> MakeRef2 for T { | |
| 5 | | ^^ unconstrained lifetime parameter | |
| 6 | ||
| 7 | error[E0716]: temporary value dropped while borrowed | |
| 8 | --> $DIR/issue-29861.rs:16:43 | |
| 9 | | | |
| 10 | LL | 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 | ||
| 18 | error: aborting due to 2 previous errors | |
| 19 | ||
| 20 | Some errors have detailed explanations: E0207, E0716. | |
| 21 | For 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 | ||
| 4 | trait methods { //~ WARN trait `methods` is never used | |
| 5 | fn to_bytes(&self) -> Vec<u8>; | |
| 6 | } | |
| 7 | ||
| 8 | impl 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! | |
| 16 | fn 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 | ||
| 25 | struct Storage { storage: Vec<u64> } | |
| 26 | ||
| 27 | pub 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 @@ |
| 1 | warning: trait `methods` is never used | |
| 2 | --> $DIR/issue-2989.rs:4:7 | |
| 3 | | | |
| 4 | LL | trait methods { | |
| 5 | | ^^^^^^^ | |
| 6 | | | |
| 7 | = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default | |
| 8 | ||
| 9 | warning: 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 | ||
| 5 | use std::panic; | |
| 6 | ||
| 7 | impl<'a> panic::UnwindSafe for Foo<'a> {} | |
| 8 | impl<'a> panic::RefUnwindSafe for Foo<'a> {} | |
| 9 | ||
| 10 | struct Foo<'a>(&'a mut bool); | |
| 11 | ||
| 12 | impl<'a> Drop for Foo<'a> { | |
| 13 | fn drop(&mut self) { | |
| 14 | *self.0 = true; | |
| 15 | } | |
| 16 | } | |
| 17 | ||
| 18 | fn f<T: FnOnce()>(t: T) { | |
| 19 | t() | |
| 20 | } | |
| 21 | ||
| 22 | fn 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 | ||
| 11 | struct Foo; | |
| 12 | ||
| 13 | impl Drop for Foo { | |
| 14 | fn drop(&mut self) {} | |
| 15 | } | |
| 16 | ||
| 17 | fn foo() -> Foo { | |
| 18 | panic!(); | |
| 19 | } | |
| 20 | ||
| 21 | fn 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 | ||
| 4 | pub enum Instruction { | |
| 5 | Increment(i8), | |
| 6 | Loop(Box<Box<()>>), | |
| 7 | } | |
| 8 | ||
| 9 | fn 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 @@ |
| 1 | fn 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 | ||
| 14 | fn main() {} |
tests/ui/issues/issue-3021-b.stderr deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | error[E0434]: can't capture dynamic environment in a fn item | |
| 2 | --> $DIR/issue-3021-b.rs:9:22 | |
| 3 | | | |
| 4 | LL | self.v0 = k0 ^ 0x736f6d6570736575; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = help: use the `|| { ... }` closure form instead | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0434`. |
tests/ui/issues/issue-3021-d.rs deleted-28| ... | ... | @@ -1,28 +0,0 @@ |
| 1 | trait SipHash { | |
| 2 | fn result(&self) -> u64; | |
| 3 | fn reset(&self); | |
| 4 | } | |
| 5 | ||
| 6 | fn 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 | ||
| 28 | fn main() {} |
tests/ui/issues/issue-3021-d.stderr deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | error[E0434]: can't capture dynamic environment in a fn item | |
| 2 | --> $DIR/issue-3021-d.rs:21:23 | |
| 3 | | | |
| 4 | LL | self.v0 = k0 ^ 0x736f6d6570736575; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = help: use the `|| { ... }` closure form instead | |
| 8 | ||
| 9 | error[E0434]: can't capture dynamic environment in a fn item | |
| 10 | --> $DIR/issue-3021-d.rs:22:23 | |
| 11 | | | |
| 12 | LL | self.v1 = k1 ^ 0x646f72616e646f6d; | |
| 13 | | ^^ | |
| 14 | | | |
| 15 | = help: use the `|| { ... }` closure form instead | |
| 16 | ||
| 17 | error: aborting due to 2 previous errors | |
| 18 | ||
| 19 | For 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 | ||
| 3 | use std::fmt; | |
| 4 | ||
| 5 | // CoerceUnsized is not implemented for tuples. You can still create | |
| 6 | // an unsized tuple by transmuting a trait object. | |
| 7 | fn any<T>() -> T { unreachable!() } | |
| 8 | ||
| 9 | fn 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)] | |
| 5 | enum 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 | ||
| 15 | fn 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 | ||
| 25 | pub 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 @@ |
| 1 | enum E { | |
| 2 | V([Box<E>]), | |
| 3 | //~^ ERROR the size for values of type | |
| 4 | } | |
| 5 | ||
| 6 | fn main() {} |
tests/ui/issues/issue-35988.stderr deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | error[E0277]: the size for values of type `[Box<E>]` cannot be known at compilation time | |
| 2 | --> $DIR/issue-35988.rs:2:7 | |
| 3 | | | |
| 4 | LL | 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 | |
| 10 | help: borrowed types always have a statically known size | |
| 11 | | | |
| 12 | LL | V(&[Box<E>]), | |
| 13 | | + | |
| 14 | help: the `Box` type always has a statically known size and allocates its contents in the heap | |
| 15 | | | |
| 16 | LL | V(Box<[Box<E>]>), | |
| 17 | | ++++ + | |
| 18 | ||
| 19 | error: aborting due to 1 previous error | |
| 20 | ||
| 21 | For 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)] | |
| 3 | type A = for<> fn(); | |
| 4 | ||
| 5 | type B = for<'a,> fn(); | |
| 6 | ||
| 7 | pub fn main() {} |
tests/ui/issues/issue-39687.rs deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | #![feature(fn_traits)] | |
| 2 | ||
| 3 | fn 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 @@ |
| 1 | error[E0229]: associated item constraints are not allowed here | |
| 2 | --> $DIR/issue-39687.rs:4:14 | |
| 3 | | | |
| 4 | LL | <fn() as Fn()>::call; | |
| 5 | | ^^^^ associated item constraint not allowed here | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For 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 | ||
| 3 | trait CallSingle<A, B> { | |
| 4 | fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B; | |
| 5 | } | |
| 6 | ||
| 7 | impl<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 | ||
| 14 | fn main() {} |
tests/ui/issues/issue-43431.stderr deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | error[E0229]: associated item constraints are not allowed here | |
| 2 | --> $DIR/issue-43431.rs:9:27 | |
| 3 | | | |
| 4 | LL | <Self as Fn(A) -> B>::call(self, (a,)) | |
| 5 | | ^ associated item constraint not allowed here | |
| 6 | ||
| 7 | error: aborting due to 1 previous error | |
| 8 | ||
| 9 | For 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)] | |
| 4 | struct A<T: ?Sized> { ptr: T } | |
| 5 | ||
| 6 | fn foo<T>(x: &A<[T]>) {} | |
| 7 | ||
| 8 | fn 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 @@ |
| 1 | pub fn main () {} | |
| 2 | ||
| 3 | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types | |
| 4 | } |
tests/ui/issues/issue-44023.stderr deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/issue-44023.rs:3:36 | |
| 3 | | | |
| 4 | LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { | |
| 5 | | ------------------------ ^^^^^ expected `isize`, found `()` | |
| 6 | | | | |
| 7 | | implicitly returns `()` as its body has no tail or `return` expression | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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)] | |
| 8 | struct Ishmael; | |
| 9 | #[derive(Debug, PartialEq, Eq)] | |
| 10 | struct Maybe; | |
| 11 | struct CallMe; | |
| 12 | ||
| 13 | impl 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 | ||
| 21 | impl 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 | ||
| 29 | fn 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 | ||
| 5 | use issue_52489; | |
| 6 | //~^ ERROR use of unstable library feature `issue_52489_unstable` | |
| 7 | ||
| 8 | fn main() {} |
tests/ui/issues/issue-52489.stderr deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | error[E0658]: use of unstable library feature `issue_52489_unstable` | |
| 2 | --> $DIR/issue-52489.rs:5:5 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | error: aborting due to 1 previous error | |
| 11 | ||
| 12 | For more information about this error, try `rustc --explain E0658`. |
tests/ui/linkage-attr/link-section-placement.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | //@ run-pass |
| 4 | 4 | |
| 5 | 5 | #![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 | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | #![allow(non_upper_case_globals)] |
| 9 | 9 |
tests/ui/linkage-attr/linkage-attr-mutable-static.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | //! them at runtime, so deny mutable statics with #[linkage]. |
| 3 | 3 | |
| 4 | 4 | #![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 | |
| 6 | 6 | #![allow(static_mut_refs)] |
| 7 | 7 | |
| 8 | 8 | fn main() { |
tests/ui/lto/lto-still-runs-thread-dtors.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | //@ needs-threads |
| 5 | 5 | //@ ignore-backends: gcc |
| 6 | 6 | |
| 7 | // FIXME(static_mut_refs): this could use an atomic | |
| 7 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 8 | 8 | #![allow(static_mut_refs)] |
| 9 | 9 | |
| 10 | 10 | use std::thread; |
tests/ui/macros/cfg.stderr+1-1| ... | ... | @@ -46,7 +46,7 @@ warning: unexpected `cfg` condition name: `foo` |
| 46 | 46 | LL | cfg!(foo); |
| 47 | 47 | | ^^^ |
| 48 | 48 | | |
| 49 | = help: expected names are: `FALSE` and `test` and 32 more | |
| 49 | = help: expected names are: `FALSE` and `test` and 33 more | |
| 50 | 50 | = help: to expect this configuration use `--check-cfg=cfg(foo)` |
| 51 | 51 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 52 | 52 | = 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` |
| 169 | 169 | LL | a + 1 => {} |
| 170 | 170 | | ^ help: found config with similar value: `target_feature = "a"` |
| 171 | 171 | | |
| 172 | = help: expected names are: `FALSE` and `test` and 32 more | |
| 172 | = help: expected names are: `FALSE` and `test` and 33 more | |
| 173 | 173 | = help: to expect this configuration use `--check-cfg=cfg(a)` |
| 174 | 174 | = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration |
| 175 | 175 | = note: `#[warn(unexpected_cfgs)]` on by default |
tests/ui/methods/method-self-arg-trait.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | // Test method calls with self as an argument |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | static mut COUNT: u64 = 1; |
tests/ui/methods/method-self-arg.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | // Test method calls with self as an argument |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | static mut COUNT: usize = 1; |
tests/ui/mir/mir_early_return_scope.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | #![allow(unused_variables)] |
| 3 | // FIXME(static_mut_refs): this could use an atomic | |
| 3 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 4 | 4 | #![allow(static_mut_refs)] |
| 5 | 5 | static mut DROP: bool = false; |
| 6 | 6 |
tests/ui/nll/issue-69114-static-mut-ty.rs+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | // Check that borrowck ensures that `static mut` items have the expected type. |
| 2 | 2 | |
| 3 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 3 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 4 | 4 | #![allow(static_mut_refs)] |
| 5 | 5 | |
| 6 | 6 | static FOO: u8 = 42; |
tests/ui/numbers-arithmetic/shift-near-oflo.rs+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | //@ run-pass |
| 2 | 2 | //@ compile-flags: -C debug-assertions |
| 3 | 3 | |
| 4 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 4 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 5 | 5 | #![allow(static_mut_refs)] |
| 6 | 6 | |
| 7 | 7 | // 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)] | |
| 4 | type A = for<> fn(); | |
| 5 | ||
| 6 | type B = for<'a,> fn(); | |
| 7 | ||
| 8 | pub 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 | ||
| 5 | mod 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 | ||
| 14 | fn 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 | ||
| 4 | fn 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 | ||
| 17 | fn main() {} |
tests/ui/resolve/impl-method-cant-capture-env.stderr created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | error[E0434]: can't capture dynamic environment in a fn item | |
| 2 | --> $DIR/impl-method-cant-capture-env.rs:12:22 | |
| 3 | | | |
| 4 | LL | self.v0 = k0 ^ 0x736f6d6570736575; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = help: use the `|| { ... }` closure form instead | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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 | ||
| 4 | trait SipHash { | |
| 5 | fn reset(&self); | |
| 6 | } | |
| 7 | ||
| 8 | fn 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 | ||
| 21 | fn main() {} |
tests/ui/resolve/impl-trait-for-type-cant-capture-env.stderr created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | error[E0434]: can't capture dynamic environment in a fn item | |
| 2 | --> $DIR/impl-trait-for-type-cant-capture-env.rs:15:22 | |
| 3 | | | |
| 4 | LL | self.v0 = k0 ^ 0x736f6d6570736575; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = help: use the `|| { ... }` closure form instead | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For more information about this error, try `rustc --explain E0434`. |
tests/ui/resolve/issue-3021-c.rs deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | fn 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 | ||
| 9 | fn main() {} |
tests/ui/resolve/issue-3021-c.stderr deleted-37| ... | ... | @@ -1,37 +0,0 @@ |
| 1 | error[E0401]: can't use generic parameters from outer item | |
| 2 | --> $DIR/issue-3021-c.rs:4:24 | |
| 3 | | | |
| 4 | LL | fn siphash<T>() { | |
| 5 | | - type parameter from outer item | |
| 6 | LL | | |
| 7 | LL | trait U { | |
| 8 | | - generic parameter used in this inner trait | |
| 9 | LL | 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 | |
| 13 | help: try introducing a local generic parameter here | |
| 14 | | | |
| 15 | LL | trait U<T> { | |
| 16 | | +++ | |
| 17 | ||
| 18 | error[E0401]: can't use generic parameters from outer item | |
| 19 | --> $DIR/issue-3021-c.rs:4:30 | |
| 20 | | | |
| 21 | LL | fn siphash<T>() { | |
| 22 | | - type parameter from outer item | |
| 23 | LL | | |
| 24 | LL | trait U { | |
| 25 | | - generic parameter used in this inner trait | |
| 26 | LL | 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 | |
| 30 | help: try introducing a local generic parameter here | |
| 31 | | | |
| 32 | LL | trait U<T> { | |
| 33 | | +++ | |
| 34 | ||
| 35 | error: aborting due to 2 previous errors | |
| 36 | ||
| 37 | For more information about this error, try `rustc --explain E0401`. |
tests/ui/resolve/issue-3021.rs deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | trait SipHash { | |
| 2 | fn reset(&self); | |
| 3 | } | |
| 4 | ||
| 5 | fn 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 | ||
| 18 | fn main() {} |
tests/ui/resolve/issue-3021.stderr deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | error[E0434]: can't capture dynamic environment in a fn item | |
| 2 | --> $DIR/issue-3021.rs:12:22 | |
| 3 | | | |
| 4 | LL | self.v0 = k0 ^ 0x736f6d6570736575; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = help: use the `|| { ... }` closure form instead | |
| 8 | ||
| 9 | error: aborting due to 1 previous error | |
| 10 | ||
| 11 | For 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 | ||
| 4 | fn 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 | ||
| 12 | fn main() {} |
tests/ui/resolve/outer-generic-in-trait-method.stderr created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | error[E0401]: can't use generic parameters from outer item | |
| 2 | --> $DIR/outer-generic-in-trait-method.rs:7:24 | |
| 3 | | | |
| 4 | LL | fn siphash<T>() { | |
| 5 | | - type parameter from outer item | |
| 6 | LL | | |
| 7 | LL | trait U { | |
| 8 | | - generic parameter used in this inner trait | |
| 9 | LL | 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 | |
| 13 | help: try introducing a local generic parameter here | |
| 14 | | | |
| 15 | LL | trait U<T> { | |
| 16 | | +++ | |
| 17 | ||
| 18 | error[E0401]: can't use generic parameters from outer item | |
| 19 | --> $DIR/outer-generic-in-trait-method.rs:7:30 | |
| 20 | | | |
| 21 | LL | fn siphash<T>() { | |
| 22 | | - type parameter from outer item | |
| 23 | LL | | |
| 24 | LL | trait U { | |
| 25 | | - generic parameter used in this inner trait | |
| 26 | LL | 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 | |
| 30 | help: try introducing a local generic parameter here | |
| 31 | | | |
| 32 | LL | trait U<T> { | |
| 33 | | +++ | |
| 34 | ||
| 35 | error: aborting due to 2 previous errors | |
| 36 | ||
| 37 | For 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 | ||
| 4 | trait SipHash { | |
| 5 | fn result(&self) -> u64; | |
| 6 | fn reset(&self); | |
| 7 | } | |
| 8 | ||
| 9 | fn 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 | ||
| 31 | fn main() {} |
tests/ui/resolve/trait-impl-cant-capture-env.stderr created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | error[E0434]: can't capture dynamic environment in a fn item | |
| 2 | --> $DIR/trait-impl-cant-capture-env.rs:24:23 | |
| 3 | | | |
| 4 | LL | self.v0 = k0 ^ 0x736f6d6570736575; | |
| 5 | | ^^ | |
| 6 | | | |
| 7 | = help: use the `|| { ... }` closure form instead | |
| 8 | ||
| 9 | error[E0434]: can't capture dynamic environment in a fn item | |
| 10 | --> $DIR/trait-impl-cant-capture-env.rs:25:23 | |
| 11 | | | |
| 12 | LL | self.v1 = k1 ^ 0x646f72616e646f6d; | |
| 13 | | ^^ | |
| 14 | | | |
| 15 | = help: use the `|| { ... }` closure form instead | |
| 16 | ||
| 17 | error: aborting due to 2 previous errors | |
| 18 | ||
| 19 | For more information about this error, try `rustc --explain E0434`. |
tests/ui/self/where-for-self.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | // Test that we can quantify lifetimes outside a constraint (i.e., including |
| 3 | 3 | // the self type) in a where clause. |
| 4 | 4 | |
| 5 | // FIXME(static_mut_refs): this could use an atomic | |
| 5 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 6 | 6 | #![allow(static_mut_refs)] |
| 7 | 7 | |
| 8 | 8 | static mut COUNT: u32 = 1; |
tests/ui/stats/input-stats.stderr+4-4| ... | ... | @@ -27,7 +27,7 @@ ast-stats Pat 560 (NN.N%) 7 80 |
| 27 | 27 | ast-stats - Struct 80 (NN.N%) 1 |
| 28 | 28 | ast-stats - Wild 80 (NN.N%) 1 |
| 29 | 29 | ast-stats - Ident 400 (NN.N%) 5 |
| 30 | ast-stats GenericParam 480 (NN.N%) 5 96 | |
| 30 | ast-stats GenericParam 400 (NN.N%) 5 80 | |
| 31 | 31 | ast-stats GenericBound 352 (NN.N%) 4 88 |
| 32 | 32 | ast-stats - Trait 352 (NN.N%) 4 |
| 33 | 33 | ast-stats AssocItem 320 (NN.N%) 4 80 |
| ... | ... | @@ -50,14 +50,14 @@ ast-stats Local 96 (NN.N%) 1 96 |
| 50 | 50 | ast-stats Arm 96 (NN.N%) 2 48 |
| 51 | 51 | ast-stats ForeignItem 80 (NN.N%) 1 80 |
| 52 | 52 | ast-stats - Fn 80 (NN.N%) 1 |
| 53 | ast-stats WherePredicate 72 (NN.N%) 1 72 | |
| 54 | ast-stats - BoundPredicate 72 (NN.N%) 1 | |
| 53 | ast-stats WherePredicate 56 (NN.N%) 1 56 | |
| 54 | ast-stats - BoundPredicate 56 (NN.N%) 1 | |
| 55 | 55 | ast-stats ExprField 48 (NN.N%) 1 48 |
| 56 | 56 | ast-stats GenericArgs 40 (NN.N%) 1 40 |
| 57 | 57 | ast-stats - AngleBracketed 40 (NN.N%) 1 |
| 58 | 58 | ast-stats Crate 40 (NN.N%) 1 40 |
| 59 | 59 | ast-stats ---------------------------------------------------------------- |
| 60 | ast-stats Total 7_624 127 | |
| 60 | ast-stats Total 7_528 127 | |
| 61 | 61 | ast-stats ================================================================ |
| 62 | 62 | hir-stats ================================================================ |
| 63 | 63 | hir-stats HIR STATS: input_stats |
tests/ui/thread-local/thread-local-issue-37508.rs+1-1| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Regression test for issue #37508 |
| 6 | 6 | |
| 7 | // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint | |
| 7 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 8 | 8 | #![allow(static_mut_refs)] |
| 9 | 9 | |
| 10 | 10 | #![no_main] |
tests/ui/traits/impl.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | |
| 4 | 4 | //@ aux-build:traitimpl.rs |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): this could use an atomic | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | extern crate traitimpl; |
tests/ui/union/union-drop-assign.rs+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | |
| 4 | 4 | // Drop works for union itself. |
| 5 | 5 | |
| 6 | // FIXME(static_mut_refs): this could use an atomic | |
| 6 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 7 | 7 | #![allow(static_mut_refs)] |
| 8 | 8 | |
| 9 | 9 | use std::mem::ManuallyDrop; |
tests/ui/union/union-drop.rs+1-1| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | #![allow(dead_code)] |
| 4 | 4 | #![allow(unused_variables)] |
| 5 | // FIXME(static_mut_refs): this could use an atomic | |
| 5 | // FIXME(static_mut_refs): use raw pointers instead of references | |
| 6 | 6 | #![allow(static_mut_refs)] |
| 7 | 7 | |
| 8 | 8 | // Drop works for union itself. |