Skip to content

Commit d4ea6f5

Browse files
[Blog] First Rust Patch
Also - update `#[\Deprecated]` on traits RFC status to implemented - bump pygments highlighting extension to v0.2.0 for DanielEScherzer/commonmark-ext-pygments-highlighter#1 - add missing `--no-coverage` flag to `phpunit:update-expected` composer script
1 parent be10fa5 commit d4ea6f5

7 files changed

Lines changed: 78 additions & 9 deletions

File tree

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"require": {
3-
"danielescherzer/commonmark-ext-pygments-highlighter": "0.1.0",
3+
"danielescherzer/commonmark-ext-pygments-highlighter": "0.2.0",
44
"danielescherzer/html-builder": "0.0.2",
55
"nikic/fast-route": "1.3.0",
66
"league/commonmark": "2.7.0",
@@ -28,7 +28,7 @@
2828
"parallel-lint": "parallel-lint . --exclude vendor",
2929
"phpcs": "phpcs -p -s",
3030
"phpunit": "php -d extension=pcov.so -d pcov.enabled=1 -d pcov.directory=. vendor/bin/phpunit",
31-
"phpunit:update-expected": "TESTS_UPDATE_EXPECTED=1 php vendor/bin/phpunit",
31+
"phpunit:update-expected": "TESTS_UPDATE_EXPECTED=1 php vendor/bin/phpunit --no-coverage",
3232
"lint": [
3333
"@parallel-lint",
3434
"@phpcs"

sitemap.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,7 @@
4545
<url>
4646
<loc>https://scherzer.dev/Blog/20250829-out-of-band</loc>
4747
</url>
48+
<url>
49+
<loc>https://scherzer.dev/Blog/20250906-mago-rust</loc>
50+
</url>
4851
</urlset>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: "First Rust Patch"
3+
extensions:
4+
pygments: true
5+
---
6+
7+
# First Rust Patch
8+
9+
As part of preparing for my Longhorn PHP talk about what is new in PHP 8.5, I
10+
have been going through various PHP tools and checking to what extent they
11+
support the new features. When the support is lacking, I have sometimes tried to
12+
add it myself; this led me to making my first patch in Rust.
13+
14+
Most of the common tools for analyzing PHP code (e.g. PHPStan and PHP
15+
Codesniffer) are written in PHP. However, I recently came across a new tool
16+
currently in development, [`mago`][mago], that is written in Rust. I have
17+
approximately zero experience with Rust - I've seen some Rust code before, but I
18+
don't recall having written any myself. Until now.
19+
20+
My last RFC for PHP 8.5 was
21+
[adding support for `#[\Deprecated]` on traits][rfc]. After I merged the
22+
implementation yesterday, I started working on patches for the various tools to
23+
add support for the new feature. I hadn't contributed to mago before, but I saw
24+
that mago already had support for reporting a trait as deprecated when it had a
25+
`@deprecated` comment, so I figured that it would be pretty simple to try and
26+
add warnings when the attribute is found.
27+
28+
The logic to warn about using deprecated traits was already there. And, I was
29+
able to look at an [existing case][nodiscard-code] (processing of the
30+
`#[\NoDiscard]` attribute) to figure out how to examine attributes. The entirety
31+
of [my Rust code][mago-patch] was the addition of:
32+
33+
```rust
34+
if class_like_metadata.attributes.iter().any(|attr| attr.name.eq_ignore_ascii_case("Deprecated")) {
35+
class_like_metadata.flags |= MetadataFlags::DEPRECATED;
36+
}
37+
```
38+
39+
to the `scan_class_like` function in the `codex` crate.
40+
41+
I like learning, and I especially like learning new programming languages. Rust
42+
has been on my list for a while now, and this experience showed me that it has
43+
some features that PHP lacks. For example, the condition above, if implemented
44+
in PHP, would look something like
45+
46+
```php startinline=True
47+
if (array_any($class_like_metadata->attributes, static fn ($attr) => strtolower($attr->name) === 'deprecated')) {
48+
$class_like_metadata->flags |= MetadataFlags::DEPRECATED;
49+
}
50+
```
51+
52+
PHP does not support methods on primitives types, and requires more boilerplate
53+
for its inline anonymous functions. (The ["scalar_objects"][scalar-objects]
54+
extension adds support for methods on primitive types, but has a disclaimer that
55+
it is intended to be just a proof of concept.) I can definitely see the appeal
56+
of Rust, even if I don't fully understand the code that I wrote. I probably
57+
shouldn't have skipped past the "Hello, World!" step.
58+
59+
[mago]: https://github.com/carthage-software/mago
60+
[rfc]: https://wiki.php.net/rfc/deprecated_traits
61+
[nodiscard-code]: https://github.com/carthage-software/mago/blob/dbe604b045af4ffeb3dfc722f1842eb23006aefc/crates/analyzer/src/statement/mod.rs#L336
62+
[mago-patch]: https://github.com/carthage-software/mago/pull/386
63+
[scalar-objects]: https://github.com/nikic/scalar_objects

src/Pages/OpenSourcePage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class OpenSourcePage extends BasePage {
4343
'link' => 'https://wiki.php.net/rfc/deprecated_traits',
4444
'date' => 'July 2025',
4545
'desc' => 'Support the #[\Deprecated] attribute on traits',
46-
'status' => 'pending implementation',
46+
'status' => 'implemented in PHP 8.5',
4747
],
4848
];
4949

tests/data/Home.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
work in Computer Science, I chose to write an honors thesis in my senior year,
66
see <a href="./Thesis">here</a> for details.</p><p>I am currently pursuing a Master of Science in Computer Science, also through
77
Tufts. I will be graduating in August of 2025.</p><p>See the links in the navigation bar above for more information about my
8-
experience.</p><h2 class="subsection-header">Contact</h2><ul><li><a href="https://www.linkedin.com/in/daniel-scherzer-520539263/" target="_blank" class="external-link">LinkedIn</a></li><li>Email: <code>daniel.e.scherzer@gmail.com</code></li></ul><h2 class="subsection-header">Blog</h2><p>I also have a blog. You can see a full index of my posts <a href="/Blog">here</a>. My latest blog post is: </p><div class="blog-preview"><h3>Out-of-Band Signaling</h3><span class="blog-preview-date">Friday, 29 August 2025</span><p>Sometimes, code needs to be able to signal an error has occurred. Perhaps some
9-
invariant was violated. Perhaps an invalid parameter was used. Regardless of the
10-
reason, there are two ways to signal an issue: &quot;in-band signaling&quot;, and
11-
&quot;out-of-band signaling&quot;. <a href="/Blog/20250829-out-of-band">Continue reading...</a></p></div></div><div class="des-footer"><div class="des-footer--content">Content is © 2025 Daniel Scherzer</div></div></body></html>
8+
experience.</p><h2 class="subsection-header">Contact</h2><ul><li><a href="https://www.linkedin.com/in/daniel-scherzer-520539263/" target="_blank" class="external-link">LinkedIn</a></li><li>Email: <code>daniel.e.scherzer@gmail.com</code></li></ul><h2 class="subsection-header">Blog</h2><p>I also have a blog. You can see a full index of my posts <a href="/Blog">here</a>. My latest blog post is: </p><div class="blog-preview"><h3>First Rust Patch</h3><span class="blog-preview-date">Saturday, 06 September 2025</span><p>As part of preparing for my Longhorn PHP talk about what is new in PHP 8.5, I
9+
have been going through various PHP tools and checking to what extent they
10+
support the new features. When the support is lacking, I have sometimes tried to
11+
add it myself; this led me to making my first patch in Rust. <a href="/Blog/20250906-mago-rust">Continue reading...</a></p></div></div><div class="des-footer"><div class="des-footer--content">Content is © 2025 Daniel Scherzer</div></div></body></html>

tests/data/OpenSource.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
decide between the volunteers (luckily there were plenty of candidates) and I
88
was one of the two &quot;rookie&quot; candidates chosen to help with the release. You can
99
read more in <a href="/Blog/20250417-php85-release-manager">my blog post</a>.</p><p>PHP uses a process of requests for comment when proposing and implementing major
10-
changes; my RFCs include:</p><ul><li>July 2025: <a href="https://wiki.php.net/rfc/deprecated_traits" target="_blank" class="external-link">#[\Deprecated] for traits</a> - Support the #[\Deprecated] attribute on traits (pending implementation)</li><li>July 2025: <a href="https://wiki.php.net/rfc/filter_throw_on_failure" target="_blank" class="external-link">FILTER_THROW_ON_FAILURE</a> - Add FILTER_THROW_ON_FAILURE flag to the filter extension (implemented in PHP 8.5)</li><li>June 2025: <a href="https://wiki.php.net/rfc/delayedtargetvalidation_attribute" target="_blank" class="external-link">#[\DelayedTargetValidation] attribute</a> - Delaying compile-time attribute target validation errors with #[\DelayedTargetValidation] (implemented in PHP 8.5)</li><li>March 2025: <a href="https://wiki.php.net/rfc/final_promotion" target="_blank" class="external-link">Final Property Promotion</a> - Adding support for final modifiers in constructor property promotion (implemented in PHP 8.5)</li><li>November 2024: <a href="https://wiki.php.net/rfc/attributes-on-constants" target="_blank" class="external-link">Attributes on Constants</a> - Adding support for attributes on compile-time constants (implemented in PHP 8.5)</li></ul><h3 class="subsection-header">Packages</h3><p>I also wrote multiple open-source PHP packages - though they are currently
10+
changes; my RFCs include:</p><ul><li>July 2025: <a href="https://wiki.php.net/rfc/deprecated_traits" target="_blank" class="external-link">#[\Deprecated] for traits</a> - Support the #[\Deprecated] attribute on traits (implemented in PHP 8.5)</li><li>July 2025: <a href="https://wiki.php.net/rfc/filter_throw_on_failure" target="_blank" class="external-link">FILTER_THROW_ON_FAILURE</a> - Add FILTER_THROW_ON_FAILURE flag to the filter extension (implemented in PHP 8.5)</li><li>June 2025: <a href="https://wiki.php.net/rfc/delayedtargetvalidation_attribute" target="_blank" class="external-link">#[\DelayedTargetValidation] attribute</a> - Delaying compile-time attribute target validation errors with #[\DelayedTargetValidation] (implemented in PHP 8.5)</li><li>March 2025: <a href="https://wiki.php.net/rfc/final_promotion" target="_blank" class="external-link">Final Property Promotion</a> - Adding support for final modifiers in constructor property promotion (implemented in PHP 8.5)</li><li>November 2024: <a href="https://wiki.php.net/rfc/attributes-on-constants" target="_blank" class="external-link">Attributes on Constants</a> - Adding support for attributes on compile-time constants (implemented in PHP 8.5)</li></ul><h3 class="subsection-header">Packages</h3><p>I also wrote multiple open-source PHP packages - though they are currently
1111
primarily used by me, I am a firm supporter of open-source code and figured that
1212
they might be useful to others. The packages that I have created so far are:</p><ul><li><a href="https://packagist.org/packages/danielescherzer/common-phpcs" target="_blank" class="external-link">danielescherzer/common-phpcs</a> - Collection of common codesniffer standards for my projects</li><li><a href="https://packagist.org/packages/danielescherzer/commonmark-ext-pygments-highlighter" target="_blank" class="external-link">danielescherzer/commonmark-ext-pygments-highlighter</a> - CommonMark extension for code highlighting with Pygments</li><li><a href="https://packagist.org/packages/danielescherzer/html-builder" target="_blank" class="external-link">danielescherzer/html-builder</a> - Tools for building HTML</li></ul><h3 class="subsection-header">Website</h3><p>The source code for my website is also public, in case the code is useful to
1313
others. The actual text about me is probably not going to be relevant, but my

tests/data/blog-index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<!DOCTYPE html>
2-
<html><head><link rel="icon" href="data:,"><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"><link rel="stylesheet" type="text/css" href="/resources/default-styles.css"><title>Blog index</title><link rel="stylesheet" type="text/css" href="/resources/blog-styles.css"></head><body><div class="des-navbar"><a href="/Home">Home</a><a href="/files/Resume.pdf">Résumé</a><a href="/OpenSource">Open Source</a><a href="/Work">Work</a><strong class="des-strong-page-link">Blog</strong></div><div class="content-wrapper"><h1>Blog index</h1><div class="blog-preview"><h2>Out-of-Band Signaling</h2><span class="blog-preview-date">Friday, 29 August 2025</span><p>Sometimes, code needs to be able to signal an error has occurred. Perhaps some
2+
<html><head><link rel="icon" href="data:,"><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"><link rel="stylesheet" type="text/css" href="/resources/default-styles.css"><title>Blog index</title><link rel="stylesheet" type="text/css" href="/resources/blog-styles.css"></head><body><div class="des-navbar"><a href="/Home">Home</a><a href="/files/Resume.pdf">Résumé</a><a href="/OpenSource">Open Source</a><a href="/Work">Work</a><strong class="des-strong-page-link">Blog</strong></div><div class="content-wrapper"><h1>Blog index</h1><div class="blog-preview"><h2>First Rust Patch</h2><span class="blog-preview-date">Saturday, 06 September 2025</span><p>As part of preparing for my Longhorn PHP talk about what is new in PHP 8.5, I
3+
have been going through various PHP tools and checking to what extent they
4+
support the new features. When the support is lacking, I have sometimes tried to
5+
add it myself; this led me to making my first patch in Rust. <a href="/Blog/20250906-mago-rust">Continue reading...</a></p></div><div class="blog-preview"><h2>Out-of-Band Signaling</h2><span class="blog-preview-date">Friday, 29 August 2025</span><p>Sometimes, code needs to be able to signal an error has occurred. Perhaps some
36
invariant was violated. Perhaps an invalid parameter was used. Regardless of the
47
reason, there are two ways to signal an issue: &quot;in-band signaling&quot;, and
58
&quot;out-of-band signaling&quot;. <a href="/Blog/20250829-out-of-band">Continue reading...</a></p></div><div class="blog-preview"><h2>#[\DelayedTargetValidation] Attribute Explained</h2><span class="blog-preview-date">Wednesday, 20 August 2025</span><p>PHP 8.5 will come with a new attribute, <code>#[\DelayedTargetValidation]</code>, that

0 commit comments

Comments
 (0)