Unverified Commit 1edaa7e6 authored by Landon James's avatar Landon James Committed by GitHub
Browse files

Add decorator and setting to set `hints.mostly-unused` (#4243)

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here -->
Continuing the work started in
https://github.com/smithy-lang/smithy-rs/pull/4208, the new feature we
are utilizing is explained in
https://blog.rust-lang.org/inside-rust/2025/07/15/call-for-testing-hint-mostly-unused

## Description
<!--- Describe your changes in detail -->
Add a new `ManifestHintsDecorator` that allows adding a `[hints]`
section to a generated `Cargo.toml`. This also introduces a new optional
entry in `smithy-build.json`, `hintsMostlyUnusedList` that allows
indicating which crates this should be enabled for. Currently this is
only enabled for `aws-sdk-s3`, `aws-sdk-dynamodb`, and `aws-sdk-ec2`.

## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
I tested both debug and release builds of the crates, with and without
the hint on an M1 Macbook Pro. You can see the full data below, but the
general outcome is that release builds are ~50% faster with the hint and
debug builds are ~40% faster. A release build of the `aws-sdk-ec2` crate
went from `124.1s` without the hint to `59.1s` with it.


<details><summary>Expand To See Test Data</summary>
<p>
All tests run after deleting the `target/` dir

## Debug No Hint
`cargo build --timings`
```
||Unit|Total|Codegen|Features|
|---|---|---|---|---|
|1.|aws-sdk-ec2 v0.0.0-local|104.8s|27.9s (27%)|default, default-https-client, rt-tokio, rustls|
|2.|aws-lc-sys v0.30.0 build script (run)|26.1s||prebuilt-nasm|
|3.|aws-sdk-s3 v0.0.0-local|21.2s|5.2s (24%)|default, default-https-client, rt-tokio, rustls, sigv4a|
|4.|aws-sdk-dynamodb v0.0.0-local|13.7s|4.0s (29%)|default, default-https-client, rt-tokio, rustls|
```

| Unit             | Total  | Codegen     |
| ---------------- | ------ | ----------- |
| aws-sdk-ec2      | 104.8s | 27.9s (27%) |
| aws-sdk-s3       | 21.2s  | 5.2s (24%)  |
| aws-sdk-dynamodb | 13.7s  | 4.0s (29%)  |

## Debug Hint
`cargo +nightly -Zprofile-hint-mostly-unused build --timings`

```
||Unit|Total|Codegen|Features|
|---|---|---|---|---|
|1.|aws-sdk-ec2 v0.0.0-local|66.4s|2.4s (4%)|default, default-https-client, rt-tokio, rustls|
|2.|aws-lc-sys v0.30.0 build script (run)|25.0s||prebuilt-nasm|
|3.|aws-sdk-s3 v0.0.0-local|14.6s|0.8s (5%)|default, default-https-client, rt-tokio, rustls, sigv4a|
|4.|aws-sdk-dynamodb v0.0.0-local|9.1s|0.4s (4%)|default, default-https-client, rt-tokio, rustls|
```

| Unit             | Total | Codegen   |
| ---------------- | ----- | --------- |
| aws-sdk-ec2      | 66.4s | 2.4s (4%) |
| aws-sdk-s3       | 14.6s | 0.8s (5%) |
| aws-sdk-dynamodb | 9.1s  | 0.4s (4%) |


## Release No Hint
`cargo build --timings --release `

```
||Unit|Total|Codegen|Features|
|---|---|---|---|---|
|1.|aws-sdk-ec2 v0.0.0-local|124.1s|54.3s (44%)|default, default-https-client, rt-tokio, rustls|
|2.|aws-lc-sys v0.30.0 build script (run)|34.3s||prebuilt-nasm|
|3.|aws-sdk-s3 v0.0.0-local|28.5s|11.4s (40%)|default, default-https-client, rt-tokio, rustls, sigv4a|
|4.|aws-sdk-dynamodb v0.0.0-local|19.3s|8.5s (44%)|default, default-https-client, rt-tokio, rustls|
```

| Unit             | Total  | Codegen     |
| ---------------- | ------ | ----------- |
| aws-sdk-ec2      | 124.1s | 54.3s (44%) |
| aws-sdk-s3       | 28.5s  | 11.4s (40%) |
| aws-sdk-dynamodb | 19.3s  | 8.5s (44%)  |


## Release Hint
`cargo +nightly -Zprofile-hint-mostly-unused build --timings --release`

```
||Unit|Total|Codegen|Features|
|---|---|---|---|---|
|1.|aws-sdk-ec2 v0.0.0-local|59.1s|1.0s (2%)|default, default-https-client, rt-tokio, rustls|
|2.|aws-lc-sys v0.30.0 build script (run)|34.4s||prebuilt-nasm|
|3.|aws-sdk-s3 v0.0.0-local|14.7s|0.4s (3%)|default, default-https-client, rt-tokio, rustls, sigv4a|
|4.|tokio v1.47.1|11.1s|7.3s (65%)|bytes, default, fs, full, io-std, io-util, libc, macros, mio, net, parking_lot, process, rt, rt-multi-thread, signal, signal-hook-registry, socket2, sync, time, tokio-macros|
|5.|aws-sdk-dynamodb v0.0.0-local|10.4s|0.4s (4%)|default, default-https-client, rt-tokio, rustls|
```

| Unit             | Total | Codegen   |
| ---------------- | ----- | --------- |
| aws-sdk-ec2      | 59.1s | 1.0s (2%) |
| aws-sdk-s3       | 14.7s | 0.4s (3%) |
| aws-sdk-dynamodb | 10.4s | 0.4s (4%) |

</p>
</details> 

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] For changes to the smithy-rs codegen or runtime crates, I have
created a changelog entry Markdown file in the `.changelog` directory,
specifying "client," "server," or both in the `applies_to` key.
- [x] For changes to the AWS SDK, generated SDK code, or SDK runtime
crates, I have created a changelog entry Markdown file in the
`.changelog` directory, specifying "aws-sdk-rust" in the `applies_to`
key.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent 91185d29
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
---
applies_to:
  - aws-sdk-rust
  - client
authors:
  - landonxjames
references:
  - smithy-rs#4208
breaking: false
new_feature: true
bug_fix: false
---
Add the ability to insert `hints.mostly-unused = true` in Cargo.toml. Enable this hint for the below crates:
- aws-sd-cloudformation
- aws-sdk-dynamodb
- aws-sdk-ec2
- aws-sdk-s3
- aws-sdk-sns
- aws-sdk-sqs
- aws-sdk-ssm
- aws-sdk-sts

See more information about this hint at https://blog.rust-lang.org/inside-rust/2025/07/15/call-for-testing-hint-mostly-unused/
+15 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@ package software.amazon.smithy.rustsdk

import software.amazon.smithy.rust.codegen.client.smithy.customizations.DocsRsMetadataDecorator
import software.amazon.smithy.rust.codegen.client.smithy.customizations.DocsRsMetadataSettings
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ManifestHintsDecorator
import software.amazon.smithy.rust.codegen.client.smithy.customizations.ManifestHintsSettings
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.customize.CombinedClientCodegenDecorator
import software.amazon.smithy.rustsdk.customize.AwsDisableStalledStreamProtection
@@ -22,6 +24,7 @@ import software.amazon.smithy.rustsdk.customize.dsql.DsqlDecorator
import software.amazon.smithy.rustsdk.customize.ec2.Ec2Decorator
import software.amazon.smithy.rustsdk.customize.glacier.GlacierDecorator
import software.amazon.smithy.rustsdk.customize.onlyApplyTo
import software.amazon.smithy.rustsdk.customize.onlyApplyToList
import software.amazon.smithy.rustsdk.customize.rds.RdsDecorator
import software.amazon.smithy.rustsdk.customize.route53.Route53Decorator
import software.amazon.smithy.rustsdk.customize.s3.S3Decorator
@@ -109,6 +112,18 @@ val DECORATORS: List<ClientCodegenDecorator> =
                ),
            ),
        ),
        ManifestHintsDecorator(ManifestHintsSettings(mostlyUnused = true)).onlyApplyToList(
            listOf(
                "com.amazonaws.cloudformation#CloudFormation",
                "com.amazonaws.dynamodb#DynamoDB_20120810",
                "com.amazonaws.ec2#AmazonEC2",
                "com.amazonaws.s3#AmazonS3",
                "com.amazonaws.sns#AmazonSimpleNotificationService",
                "com.amazonaws.sqs#AmazonSQS",
                "com.amazonaws.ssm#AmazonSSM",
                "com.amazonaws.sts#AWSSecurityTokenServiceV20110615",
            ),
        ),
    ).flatten()

class AwsCodegenDecorator : CombinedClientCodegenDecorator(DECORATORS) {
+8 −0
Original line number Diff line number Diff line
@@ -17,6 +17,14 @@ fun ClientCodegenDecorator.onlyApplyTo(serviceId: String): List<ClientCodegenDec
        },
    )

/** Only apply this decorator to the given list of service IDs */
fun ClientCodegenDecorator.onlyApplyToList(serviceIds: List<String>): List<ClientCodegenDecorator> =
    serviceIds.map {
        ConditionalDecorator(this) { _, serviceShapeId ->
            serviceShapeId == ShapeId.from(it)
        }
    }

/** Apply this decorator to all services but the one identified by ID */
fun ClientCodegenDecorator.applyExceptFor(serviceId: String): List<ClientCodegenDecorator> =
    listOf(
+2 −2
Original line number Diff line number Diff line
@@ -494,7 +494,7 @@ fun Project.registerDowngradeFor(
            val crateNameToLastKnownWorkingVersions =
                mapOf(
                    "minicbor" to "0.24.2",
                    "libfuzzer-sys" to "0.4.7" // TODO(https://github.com/rust-fuzz/libfuzzer/issues/126)
                    "libfuzzer-sys" to "0.4.7", // TODO(https://github.com/rust-fuzz/libfuzzer/issues/126)
                )

            crateNameToLastKnownWorkingVersions.forEach { (crate, version) ->
+9 −1
Original line number Diff line number Diff line
@@ -2,5 +2,13 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
#

aws.services=
aws.services.hints.mostlyUnused=\
  aws-sd-cloudformation,\
  aws-sdk-dynamodb,\
  aws-sdk-ec2,\
  aws-sdk-s3,\
  aws-sdk-sns,\
  aws-sdk-sqs,\
  aws-sdk-ssm,\
  aws-sdk-sts
Loading