1167 Commits

Author SHA1 Message Date
Jacob Pratt
566c13c88e
Rollup merge of #145726 - aapoalas:reborrow-lang-experiment, r=petrochenkov
Experiment: Reborrow trait

Tracking issue: rust-lang/rust#145612

Starting off really small here: just introduce the unstable feature and the feature gate, and one of the two traits that the Reborrow experiment deals with.

### Cliff-notes explanation

The `Reborrow` trait is conceptually a close cousin of `Copy` with the exception that it disables the source (`self`) for the lifetime of the target / result of the reborrow action. It can be viewed as a method of `fn reborrow(self: Self<'a>) -> Self<'a>` with the compiler adding tracking of the resulting `Self<'a>` (or any value derived from it that retains the `'a` lifetime) to keep the `self` disabled for reads and writes.

No method is planned to be surfaced to the user, however, as reborrowing cannot be seen in code (except for method calls [`a.foo()` reborrows `a`] and explicit reborrows [`&*a`]) and thus triggering user-code in it could be viewed as "spooky action at a distance". Furthermore, the added compiler tracking cannot be seen on the method itself, violating the Golden Rule. Note that the userland "reborrow" method is not True Reborrowing, but rather a form of a "Fancy Deref":
```rust
fn reborrow(&'short self: Self<'long>) -> Self<'short>;
```
The lifetime shortening is the issue here: a reborrowed `Self` or any value derived from it is bound to the method that called `reborrow`, since `&'short` is effectively a local variable. True Reborrowing does not shorten the lifetime of the result.

To avoid having to introduce new kinds of references, new kinds of lifetime annotations, or a blessed trait method, no method will be introduced at all. Instead, the `Reborrow` trait is intended to be a derived trait that effectively reborrows each field individually; `Copy` fields end up just copying, while fields that themselves `Reborrow` get disabled in the source, usually leading to the source itself being disabled (some differences may appear with structs that contain multiple reborrowable fields). The goal of the experiment is to determine how the actual implementation here will shape out, and what the "bottom case" for the recursive / deriving `Reborrow` is.

`Reborrow` has a friend trait, `CoerceShared`, which is equivalent to a `&'a mut T -> &'a T` conversion. This is needed as a different trait and different operation due to the different semantics it enforces on the source: a `CoerceShared` operation only disables the source for writes / exclusive access for the lifetime of the result. That trait is not yet introduced in this PR, though there is no particular reason why it could not be introduced.
2025-08-22 22:00:55 -04:00
Luca Versari
291da71b2a Add an experimental unsafe(force_target_feature) attribute.
This uses the feature gate for
https://github.com/rust-lang/rust/issues/143352, but is described in
https://github.com/rust-lang/rfcs/pull/3820 which is strongly tied to
the experiment.
2025-08-22 01:26:26 +02:00
Aapo Alasuutari
5af359162e Introduce Reborrow lang item and trait 2025-08-21 23:53:25 +03:00
Aapo Alasuutari
719880dd2a Introduce reborrow unstable feature 2025-08-21 23:38:20 +03:00
bors
040a98af70 Auto merge of #144086 - clubby789:alloc-zeroed, r=nikic
Pass `alloc-variant-zeroed` to LLVM

Makes use of https://github.com/llvm/llvm-project/pull/138299 (once we pull in a version of LLVM with this attribute). ~~Unfortunately also requires https://github.com/llvm/llvm-project/pull/149336 to work.~~

Closes rust-lang/rust#104847
2025-08-20 17:16:34 +00:00
clubby789
8ea3b09381 Pass alloc-variant-zeroed to LLVM 2025-08-20 17:08:46 +01:00
Stuart Cook
11c6d898b6
Rollup merge of #145243 - jdonszelmann:inner-attr-errors, r=petrochenkov
take attr style into account in diagnostics

when the original attribute was specified as an inner attribute, the suggestion will now match that attribute style
2025-08-19 14:18:23 +10:00
Stuart Cook
633cc0cc6c
Rollup merge of #142681 - 1c3t3a:sanitize-off-on, r=rcvalle
Remove the `#[no_sanitize]` attribute in favor of `#[sanitize(xyz = "on|off")]`

This came up during the sanitizer stabilization (rust-lang/rust#123617). Instead of a `#[no_sanitize(xyz)]` attribute, we would like to have a `#[sanitize(xyz = "on|off")]` attribute, which is more powerful and allows to be extended in the future (instead
of just focusing on turning sanitizers off). The implementation is done according to what was [discussed on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/343119-project-exploit-mitigations/topic/Stabilize.20the.20.60no_sanitize.60.20attribute/with/495377292)).

The new attribute also works on modules, traits and impl items and thus enables usage as the following:
```rust
#[sanitize(address = "off")]
mod foo {
    fn unsanitized(..) {}

    #[sanitize(address = "on")]
    fn sanitized(..) {}
}

trait MyTrait {
  #[sanitize(address = "off")]
  fn unsanitized_default(..) {}
}

#[sanitize(thread = "off")]
impl MyTrait for () {
    ...
}
```

r? ```@rcvalle```
2025-08-19 14:18:16 +10:00
Bastian Kersting
95bdb34494 Remove the no_sanitize attribute in favor of sanitize
This removes the #[no_sanitize] attribute, which was behind an unstable
feature named no_sanitize. Instead, we introduce the sanitize attribute
which is more powerful and allows to be extended in the future (instead
of just focusing on turning sanitizers off).

This also makes sanitize(kernel_address = ..) attribute work with
-Zsanitize=address

To do it the same as how clang disables address sanitizer, we now
disable ASAN on sanitize(kernel_address = "off") and KASAN on
sanitize(address = "off").

The same was added to clang in https://reviews.llvm.org/D44981.
2025-08-18 08:45:28 +00:00
Bastian Kersting
3ef065bf87 Implement the #[sanitize(..)] attribute
This change implements the #[sanitize(..)] attribute, which opts to
replace the currently unstable #[no_sanitize]. Essentially the new
attribute works similar as #[no_sanitize], just with more flexible
options regarding where it is applied. E.g. it is possible to turn
a certain sanitizer either on or off:
`#[sanitize(address = "on|off")]`

This attribute now also applies to more places, e.g. it is possible
to turn off a sanitizer for an entire module or impl block:
```rust
\#[sanitize(address = "off")]
mod foo {
    fn unsanitized(..) {}

    #[sanitize(address = "on")]
    fn sanitized(..) {}
}

\#[sanitize(thread = "off")]
impl MyTrait for () {
    ...
}
```

This attribute is enabled behind the unstable `sanitize` feature.
2025-08-18 08:30:00 +00:00
Stuart Cook
152b43c7cb
Rollup merge of #145208 - joshtriplett:mbe-derive, r=petrochenkov
Implement declarative (`macro_rules!`) derive macros (RFC 3698)

This is a draft for review, and should not be merged yet.

This is layered atop https://github.com/rust-lang/rust/pull/145153 , and has
only two additional commits atop that. The first handles parsing and provides a
test for various parse errors. The second implements expansion and handles
application.

This implements RFC 3698, "Declarative (`macro_rules!`) derive macros".
Tracking issue: https://github.com/rust-lang/rust/issues/143549

This has one remaining issue, which I could use some help debugging: in
`tests/ui/macros/macro-rules-derive-error.rs`, the diagnostics for
`derive(fn_only)` (for a `fn_only` with no `derive` rules) and
`derive(ForwardReferencedDerive)` both get emitted twice, as a duplicate
diagnostic.

From what I can tell via adding some debugging code,
`unresolved_macro_suggestions` is getting called twice from
`finalize_macro_resolutions` for each of them, because
`self.single_segment_macro_resolutions` has two entries for the macro, with two
different `parent_scope` values. I'm not clear on why that happened; it doesn't
happen with the equivalent code using attrs.

I'd welcome any suggestions for fixing this.
2025-08-18 15:31:10 +10:00
bors
2e2642e641 Auto merge of #145304 - m-ou-se:simplify-panic, r=oli-obk
Revert "Partially outline code inside the panic! macro".

This reverts https://github.com/rust-lang/rust/pull/115670

Without any tests/benchmarks that show some improvement, it's hard to know whether the change had any positive effect. (And if it did, whether that effect is still achieved today.)
2025-08-16 10:15:46 +00:00
Jana Dönszelmann
70e26c1b7b
take attr style into account in attr diagnostics 2025-08-16 10:51:09 +02:00
Jakub Beránek
f39085bb37
Add derive_from unstable feature 2025-08-15 12:06:20 +02:00
Josh Triplett
8fb98ef368 mbe: Parse macro derive rules
This handles various kinds of errors, but does not allow applying the
derive yet.

This adds the feature gate `macro_derive`.
2025-08-14 13:53:57 -07:00
sayantn
100d19ce5b
Stabilize sse4a and tbm target features
- remove some stabilized target features from `gate.rs`
2025-08-14 02:07:40 +05:30
Mara Bos
08acba3071 Revert "Partially outline code inside the panic! macro".
Without any tests/benchmarks that show some improvement, it's hard to
know whether the change had any positive effect at all. (And if it did,
whether that effect is still achieved today.)
2025-08-12 12:52:39 +02:00
Esteban Küber
adccb8d214 Rework NameValueStr 2025-08-11 17:02:43 +00:00
Esteban Küber
32ee26c625 Add more docs to templates for attrs with incorrect arguments 2025-08-11 17:02:32 +00:00
Esteban Küber
625143bac3 Add link to docs on malformed attributes 2025-08-11 16:00:49 +00:00
Esteban Küber
189f264926 Allow attr entries to declare list of alternatives for List and NamedValueStr
Modify `AttributeTemplate` to support list of alternatives for list and name value attribute styles.

Suggestions now provide more correct suggested code:

```
error[E0805]: malformed `used` attribute input
  --> $DIR/used_with_multi_args.rs:3:1
   |
LL | #[used(compiler, linker)]
   | ^^^^^^------------------^
   |       |
   |       expected a single argument here
   |
help: try changing it to one of the following valid forms of the attribute
   |
LL - #[used(compiler, linker)]
LL + #[used(compiler)]
   |
LL - #[used(compiler, linker)]
LL + #[used(linker)]
   |
LL - #[used(compiler, linker)]
LL + #[used]
   |
```

instead of the prior "masking" of the lack of this feature by suggesting pipe-separated lists:

```
error[E0805]: malformed `used` attribute input
  --> $DIR/used_with_multi_args.rs:3:1
   |
LL | #[used(compiler, linker)]
   | ^^^^^^------------------^
   |       |
   |       expected a single argument here
   |
help: try changing it to one of the following valid forms of the attribute
   |
LL - #[used(compiler, linker)]
LL + #[used(compiler|linker)]
   |
LL - #[used(compiler, linker)]
LL + #[used]
   |
```
2025-08-11 16:00:49 +00:00
Josh Triplett
feed41c852 Fix an unstable feature comment that wasn't a doc comment
Every other feature in the list uses a doc comment; fix one that used a
regular comment to use a doc comment.
2025-08-09 15:17:02 -07:00
Josh Triplett
bad0d45b2d mbe: Parse macro attribute rules
This handles various kinds of errors, but does not allow applying the
attributes yet.

This adds the feature gate `macro_attr`.
2025-08-08 11:00:54 -07:00
bors
321a89bec5 Auto merge of #145043 - Zalathar:rollup-3dbvdrm, r=Zalathar
Rollup of 19 pull requests

Successful merges:

 - rust-lang/rust#137831 (Tweak auto trait errors)
 - rust-lang/rust#138689 (add nvptx_target_feature)
 - rust-lang/rust#140267 (implement continue_ok and break_ok for ControlFlow)
 - rust-lang/rust#143028 (emit `StorageLive` and schedule `StorageDead` for `let`-`else`'s bindings after matching)
 - rust-lang/rust#143764 (lower pattern bindings in the order they're written and base drop order on primary bindings' order)
 - rust-lang/rust#143808 (Port `#[should_panic]` to the new attribute parsing infrastructure )
 - rust-lang/rust#143906 (Miri: non-deterministic floating point operations in `foreign_items`)
 - rust-lang/rust#143929 (Mark all deprecation lints in name resolution as deny-by-default and report-in-deps)
 - rust-lang/rust#144133 (Stabilize const TypeId::of)
 - rust-lang/rust#144369 (Upgrade semicolon_in_expressions_from_macros from warn to deny)
 - rust-lang/rust#144439 (Introduce ModernIdent type to unify macro 2.0 hygiene handling)
 - rust-lang/rust#144473 (Address libunwind.a inconsistency issues in the bootstrap program)
 - rust-lang/rust#144601 (Allow `cargo fix` to partially apply `mismatched_lifetime_syntaxes`)
 - rust-lang/rust#144650 (Additional tce tests)
 - rust-lang/rust#144659 (bootstrap: refactor mingw dist and fix gnullvm)
 - rust-lang/rust#144682 (Stabilize `strict_overflow_ops`)
 - rust-lang/rust#145026 (Update books)
 - rust-lang/rust#145033 (Reimplement `print_region` in `type_name.rs`.)
 - rust-lang/rust#145040 (rustc-dev-guide subtree update)

Failed merges:

 - rust-lang/rust#143857 (Port #[macro_export] to the new attribute parsing infrastructure)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-08-07 14:01:43 +00:00
Stuart Cook
1cd368a744
Rollup merge of #138689 - jedbrown:jed/nvptx-target-feature, r=ZuseZ4
add nvptx_target_feature

Tracking issue: #141468 (nvptx), which is part of #44839 (catch-all arches)
The feature gate is `#![feature(nvptx_target_feature)]`

This exposes the target features `sm_20` through `sm_120a` [as defined](https://github.com/llvm/llvm-project/blob/llvmorg-20.1.1/llvm/lib/Target/NVPTX/NVPTX.td#L59-L85) by LLVM.

Cc: ``````@gonzalobg``````
``````@rustbot`````` label +O-NVPTX +A-target-feature
2025-08-07 20:49:36 +10:00
Boxy
9ccc9f177e replace version placeholder 2025-08-06 13:22:38 +01:00
bjorn3
ae2f8d9216 Remove the omit_gdb_pretty_printer_section attribute
Disabling loading of pretty printers in the debugger itself is more
reliable. Before this commit the .gdb_debug_scripts section couldn't be
included in dylibs or rlibs as otherwise there is no way to disable the
section anymore without recompiling the entire standard library.
2025-08-01 20:04:59 +00:00
Jana Dönszelmann
e1d3ad89c7
remove rustc_attr_data_structures 2025-07-31 14:19:27 +02:00
Jieyou Xu
69b71e4410
Mitigate #[align] name resolution ambiguity regression with a rename
From `#[align]` -> `#[rustc_align]`. Attributes starting with `rustc`
are always perma-unstable and feature-gated by `feature(rustc_attrs)`.

See regression RUST-143834.

For the underlying problem where even introducing new feature-gated
unstable built-in attributes can break user code such as

```rs
macro_rules! align {
    () => {
        /* .. */
    };
}

pub(crate) use align; // `use` here becomes ambiguous
```

refer to RUST-134963.

Since the `#[align]` attribute is still feature-gated by
`feature(fn_align)`, we can rename it as a mitigation. Note that
`#[rustc_align]` will obviously mean that current unstable user code
using `feature(fn_aling)` will need additionally `feature(rustc_attrs)`,
but this is a short-term mitigation to buy time, and is expected to be
changed to a better name with less collision potential.

See
<https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202025-07-17/near/529290371>
where mitigation options were considered.
2025-07-19 01:42:30 +08:00
Deadbeef
69326878ee parse const trait Trait 2025-07-17 18:06:26 +08:00
tiif
7356ff7517 Implement other logics 2025-07-15 13:48:30 +00:00
Deadbeef
6b02597ed3 update issue number for const_trait_impl 2025-07-13 23:55:06 +08:00
bors
1ce9c977ff Auto merge of #143214 - camsteffen:remove-let-chains-feature, r=est31
Remove let_chains unstable feature

Per https://github.com/rust-lang/rust/issues/53667#issuecomment-3016742982 (but then I also noticed rust-lang/rust#140722)

This replaces the feature gate with a parser error that says let chains require 2024.

A lot of tests were using the unstable feature. I either added edition:2024 to the test or split out the parts that require 2024.
2025-07-02 17:18:47 +00:00
bors
f51c9870ba Auto merge of #142974 - cuviper:stage0-bump, r=Mark-Simulacrum
Update stage0 to 1.89.0-beta.1

- Update version placeholders
- Update stage0 to 1.89.0-beta.1
- Update `STAGE0_MISSING_TARGETS`
- Update `cfg(bootstrap)`

r? `@Mark-Simulacrum`

try-job: dist-i586-gnu-i586-i686-musl
2025-07-02 01:41:18 +00:00
Michael Goulet
2516c33982 Remove support for dyn* 2025-07-01 19:00:21 +00:00
Josh Stone
9ce8930da6 Update version placeholders 2025-07-01 10:54:33 -07:00
Cameron Steffen
dc9879cb3d Remove let_chains feature 2025-06-30 07:49:20 -05:00
Tshepang Mbambo
bc00a633c6 fix typos on some doc comments 2025-06-28 13:13:59 +02:00
Matthias Krüger
36c2b011cb
Rollup merge of #139858 - oli-obk:new-const-traits-syntax, r=fee1-dead
New const traits syntax

This PR only affects the AST and doesn't actually change anything semantically.

All occurrences of `~const` outside of libcore have been replaced by `[const]`. Within libcore we have to wait for rustfmt to be bumped in the bootstrap compiler. This will happen "automatically" (when rustfmt is run) during the bootstrap bump, as rustfmt converts `~const` into `[const]`. After this we can remove the `~const` support from the parser

Caveat discovered during impl: there is no legacy bare trait object recovery for `[const] Trait` as that snippet in type position goes down the slice /array parsing code and will error

r? ``@fee1-dead``

cc ``@nikomatsakis`` ``@traviscross`` ``@compiler-errors``
2025-06-27 22:13:00 +02:00
Guillaume Gomez
80f20c98f3
Rollup merge of #142671 - davidtwco:no-default-bounds-attr, r=lcnr
add #![rustc_no_implicit_bounds]

Follow-up from rust-lang/rust#137944.

Adds a new `rustc_attrs` attribute that stops rustc from adding any default bounds. Useful for tests where default bounds just add noise and make debugging harder.

After reviewing all tests with `?Sized`, these tests seem like they could probably benefit from `#![rustc_no_implicit_bounds]`.

- Skipping most of `tests/ui/unsized` as these seem to want to test `?Sized`
- Skipping tests that used `Box<T>` because it's still bound by `T: MetaSized`
- Skipping parsing or other tests that cared about `?Sized` syntactically
- Skipping tests for `derive(CoercePointee)` because this appears to check that the pointee type is relaxed with `?Sized` explicitly

r? `@lcnr`
2025-06-27 15:04:52 +02:00
Oli Scherer
eb7245a864 Change const trait bound syntax from ~const to [const] 2025-06-26 13:46:45 +00:00
bors
bc4376fa73 Auto merge of #143026 - jdonszelmann:rollup-z7mkuyt, r=jdonszelmann
Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#142146 (Withdraw the claim `extern "C-cmse-nonsecure-*"` always matches `extern "C"`)
 - rust-lang/rust#142200 (`tests/ui`: A New Order [8/N])
 - rust-lang/rust#142724 (Add runtime check to avoid overwrite arg in `Diag`)
 - rust-lang/rust#142809 (Add PrintTAFn flag for targeted type analysis printing)
 - rust-lang/rust#142976 (Check CoerceUnsized impl validity before coercing)
 - rust-lang/rust#142992 (Convert some ABI tests to use `extern "rust-invalid"`)
 - rust-lang/rust#143000 (Make `Sub`, `Mul`, `Div` and `Rem`  `const_traits`)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-06-25 23:33:23 +00:00
Jana Dönszelmann
64a1a98f47
encode_cross_crate for hir attributes 2025-06-25 22:10:40 +02:00
Jubilee Young
383d76106b compiler: Trim the misleading C of C-cmse from errors 2025-06-25 00:52:10 -07:00
Jubilee Young
4bdf1c574a compiler: remove misleading 'c' from abi_c_cmse_nonsecure_call feature 2025-06-25 00:52:10 -07:00
Jubilee
f542909d1c
Rollup merge of #138780 - trifectatechfoundation:loop_match_attr, r=oli-obk,traviscross
Add `#[loop_match]` for improved DFA codegen

tracking issue: https://github.com/rust-lang/rust/issues/132306
project goal: https://github.com/rust-lang/rust-project-goals/issues/258

This PR adds the `#[loop_match]` attribute, which aims to improve code generation for state machines. For some (very exciting) benchmarks, see https://github.com/rust-lang/rust-project-goals/issues/258#issuecomment-2732965199

Currently, a very restricted syntax pattern is accepted. We'd like to get feedback and merge this now before we go too far in a direction that others have concerns with.

## current state

We accept code that looks like this

```rust
#[loop_match]
loop {
    state = 'blk: {
        match state {
            State::A => {
                #[const_continue]
                break 'blk State::B
            }
            State::B => { /* ... */ }
            /* ... */
        }
    }
}
```

- a loop should have the same semantics with and without `#[loop_match]`: normal `continue` and `break` continue to work
- `#[const_continue]` is only allowed in loops annotated with `#[loop_match]`
- the loop body needs to have this particular shape (a single assignment to the match scrutinee, with the body a labelled block containing just a match)

## future work

- perform const evaluation on the `break` value
- support more state/scrutinee types

## maybe future work

- allow `continue 'label value` syntax, which `#[const_continue]` could then use.
- allow the match to be on an arbitrary expression (e.g. `State::Initial`)
- attempt to also optimize `break`/`continue` expressions that are not marked with `#[const_continue]`

r? ``@traviscross``
2025-06-24 19:45:30 -07:00
Guillaume Gomez
0377330be4
Rollup merge of #142704 - tgross35:remove-concat_idents, r=fee1-dead
Remove the deprecated unstable `concat_idents!` macro

In [rust-lang/rust#137653], the lang and libs-API teams did a joint FCP to deprecate
and eventually remove the long-unstable `concat_idents!` macro. The
deprecation is landing in 1.88, so do the removal here (target version
1.90).

This macro has been superseded by the more recent `${concat(...)}`
metavariable expression language feature, which avoids some of the
limitations of `concat_idents!`. The metavar expression is unstably
available under the [`macro_metavar_expr_concat`] feature.

History is mildly interesting here: `concat_idents!` goes back to 2011
when it was introduced with 513276e595f8 ("Add #concat_idents[] and
#ident_to_str[]"). The syntax looks a bit different but it still works
about the same:

    let asdf_fdsa = "<.<";
    assert(#concat_idents[asd,f_f,dsa] == "<.<");

    assert(#ident_to_str[use_mention_distinction]
           == "use_mention_distinction");

(That test existed from introduction until its removal here.)

Closes: https://github.com/rust-lang/rust/issues/29599

[rust-lang/rust#137653]: https://github.com/rust-lang/rust/pull/137653
[`macro_metavar_expr_concat`]: https://github.com/rust-lang/rust/issues/124225
2025-06-24 15:39:38 +02:00
Trevor Gross
0e4de4ceb0 Remove the deprecated concat_idents! macro
In [137653], the lang and libs-API teams did a joint FCP to deprecate
and eventually remove the long-unstable `concat_idents!` macro. The
deprecation is landing in 1.88, so do the removal here (target version
1.90).

This macro has been superseded by the more recent `${concat(...)}`
metavariable expression language feature, which avoids some of the
limitations of `concat_idents!`. The metavar expression is unstably
available under the [`macro_metavar_expr_concat`] feature.

History is mildly interesting here: `concat_idents!` goes back to 2011
when it was introduced with 513276e595f8 ("Add #concat_idents[] and
about the same:

    let asdf_fdsa = "<.<";
    assert(#concat_idents[asd,f_f,dsa] == "<.<");

    assert(#ident_to_str[use_mention_distinction]
           == "use_mention_distinction");

(That test existed from introduction until its removal here.)

Closes: https://www.github.com/rust-lang/rust/issues/29599

[137653]: https://www.github.com/rust-lang/rust/pull/137653
[`macro_metavar_expr_concat`]: https://www.github.com/rust-lang/rust/issues/124225
2025-06-24 11:07:16 +00:00
Pavel Grigorenko
aa80a2b62c Port #[rustc_skip_during_method_dispatch] to the new attribute system 2025-06-23 22:48:20 +03:00
bjorn3
ba5556d239
Add #[loop_match] for improved DFA codegen
Co-authored-by: Folkert de Vries <folkert@folkertdev.nl>
2025-06-23 20:43:04 +02:00