Auto merge of #115126 - Dylan-DPC:rollup-g6w3qjd, r=Dylan-DPC

Rollup of 7 pull requests

Successful merges:

 - #114930 (Automatically add OS labels to std PRs)
 - #115053 (docs: Add example, reference link for `type` keyword.)
 - #115092 (Add generics_of to smir)
 - #115096 (Add regression test for not `memcpy`ing padding bytes)
 - #115100 (Add support for `ptr::write`s for the `invalid_reference_casting` lint)
 - #115114 (Contents of reachable statics is reachable)
 - #115122 (Fix clippy lint for identical `if`/`else` contraining `?` expressions)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-08-23 07:16:47 +00:00
commit 810573919f
18 changed files with 383 additions and 46 deletions

View File

@ -56,20 +56,7 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx rustc_hir::Stmt<'tc
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
// &mut <expr>
let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
expr
// <expr> = ...
} else if let ExprKind::Assign(expr, _, _) = expr.kind {
expr
// <expr> += ...
} else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
expr
} else {
return;
};
let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else {
let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else {
return;
};
@ -86,15 +73,58 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
cx.emit_spanned_lint(
INVALID_REFERENCE_CASTING,
expr.span,
if matches!(expr.kind, ExprKind::AddrOf(..)) {
InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
} else {
if is_assignment {
InvalidReferenceCastingDiag::AssignToRef { orig_cast }
} else {
InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
},
);
}
}
fn is_operation_we_care_about<'tcx>(
cx: &LateContext<'tcx>,
e: &'tcx Expr<'tcx>,
) -> Option<(bool, &'tcx Expr<'tcx>)> {
fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> {
// &mut <expr>
let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
expr
// <expr> = ...
} else if let ExprKind::Assign(expr, _, _) = expr.kind {
expr
// <expr> += ...
} else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
expr
} else {
return None;
};
if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind {
Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e))
} else {
None
}
}
fn ptr_write<'tcx>(
cx: &LateContext<'tcx>,
e: &'tcx Expr<'tcx>,
) -> Option<(bool, &'tcx Expr<'tcx>)> {
if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind
&& let ExprKind::Path(ref qpath) = path.kind
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
&& matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned))
{
Some((true, arg_ptr))
} else {
None
}
}
deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
}
fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
let e = e.peel_blocks();

View File

@ -98,15 +98,11 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
self.worklist.push(def_id);
} else {
match res {
// If this path leads to a constant, then we need to
// recurse into the constant to continue finding
// items that are reachable.
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
// Reachable constants and reachable statics can have their contents inlined
// into other crates. Mark them as reachable and recurse into their body.
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => {
self.worklist.push(def_id);
}
// If this wasn't a static, then the destination is
// surely reachable.
_ => {
self.reachable_symbols.insert(def_id);
}

View File

@ -80,6 +80,10 @@ pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
self.def_ids[impl_def.0]
}
pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
self.def_ids[generic_def.0]
}
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
stable_mir::CrateItem(self.create_def_id(did))
}
@ -120,6 +124,10 @@ pub fn trait_def(&mut self, did: DefId) -> stable_mir::ty::TraitDef {
stable_mir::ty::TraitDef(self.create_def_id(did))
}
pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
stable_mir::ty::GenericDef(self.create_def_id(did))
}
pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
stable_mir::ty::ConstDef(self.create_def_id(did))
}

View File

@ -10,7 +10,8 @@
use crate::rustc_internal::{self, opaque};
use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
use crate::stable_mir::ty::{
allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy,
Movability, RigidTy, TyKind, UintTy,
};
use crate::stable_mir::{self, Context};
use rustc_hir as hir;
@ -101,6 +102,12 @@ fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
let ty = self.types[ty.0];
ty.stable(self)
}
fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics {
let def_id = self.generic_def_id(generic_def);
let generic_def = self.tcx.generics_of(def_id);
generic_def.stable(self)
}
}
pub struct Tables<'tcx> {
@ -1205,3 +1212,67 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
}
}
impl<'tcx> Stable<'tcx> for ty::Generics {
type T = stable_mir::ty::Generics;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::Generics;
let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect();
let param_def_id_to_index =
params.iter().map(|param| (param.def_id, param.index)).collect();
Generics {
parent: self.parent.map(|did| tables.generic_def(did)),
parent_count: self.parent_count,
params,
param_def_id_to_index,
has_self: self.has_self,
has_late_bound_regions: self
.has_late_bound_regions
.as_ref()
.map(|late_bound_regions| late_bound_regions.stable(tables)),
host_effect_index: self.host_effect_index,
}
}
}
impl<'tcx> Stable<'tcx> for rustc_span::Span {
type T = stable_mir::ty::Span;
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
opaque(self)
}
}
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
type T = stable_mir::ty::GenericParamDefKind;
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::GenericParamDefKind;
match self {
ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
ty::GenericParamDefKind::Type { has_default, synthetic } => {
GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
}
ty::GenericParamDefKind::Const { has_default } => {
GenericParamDefKind::Const { has_default: *has_default }
}
}
}
}
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
type T = stable_mir::ty::GenericParamDef;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
GenericParamDef {
name: self.name.to_string(),
def_id: tables.generic_def(self.def_id),
index: self.index,
pure_wrt_drop: self.pure_wrt_drop,
kind: self.kind.stable(tables),
}
}
}

View File

@ -15,7 +15,7 @@
use crate::rustc_smir::Tables;
use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
use self::ty::{GenericDef, Generics, ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
pub mod mir;
pub mod ty;
@ -110,6 +110,7 @@ pub trait Context {
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
fn all_trait_impls(&mut self) -> ImplTraitDecls;
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
fn generics_of(&mut self, generic_def: &GenericDef) -> Generics;
/// Get information about the local crate.
fn local_crate(&self) -> Crate;
/// Retrieve a list of all external crates.

View File

@ -22,7 +22,7 @@ pub struct Const {
type Ident = Opaque;
pub(crate) type Region = Opaque;
type Span = Opaque;
pub type Span = Opaque;
#[derive(Clone, Debug)]
pub enum TyKind {
@ -87,34 +87,37 @@ pub enum Movability {
Movable,
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ForeignDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct FnDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ClosureDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct GeneratorDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ParamDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct BrNamedDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AdtDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AliasDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct TraitDef(pub(crate) DefId);
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct GenericDef(pub(crate) DefId);
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ConstDef(pub(crate) DefId);
impl TraitDef {
@ -132,6 +135,12 @@ pub fn trait_impl(&self) -> ImplTrait {
}
}
impl GenericDef {
pub fn generics_of(&self) -> Generics {
with(|tcx| tcx.generics_of(self))
}
}
#[derive(Clone, Debug)]
pub struct GenericArgs(pub Vec<GenericArgKind>);
@ -461,3 +470,30 @@ pub struct TraitRef {
pub def_id: TraitDef,
pub args: GenericArgs,
}
#[derive(Clone, Debug)]
pub struct Generics {
pub parent: Option<GenericDef>,
pub parent_count: usize,
pub params: Vec<GenericParamDef>,
pub param_def_id_to_index: Vec<(GenericDef, u32)>,
pub has_self: bool,
pub has_late_bound_regions: Option<Span>,
pub host_effect_index: Option<usize>,
}
#[derive(Clone, Debug)]
pub enum GenericParamDefKind {
Lifetime,
Type { has_default: bool, synthetic: bool },
Const { has_default: bool },
}
#[derive(Clone, Debug)]
pub struct GenericParamDef {
pub name: super::Symbol,
pub def_id: GenericDef,
pub index: u32,
pub pure_wrt_drop: bool,
pub kind: GenericParamDefKind,
}

View File

@ -1179,6 +1179,9 @@
ptr_offset_from,
ptr_offset_from_unsigned,
ptr_unique,
ptr_write,
ptr_write_unaligned,
ptr_write_volatile,
pub_macro_rules,
pub_restricted,
public,

View File

@ -1357,6 +1357,7 @@ macro_rules! attempt_swap_as_chunks {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
#[rustc_diagnostic_item = "ptr_write"]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn write<T>(dst: *mut T, src: T) {
// Semantically, it would be fine for this to be implemented as a
@ -1459,6 +1460,7 @@ macro_rules! attempt_swap_as_chunks {
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
#[rustc_diagnostic_item = "ptr_write_unaligned"]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
// SAFETY: the caller must guarantee that `dst` is valid for writes.
@ -1607,6 +1609,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
/// ```
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
#[rustc_diagnostic_item = "ptr_write_volatile"]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
// SAFETY: the caller must uphold the safety contract for `volatile_store`.

View File

@ -1820,7 +1820,7 @@ mod true_keyword {}
#[doc(keyword = "type")]
//
/// Define an alias for an existing type.
/// Define an [alias] for an existing type.
///
/// The syntax is `type Name = ExistingType;`.
///
@ -1838,6 +1838,13 @@ mod true_keyword {}
/// assert_eq!(m, k);
/// ```
///
/// A type can be generic:
///
/// ```rust
/// # use std::sync::{Arc, Mutex};
/// type ArcMutex<T> = Arc<Mutex<T>>;
/// ```
///
/// In traits, `type` is used to declare an [associated type]:
///
/// ```rust
@ -1860,6 +1867,7 @@ mod true_keyword {}
///
/// [`trait`]: keyword.trait.html
/// [associated type]: ../reference/items/associated-items.html#associated-types
/// [alias]: ../reference/items/type-aliases.html
mod type_keyword {}
#[doc(keyword = "unsafe")]

View File

@ -10,6 +10,7 @@
GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
};
use rustc_hir::MatchSource::TryDesugar;
use rustc_lexer::{tokenize, TokenKind};
use rustc_lint::LateContext;
use rustc_middle::ty::TypeckResults;
@ -311,7 +312,7 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
},
(&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => {
ls == rs
(ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))
&& self.eq_expr(le, re)
&& over(la, ra, |l, r| {
self.eq_pat(l.pat, r.pat)

View File

@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
};
if true {
// FIXME: should emit "this `if` has identical blocks"
//~^ ERROR: this `if` has identical blocks
Ok("foo")?;
} else {
Ok("foo")?;

View File

@ -82,6 +82,25 @@ LL | | f32::NAN
LL | | };
| |_____^
error: this `if` has identical blocks
--> $DIR/if_same_then_else2.rs:100:13
|
LL | if true {
| _____________^
LL | |
LL | | Ok("foo")?;
LL | | } else {
| |_____^
|
note: same as this
--> $DIR/if_same_then_else2.rs:103:12
|
LL | } else {
| ____________^
LL | | Ok("foo")?;
LL | | }
| |_____^
error: this `if` has identical blocks
--> $DIR/if_same_then_else2.rs:124:20
|
@ -103,5 +122,5 @@ LL | | return Ok(&foo[0..]);
LL | | }
| |_____^
error: aborting due to 5 previous errors
error: aborting due to 6 previous errors

View File

@ -25,6 +25,20 @@ pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
Box::new(MaybeUninit::uninit())
}
#[repr(align(1024))]
pub struct LotsaPadding(usize);
// Boxing a value with padding should not copy junk from the stack
#[no_mangle]
pub fn box_lotsa_padding() -> Box<LotsaPadding> {
// CHECK-LABEL: @box_lotsa_padding
// CHECK-NOT: alloca
// CHECK-NOT: getelementptr
// CHECK-NOT: memcpy
// CHECK-NOT: memset
Box::new(LotsaPadding(42))
}
// Hide the `allocalign` attribute in the declaration of __rust_alloc
// from the CHECK-NOT above, and also verify the attributes got set reasonably.
// CHECK: declare {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]

View File

@ -1,10 +1,14 @@
pub static V: &u32 = &X;
pub static F: fn() = f;
pub static G: fn() = G0;
static X: u32 = 42;
static G0: fn() = g;
pub fn v() -> *const u32 {
V
}
fn f() {}
fn g() {}

View File

@ -1,9 +1,11 @@
// Regression test for #84455 and #115052.
// run-pass
// aux-build:static_init_aux.rs
extern crate static_init_aux as aux;
static V: &u32 = aux::V;
static F: fn() = aux::F;
static G: fn() = aux::G;
fn v() -> *const u32 {
V
@ -12,4 +14,5 @@ fn v() -> *const u32 {
fn main() {
assert_eq!(aux::v(), crate::v());
F();
G();
}

View File

@ -71,6 +71,11 @@ unsafe fn assign_to_ref() {
//~^ ERROR assigning to `&T` is undefined behavior
*std::mem::transmute::<_, *mut i32>(num) += 1;
//~^ ERROR assigning to `&T` is undefined behavior
std::ptr::write(
//~^ ERROR assigning to `&T` is undefined behavior
std::mem::transmute::<*const i32, *mut i32>(num),
-1i32,
);
let value = num as *const i32 as *mut i32;
*value = 1;
@ -79,6 +84,12 @@ unsafe fn assign_to_ref() {
//~^ ERROR assigning to `&T` is undefined behavior
*(num as *const _ as usize as *mut i32) = 2;
//~^ ERROR assigning to `&T` is undefined behavior
std::ptr::write(value, 2);
//~^ ERROR assigning to `&T` is undefined behavior
std::ptr::write_unaligned(value, 2);
//~^ ERROR assigning to `&T` is undefined behavior
std::ptr::write_volatile(value, 2);
//~^ ERROR assigning to `&T` is undefined behavior
unsafe fn generic_assign_to_ref<T>(this: &T, a: T) {
*(this as *const _ as *mut _) = a;

View File

@ -131,7 +131,17 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:76:5
--> $DIR/reference_casting.rs:74:5
|
LL | / std::ptr::write(
LL | |
LL | | std::mem::transmute::<*const i32, *mut i32>(num),
LL | | -1i32,
LL | | );
| |_____^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:81:5
|
LL | let value = num as *const i32 as *mut i32;
| ----------------------------- casting happend here
@ -139,22 +149,49 @@ LL | *value = 1;
| ^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:78:5
--> $DIR/reference_casting.rs:83:5
|
LL | *(num as *const i32).cast::<i32>().cast_mut() = 2;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:80:5
--> $DIR/reference_casting.rs:85:5
|
LL | *(num as *const _ as usize as *mut i32) = 2;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:84:9
--> $DIR/reference_casting.rs:87:5
|
LL | let value = num as *const i32 as *mut i32;
| ----------------------------- casting happend here
...
LL | std::ptr::write(value, 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:89:5
|
LL | let value = num as *const i32 as *mut i32;
| ----------------------------- casting happend here
...
LL | std::ptr::write_unaligned(value, 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:91:5
|
LL | let value = num as *const i32 as *mut i32;
| ----------------------------- casting happend here
...
LL | std::ptr::write_volatile(value, 2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
--> $DIR/reference_casting.rs:95:9
|
LL | *(this as *const _ as *mut _) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 25 previous errors
error: aborting due to 29 previous errors

View File

@ -177,6 +177,98 @@ exclude_labels = [
"T-*",
]
[autolabel."O-android"]
trigger_files = [
"library/std/src/os/android"
]
[autolabel."O-fuchsia"]
trigger_files = [
"library/std/src/os/fuchsia"
]
[autolabel."O-hermit"]
trigger_files = [
"library/std/src/sys/hermit",
"library/std/src/os/hermit"
]
[autolabel."O-ios"]
trigger_files = [
"library/std/src/os/ios"
]
[autolabel."O-itron"]
trigger_files = [
"library/std/src/sys/itron"
]
[autolabel."O-linux"]
trigger_files = [
"library/std/src/os/linux"
]
[autolabel."O-macos"]
trigger_files = [
"library/std/src/os/macos"
]
[autolabel."O-netbsd"]
trigger_files = [
"library/std/src/os/netbsd"
]
[autolabel."O-redox"]
trigger_files = [
"library/std/src/os/redox"
]
[autolabel."O-SGX"]
trigger_files = [
"library/std/src/sys/sgx",
"library/std/src/os/fortanix_sgx"
]
[autolabel."O-solaris"]
trigger_files = [
"library/std/src/os/solaris"
]
[autolabel."O-solid"]
trigger_files = [
"library/std/src/sys/solid",
"library/std/src/os/solid"
]
[autolabel."O-unix"]
trigger_files = [
"library/std/src/sys/unix",
"library/std/src/os/unix"
]
[autolabel."O-wasi"]
trigger_files = [
"library/std/src/sys/wasi",
"library/std/src/os/wasi"
]
[autolabel."O-wasm"]
trigger_files = [
"library/std/src/sys/wasm",
"library/std/src/os/wasm"
]
[autolabel."O-watchos"]
trigger_files = [
"library/std/src/os/watchos"
]
[autolabel."O-windows"]
trigger_files = [
"library/std/src/sys/windows",
"library/std/src/os/windows"
]
[autolabel."T-bootstrap"]
trigger_files = [
"x.py",