Skip to content

Rollup of 11 pull requests #141739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8bed646
Enable review queue tracking
Kobzol May 22, 2025
19fd098
float: Disable `total_cmp` sNaN tests for `f16`
tgross35 May 28, 2025
0527f02
Add `eslint` as part of tidy run
GuillaumeGomez May 28, 2025
9e5dd51
Remove checks that are run with `tidy`
GuillaumeGomez May 28, 2025
c593c01
Remove codegen_unit from MiscCodegenMethods
bjorn3 Dec 13, 2024
5b0ab2c
The personality function is a Function, not a Value
bjorn3 Dec 13, 2024
a4cb1c7
Reduce amount of types that need to be PartialEq
bjorn3 Dec 13, 2024
0fd257d
Remove a couple of uses of interior mutability around statics
bjorn3 Dec 13, 2024
0809b41
Move supports_parallel from CodegenBackend to ExtraBackendMethods
bjorn3 Jan 9, 2025
669e2ea
Make predefine methods take &mut self
bjorn3 Jan 9, 2025
d7c0bde
Remove methods from StaticCodegenMethods that are not called in cg_ss…
bjorn3 Jan 9, 2025
f0707fa
Mark all optimize methods and the codegen method as safe
bjorn3 Jan 9, 2025
865c7b9
Remove unused arg_memory_ty method
bjorn3 Nov 7, 2024
b2858f3
Add `loongarch64` with `d` feature to `f32::midpoint` fast path
heiher May 24, 2025
367a877
avoid some usages of `&mut P<T>` in AST visitors
fee1-dead May 27, 2025
059bc38
Provide secrets to try builds with new bors
Kobzol May 29, 2025
8e5d579
Fix false documentation
JonathanBrouwer May 29, 2025
8c8d2c2
creader: Remove extraenous String::clone
osiewicz May 29, 2025
0d9f25b
resolve target-libdir directly from rustc
onur-ozkan May 29, 2025
f0f661d
Install eslint in host-x86_64 Dockerfile
GuillaumeGomez May 29, 2025
b1723fc
Centralize the eslint version between tidy and docker
GuillaumeGomez May 29, 2025
a5f3b1e
Make `std/src/num` mirror `core/src/num`
tgross35 Feb 25, 2025
8645ef7
Fix npm install error
GuillaumeGomez May 29, 2025
be64109
Rollup merge of #137574 - tgross35:std-float-reorganization, r=workin…
GuillaumeGomez May 29, 2025
08bbf24
Rollup merge of #141384 - Kobzol:enable-review-prefs, r=jieyouxu
GuillaumeGomez May 29, 2025
161cf3e
Rollup merge of #141448 - bjorn3:codegen_refactors, r=WaffleLapkin
GuillaumeGomez May 29, 2025
2b08e4d
Rollup merge of #141636 - fee1-dead-contrib:push-ntqvvxwuvrvx, r=petr…
GuillaumeGomez May 29, 2025
cb7efc0
Rollup merge of #141676 - tgross35:f16-disable-total-cmp, r=workingju…
GuillaumeGomez May 29, 2025
a547af9
Rollup merge of #141705 - GuillaumeGomez:eslint-tidy, r=Kobzol
GuillaumeGomez May 29, 2025
8c708a4
Rollup merge of #141715 - heiher:loong64-f32-midpoint, r=the8472
GuillaumeGomez May 29, 2025
5f6f23a
Rollup merge of #141723 - Kobzol:new-bors-try, r=marcoieni
GuillaumeGomez May 29, 2025
710fa11
Rollup merge of #141728 - JonathanBrouwer:fix-docs, r=compiler-errors
GuillaumeGomez May 29, 2025
aaa9159
Rollup merge of #141729 - onur-ozkan:fix-141722, r=jieyouxu
GuillaumeGomez May 29, 2025
18646a8
Rollup merge of #141732 - osiewicz:creader-remove-extraenous-string-c…
GuillaumeGomez May 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ concurrency:
# For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
# We add an exception for try builds (try branch) and unrolled rollup builds (try-perf), which
# are all triggered on the same branch, but which should be able to run concurrently.
group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.sha) || github.ref }}
group: ${{ github.workflow }}-${{ ((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try') && github.sha) || github.ref }}
cancel-in-progress: true
env:
TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
# access the environment.
#
# We only enable the environment for the rust-lang/rust repository, so that CI works on forks.
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/auto')) && 'bors') || '' }}
environment: ${{ ((github.repository == 'rust-lang/rust' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf' || github.ref == 'refs/heads/automation/bors/try' || github.ref == 'refs/heads/auto')) && 'bors') || '' }}
env:
CI_JOB_NAME: ${{ matrix.name }}
CI_JOB_DOC_URL: ${{ matrix.doc_url }}
Expand Down
44 changes: 22 additions & 22 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ pub trait MutVisitor: Sized {
walk_use_tree(self, use_tree);
}

fn visit_foreign_item(&mut self, ni: &mut P<ForeignItem>) {
fn visit_foreign_item(&mut self, ni: &mut ForeignItem) {
walk_item(self, ni);
}

fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
walk_flat_map_foreign_item(self, ni)
}

fn visit_item(&mut self, i: &mut P<Item>) {
fn visit_item(&mut self, i: &mut Item) {
walk_item(self, i);
}

Expand All @@ -105,7 +105,7 @@ pub trait MutVisitor: Sized {
walk_flat_map_field_def(self, fd)
}

fn visit_assoc_item(&mut self, i: &mut P<AssocItem>, ctxt: AssocCtxt) {
fn visit_assoc_item(&mut self, i: &mut AssocItem, ctxt: AssocCtxt) {
walk_assoc_item(self, i, ctxt)
}

Expand All @@ -117,11 +117,11 @@ pub trait MutVisitor: Sized {
walk_flat_map_assoc_item(self, i, ctxt)
}

fn visit_contract(&mut self, c: &mut P<FnContract>) {
fn visit_contract(&mut self, c: &mut FnContract) {
walk_contract(self, c);
}

fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
fn visit_fn_decl(&mut self, d: &mut FnDecl) {
walk_fn_decl(self, d);
}

Expand All @@ -138,7 +138,7 @@ pub trait MutVisitor: Sized {
walk_closure_binder(self, b);
}

fn visit_block(&mut self, b: &mut P<Block>) {
fn visit_block(&mut self, b: &mut Block) {
walk_block(self, b);
}

Expand Down Expand Up @@ -184,7 +184,7 @@ pub trait MutVisitor: Sized {
walk_ty(self, t);
}

fn visit_ty_pat(&mut self, t: &mut P<TyPat>) {
fn visit_ty_pat(&mut self, t: &mut TyPat) {
walk_ty_pat(self, t);
}

Expand Down Expand Up @@ -240,7 +240,7 @@ pub trait MutVisitor: Sized {
walk_parenthesized_parameter_data(self, p);
}

fn visit_local(&mut self, l: &mut P<Local>) {
fn visit_local(&mut self, l: &mut Local) {
walk_local(self, l);
}

Expand Down Expand Up @@ -507,8 +507,8 @@ fn walk_assoc_item_constraint<T: MutVisitor>(
vis.visit_span(span);
}

pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
let Ty { id, kind, span, tokens: _ } = ty.deref_mut();
pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut Ty) {
let Ty { id, kind, span, tokens: _ } = ty;
vis.visit_id(id);
match kind {
TyKind::Err(_guar) => {}
Expand Down Expand Up @@ -559,8 +559,8 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
vis.visit_span(span);
}

pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
let TyPat { id, kind, span, tokens: _ } = ty.deref_mut();
pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut TyPat) {
let TyPat { id, kind, span, tokens: _ } = ty;
vis.visit_id(id);
match kind {
TyPatKind::Range(start, end, _include_end) => {
Expand Down Expand Up @@ -651,8 +651,8 @@ fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut Pare
vis.visit_span(inputs_span);
}

fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut P<Local>) {
let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local.deref_mut();
fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut Local) {
let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local;
visit_opt(super_, |sp| vis.visit_span(sp));
vis.visit_id(id);
visit_attrs(vis, attrs);
Expand Down Expand Up @@ -789,8 +789,8 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) {
}
}

fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) {
let FnContract { requires, ensures } = contract.deref_mut();
fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut FnContract) {
let FnContract { requires, ensures } = contract;
if let Some(pred) = requires {
vis.visit_expr(pred);
}
Expand All @@ -799,8 +799,8 @@ fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) {
}
}

fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut P<FnDecl>) {
let FnDecl { inputs, output } = decl.deref_mut();
fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut FnDecl) {
let FnDecl { inputs, output } = decl;
inputs.flat_map_in_place(|param| vis.flat_map_param(param));
vis.visit_fn_ret_ty(output);
}
Expand Down Expand Up @@ -999,8 +999,8 @@ pub fn walk_flat_map_expr_field<T: MutVisitor>(
smallvec![f]
}

pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) {
let Block { id, stmts, rules: _, span, tokens: _ } = block.deref_mut();
pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut Block) {
let Block { id, stmts, rules: _, span, tokens: _ } = block;
vis.visit_id(id);
stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
vis.visit_span(span);
Expand Down Expand Up @@ -1049,8 +1049,8 @@ pub fn walk_flat_map_assoc_item(
smallvec![item]
}

pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) {
let Pat { id, kind, span, tokens: _ } = pat.deref_mut();
pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut Pat) {
let Pat { id, kind, span, tokens: _ } = pat;
vis.visit_id(id);
match kind {
PatKind::Err(_guar) => {}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,10 @@ macro_rules! common_visitor_and_walkers {

fn walk_item_ctxt<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind>(
visitor: &mut V,
item: &$($mut P<Item<K>>)? $($lt Item<K>)?,
item: &$($mut)? $($lt)? Item<K>,
ctxt: K::Ctxt,
) $(-> <V as Visitor<$lt>>::Result)? {
let Item { attrs, id, kind, vis, span, tokens: _ } = &$($mut *)? *item;
let Item { attrs, id, kind, vis, span, tokens: _ } = item;
try_visit!(visit_id(visitor, id));
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
Expand All @@ -417,14 +417,14 @@ macro_rules! common_visitor_and_walkers {

pub fn walk_item<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind<Ctxt = ()>>(
visitor: &mut V,
item: &$($mut P<Item<K>>)? $($lt Item<K>)?,
item: &$($mut)? $($lt)? Item<K>,
) $(-> <V as Visitor<$lt>>::Result)? {
walk_item_ctxt(visitor, item, ())
}

pub fn walk_assoc_item<$($lt,)? V: $Visitor$(<$lt>)?>(
visitor: &mut V,
item: &$($mut P<AssocItem>)? $($lt AssocItem)?,
item: &$($mut)? $($lt)? AssocItem,
ctxt: AssocCtxt,
) $(-> <V as Visitor<$lt>>::Result)? {
walk_item_ctxt(visitor, item, ctxt)
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
c.items.push(mk_main(&mut self.cx));
}

fn visit_item(&mut self, item: &mut P<ast::Item>) {
let item = &mut **item;

fn visit_item(&mut self, item: &mut ast::Item) {
if let Some(name) = get_test_name(&item) {
debug!("this is a test item");

Expand Down Expand Up @@ -193,7 +191,7 @@ struct EntryPointCleaner<'a> {
}

impl<'a> MutVisitor for EntryPointCleaner<'a> {
fn visit_item(&mut self, item: &mut P<ast::Item>) {
fn visit_item(&mut self, item: &mut ast::Item) {
self.depth += 1;
ast::mut_visit::walk_item(self, item);
self.depth -= 1;
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use rustc_target::callconv::{Conv, RiscvInterruptKind};

use crate::builder::Builder;
use crate::context::CodegenCx;
use crate::intrinsic::ArgAbiExt;
use crate::type_of::LayoutGccExt;

impl AbiBuilderMethods for Builder<'_, '_, '_> {
Expand Down Expand Up @@ -125,7 +124,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx),
PassMode::Cast { ref cast, .. } => cast.gcc_type(cx),
PassMode::Indirect { .. } => {
argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
argument_tys.push(cx.type_ptr_to(self.ret.layout.gcc_type(cx)));
cx.type_void()
}
};
Expand Down Expand Up @@ -176,13 +175,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => {
// This is a "byval" argument, so we don't apply the `restrict` attribute on it.
on_stack_param_indices.insert(argument_tys.len());
arg.memory_ty(cx)
arg.layout.gcc_type(cx)
}
PassMode::Direct(attrs) => {
apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len())
}
PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len())
apply_attrs(cx.type_ptr_to(arg.layout.gcc_type(cx)), &attrs, argument_tys.len())
}
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
assert!(!on_stack);
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_codegen_gcc/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,22 @@ pub fn compile_codegen_unit(

let mono_items = cgu.items_in_deterministic_order(tcx);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
mono_item.predefine::<Builder<'_, '_, '_>>(
&mut cx,
cgu_name.as_str(),
data.linkage,
data.visibility,
);
}

// ... and now that we have everything pre-defined, fill out those definitions.
for &(mono_item, item_data) in &mono_items {
mono_item.define::<Builder<'_, '_, '_>>(&mut cx, item_data);
mono_item.define::<Builder<'_, '_, '_>>(&mut cx, cgu_name.as_str(), item_data);
}

// If this codegen unit contains the main function, also create the
// wrapper here
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx);
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx, cx.codegen_unit);

// Finalize debuginfo
if cx.sess().opts.debuginfo != DebugInfo::None {
Expand Down
13 changes: 4 additions & 9 deletions compiler/rustc_codegen_gcc/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
}

#[cfg_attr(not(feature = "master"), allow(unused_mut))]
fn codegen_static(&self, def_id: DefId) {
fn codegen_static(&mut self, def_id: DefId) {
let attrs = self.tcx.codegen_fn_attrs(def_id);

let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else {
Expand Down Expand Up @@ -160,19 +160,14 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
self.add_used_global(global.to_rvalue());
}
}
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
/// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*.
fn add_used_global(&self, _global: RValue<'gcc>) {
pub fn add_used_global(&mut self, _global: RValue<'gcc>) {
// TODO(antoyo)
}

fn add_compiler_used_global(&self, global: RValue<'gcc>) {
// NOTE: seems like GCC does not make the distinction between compiler.used and used.
self.add_used_global(global);
}
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature = "master"), allow(unused_variables))]
pub fn add_used_function(&self, function: Function<'gcc>) {
#[cfg(feature = "master")]
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 +470,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.tcx.sess
}

fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> {
self.codegen_unit
}

fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) {
// TODO(antoyo)
}
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,14 +574,9 @@ impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
) {
arg_abi.store(self, val, dst)
}

fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
arg_abi.memory_ty(self)
}
}

pub trait ArgAbiExt<'gcc, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
fn store(
&self,
bx: &mut Builder<'_, 'gcc, 'tcx>,
Expand All @@ -597,12 +592,6 @@ pub trait ArgAbiExt<'gcc, 'tcx> {
}

impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
/// Gets the LLVM type for a place of the original Rust type of
/// this argument/return, i.e., the result of `type_of::type_of`.
fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
self.layout.gcc_type(cx)
}

/// Stores a direct/indirect value described by this ArgAbi into a
/// place for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ impl WriteBackendMethods for GccCodegenBackend {
unimplemented!()
}

unsafe fn optimize(
fn optimize(
_cgcx: &CodegenContext<Self>,
_dcx: DiagCtxtHandle<'_>,
module: &mut ModuleCodegen<Self::Module>,
Expand All @@ -409,14 +409,14 @@ impl WriteBackendMethods for GccCodegenBackend {
Ok(())
}

unsafe fn optimize_thin(
fn optimize_thin(
cgcx: &CodegenContext<Self>,
thin: ThinModule<Self>,
) -> Result<ModuleCodegen<Self::Module>, FatalError> {
back::lto::optimize_thin_module(thin, cgcx)
}

unsafe fn codegen(
fn codegen(
cgcx: &CodegenContext<Self>,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<Self::Module>,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{attributes, base};
impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature = "master"), allow(unused_variables))]
fn predefine_static(
&self,
&mut self,
def_id: DefId,
_linkage: Linkage,
visibility: Visibility,
Expand All @@ -42,7 +42,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {

#[cfg_attr(not(feature = "master"), allow(unused_variables))]
fn predefine_fn(
&self,
&mut self,
instance: Instance<'tcx>,
linkage: Linkage,
visibility: Visibility,
Expand Down
Loading
Loading