Skip to content
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

Bump Rust MSRV to 1.63.0 #2222

Merged
merged 12 commits into from
Feb 10, 2023
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ on:
required: false

env:
rust_version: 1.62.1
rust_version: 1.63.0
rust_toolchain_components: clippy,rustfmt
ENCRYPTED_DOCKER_PASSWORD: ${{ secrets.ENCRYPTED_DOCKER_PASSWORD }}
DOCKER_LOGIN_TOKEN_PASSPHRASE: ${{ secrets.DOCKER_LOGIN_TOKEN_PASSPHRASE }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/claim-crate-names.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ concurrency:
cancel-in-progress: true

env:
rust_version: 1.62.1
rust_version: 1.63.0

name: Claim unpublished crate names on crates.io
run-name: ${{ github.workflow }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pull-request-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ concurrency:

env:
java_version: 11
rust_version: 1.62.1
rust_version: 1.63.0
rust_toolchain_components: clippy,rustfmt
apt_dependencies: libssl-dev gnuplot jq

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ concurrency:
cancel-in-progress: true

env:
rust_version: 1.62.1
rust_version: 1.63.0

name: Release smithy-rs
run-name: ${{ github.workflow }} ${{ inputs.semantic_version }} (${{ inputs.commit_sha }}) - ${{ inputs.dry_run && 'Dry run' || 'Production run' }}
on:
workflow_dispatch:
inputs:
commit_sha:
description: |
The SHA of the git commit that you want to release.
description: |
The SHA of the git commit that you want to release.
You must use the non-abbreviated SHA (e.g. b2318b0 won't work!).
required: true
type: string
Expand Down Expand Up @@ -75,8 +75,8 @@ jobs:
# We need `always` here otherwise this job won't run if the previous job has been skipped
# See https://samanpavel.medium.com/github-actions-conditional-job-execution-e6aa363d2867
if: |
always() &&
needs.acquire-base-image.result == 'success' &&
always() &&
needs.acquire-base-image.result == 'success' &&
(needs.release-ci.result == 'success' || needs.release-ci.result == 'skipped')
runs-on: ubuntu-latest
outputs:
Expand Down Expand Up @@ -234,7 +234,7 @@ jobs:
shell: bash
run: |
set -eux

# This will fail if other commits have been pushed to `main` after `commit_sha`
# In particular, this will ALWAYS fail if you are creating a new release series from
# a commit that is not the current tip of `main`.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-sdk-next.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Set up Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.62.1
toolchain: 1.63.0
- name: Delete old SDK
run: |
- name: Generate a fresh SDK
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,15 @@
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
# author = "rcoh"

[[aws-sdk-rust]]
message = "Upgrade Rust MSRV to 1.63.0"
references = ["smithy-rs#2222"]
meta = { "breaking" = true, "tada" = true, "bug" = false }
author = "Nugine"

[[smithy-rs]]
message = "Upgrade Rust MSRV to 1.63.0"
references = ["smithy-rs#2222"]
meta = { "breaking" = true, "tada" = true, "bug" = false, "target" = "all" }
author = "Nugine"
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-config/src/imds/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ pub(crate) mod test {
imds_request("http://169.254.169.254/latest/metadata", TOKEN_A),
http::Response::builder()
.status(200)
.body(SdkBody::from(vec![0xA0 as u8, 0xA1 as u8]))
.body(SdkBody::from(vec![0xA0, 0xA1]))
.unwrap(),
),
]);
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

#![allow(clippy::derive_partial_eq_without_eq)]
#![warn(
missing_debug_implementations,
missing_docs,
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-credential-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! * An opaque struct representing credentials
//! * Concrete implementations of credentials caching

#![allow(clippy::derive_partial_eq_without_eq)]
#![warn(
missing_debug_implementations,
missing_docs,
Expand Down
4 changes: 3 additions & 1 deletion aws/rust-runtime/aws-endpoint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

#![allow(clippy::derive_partial_eq_without_eq)]

use std::collections::HashMap;
use std::error::Error;
use std::fmt;
Expand Down Expand Up @@ -270,7 +272,7 @@ mod test {
let mut req = operation::Request::new(req);
{
let mut props = req.properties_mut();
props.insert(region.clone());
props.insert(region);
props.insert(SigningService::from_static("qldb"));
props.insert(endpoint);
};
Expand Down
5 changes: 1 addition & 4 deletions aws/rust-runtime/aws-http/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,7 @@ mod tests {
.create_cache(SharedCredentialsProvider::new(provide_credentials_fn(
|| async { Ok(Credentials::for_tests()) },
)));
set_credentials_cache(
&mut req.properties_mut(),
SharedCredentialsCache::from(credentials_cache),
);
set_credentials_cache(&mut req.properties_mut(), credentials_cache);
let req = CredentialsStage::new()
.apply(req)
.await
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

//! Provides user agent and credentials middleware for the AWS SDK.

#![allow(clippy::derive_partial_eq_without_eq)]
#![warn(
missing_docs,
rustdoc::missing_crate_level_docs,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ mod tests {

for i in 0..10000 {
let line = format!("This is a large file created for testing purposes {}", i);
file.as_file_mut().write(line.as_bytes()).unwrap();
file.as_file_mut().write_all(line.as_bytes()).unwrap();
crc32c_checksum.update(line.as_bytes());
}

Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-inlineable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//! This is _NOT_ intended to be an actual crate. It is a cargo project to solely to aid
//! with local development of the SDK.

#![allow(clippy::derive_partial_eq_without_eq)]
#![warn(
missing_docs,
rustdoc::missing_crate_level_docs,
Expand Down
2 changes: 2 additions & 0 deletions aws/rust-runtime/aws-sig-auth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

#![allow(clippy::derive_partial_eq_without_eq)]

//! AWS Signature Authentication Package
//!
//! This crate may be used to generate presigned URLs for unmodeled behavior such as `rds-iam-token`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ mod test {
let mut query_writer = QueryWriter::new(&uri);
query_writer.insert("key", value);

if let Err(_) = std::panic::catch_unwind(|| query_writer.build_uri()) {
if std::panic::catch_unwind(|| query_writer.build_uri()).is_err() {
problematic_chars.push(char::from(byte));
};
}
Expand Down
8 changes: 5 additions & 3 deletions aws/rust-runtime/aws-sigv4/src/http_request/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,11 @@ mod tests {

#[test]
fn test_sign_vanilla_with_query_params() {
let mut settings = SigningSettings::default();
settings.signature_location = SignatureLocation::QueryParams;
settings.expires_in = Some(Duration::from_secs(35));
let settings = SigningSettings {
signature_location: SignatureLocation::QueryParams,
expires_in: Some(Duration::from_secs(35)),
..Default::default()
};
let params = SigningParams {
access_key: "AKIDEXAMPLE",
secret_key: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-sigv4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! Provides functions for calculating Sigv4 signing keys, signatures, and
//! optional utilities for signing HTTP requests and Event Stream messages.

#![allow(clippy::derive_partial_eq_without_eq)]
#![warn(
missing_docs,
rustdoc::missing_crate_level_docs,
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

//! Cross-service types for the AWS SDK.

#![allow(clippy::derive_partial_eq_without_eq)]
#![warn(
missing_docs,
rustdoc::missing_crate_level_docs,
Expand Down
2 changes: 1 addition & 1 deletion aws/sdk/integration-tests/s3/tests/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn test_client(update_builder: fn(Builder) -> Builder) -> (CaptureRequestReceive
let sdk_config = SdkConfig::builder()
.credentials_provider(SharedCredentialsProvider::new(Credentials::for_tests()))
.region(Region::new("us-west-4"))
.http_connector(conn.clone())
.http_connector(conn)
.build();
let client = Client::from_conf(update_builder(Builder::from(&sdk_config)).build());
(captured_request, client)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ class ExpressionGenerator(
getAttr.path.toList().forEach { part ->
when (part) {
is GetAttr.Part.Key -> rust(".${part.key().rustName()}()")
is GetAttr.Part.Index -> rust(".get(${part.index()}).cloned()") // we end up with Option<&&T>, we need to get to Option<&T>
is GetAttr.Part.Index -> {
if (part.index() == 0) {
// In this case, `.first()` is more idiomatic and `.get(0)` triggers lint warnings
rust(".first().cloned()")
} else {
rust(".get(${part.index()}).cloned()") // we end up with Option<&&T>, we need to get to Option<&T>
}
}
}
}
if (ownership == Ownership.Owned && getAttr.type() != Type.bool()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ class ProtocolTestGenerator(
checkQueryParams(this, httpRequestTestCase.queryParams)
checkForbidQueryParams(this, httpRequestTestCase.forbidQueryParams)
checkRequiredQueryParams(this, httpRequestTestCase.requireQueryParams)
checkHeaders(this, "&http_request.headers()", httpRequestTestCase.headers)
checkForbidHeaders(this, "&http_request.headers()", httpRequestTestCase.forbidHeaders)
checkRequiredHeaders(this, "&http_request.headers()", httpRequestTestCase.requireHeaders)
checkHeaders(this, "http_request.headers()", httpRequestTestCase.headers)
checkForbidHeaders(this, "http_request.headers()", httpRequestTestCase.forbidHeaders)
checkRequiredHeaders(this, "http_request.headers()", httpRequestTestCase.requireHeaders)
if (protocolSupport.requestBodySerialization) {
// "If no request body is defined, then no assertions are made about the body of the message."
httpRequestTestCase.body.orNull()?.also { body ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,16 @@ fun RustType.isCopy(): Boolean = when (this) {
else -> false
}

/** Returns true if the type implements Eq */
fun RustType.isEq(): Boolean = when (this) {
is RustType.Integer -> true
is RustType.Bool -> true
is RustType.String -> true
is RustType.Unit -> true
is RustType.Container -> this.member.isEq()
else -> false
}

enum class Visibility {
PRIVATE, PUBCRATE, PUBLIC;

Expand Down Expand Up @@ -546,3 +556,10 @@ class Attribute(val inner: Writable) {
}
}
}

/** Render all attributes in this list, one after another */
fun Collection<Attribute>.render(writer: RustWriter) {
for (attr in this) {
attr.render(writer)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fun containerDefaultMetadata(
model: Model,
additionalAttributes: List<Attribute> = emptyList(),
): RustMetadata {
val defaultDerives = setOf(RuntimeType.Debug, RuntimeType.PartialEq, RuntimeType.Clone)
val derives = mutableSetOf(RuntimeType.Debug, RuntimeType.PartialEq, RuntimeType.Clone)

val isSensitive = shape.hasTrait<SensitiveTrait>() ||
// Checking the shape's direct members for the sensitive trait should suffice.
Expand All @@ -101,22 +101,17 @@ fun containerDefaultMetadata(
// shape; any sensitive descendant should still be printed as redacted.
shape.members().any { it.getMemberTrait(model, SensitiveTrait::class.java).isPresent }

val setOfDerives = if (isSensitive) {
defaultDerives - RuntimeType.Debug
} else {
defaultDerives
if (isSensitive) {
derives.remove(RuntimeType.Debug)
}
return RustMetadata(
setOfDerives,
additionalAttributes,
Visibility.PUBLIC,
)

return RustMetadata(derives, additionalAttributes, Visibility.PUBLIC)
}

/**
* The base metadata supports a set of attributes that are used by generators to decorate code.
*
* By default we apply `#[non_exhaustive]` in [additionalAttributes] only to client structures since breaking model
* By default, we apply `#[non_exhaustive]` in [additionalAttributes] only to client structures since breaking model
* changes are fine when generating server code.
*/
class BaseSymbolMetadataProvider(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private val allowedClippyLints = listOf(
"should_implement_trait",

// Protocol tests use silly names like `baz`, don't flag that.
// TODO(msrv_upgrade): switch
// TODO(msrv_upgrade): switch upon MSRV upgrade to Rust 1.65
"blacklisted_name",
// "disallowed_names",

Expand All @@ -48,11 +48,10 @@ private val allowedClippyLints = listOf(
"needless_return",

// For backwards compatibility, we often don't derive Eq
// TODO(msrv_upgrade): enable
// "derive_partial_eq_without_eq",
"derive_partial_eq_without_eq",

// Keeping errors small in a backwards compatible way is challenging
// TODO(msrv_upgrade): enable
// TODO(msrv_upgrade): uncomment upon MSRV upgrade to Rust 1.65
// "result_large_err",
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ class BuilderGenerator(
private val members: List<MemberShape> = shape.allMembers.values.toList()
private val structureSymbol = symbolProvider.toSymbol(shape)
private val builderSymbol = shape.builderSymbol(symbolProvider)
private val baseDerives = structureSymbol.expectRustMetadata().derives
private val metadata = structureSymbol.expectRustMetadata()

// Filter out any derive that isn't Debug, PartialEq, or Clone. Then add a Default derive
private val builderDerives = baseDerives.filter { it == RuntimeType.Debug || it == RuntimeType.PartialEq || it == RuntimeType.Clone } + RuntimeType.Default
private val builderDerives = metadata.derives.filter { it == RuntimeType.Debug || it == RuntimeType.PartialEq || it == RuntimeType.Clone } + RuntimeType.Default
private val builderName = "Builder"

fun render(writer: RustWriter) {
Expand Down Expand Up @@ -207,6 +207,7 @@ class BuilderGenerator(

private fun renderBuilder(writer: RustWriter) {
writer.docs("A builder for #D.", structureSymbol)
metadata.additionalAttributes.render(writer)
Attribute(derive(builderDerives)).render(writer)
writer.rustBlock("pub struct $builderName") {
for (member in members) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,13 @@ class HttpBindingGenerator(
let $safeName = $formatted;
if !$safeName.is_empty() {
let header_value = $safeName;
let header_value = http::header::HeaderValue::try_from(&*header_value).map_err(|err| {
let header_value: #{HeaderValue} = header_value.parse().map_err(|err| {
#{invalid_field_error:W}
})?;
builder = builder.header("$headerName", header_value);
}
""",
"HeaderValue" to RuntimeType.Http.resolve("HeaderValue"),
"invalid_field_error" to renderErrorMessage("header_value"),
)
}
Expand Down Expand Up @@ -698,13 +699,14 @@ class HttpBindingGenerator(
isMultiValuedHeader = false,
)
};
let header_value = http::header::HeaderValue::try_from(&*header_value).map_err(|err| {
let header_value: #{HeaderValue} = header_value.parse().map_err(|err| {
#{invalid_header_value:W}
})?;
builder = builder.header(header_name, header_value);
}

""",
"HeaderValue" to RuntimeType.Http.resolve("HeaderValue"),
"invalid_header_name" to OperationBuildError(runtimeConfig).invalidField(memberName) {
rust("""format!("`{k}` cannot be used as a header name: {err}")""")
},
Expand Down