Skip to content

Commit

Permalink
Bump Rust MSRV to 1.63.0 (smithy-lang#2222)
Browse files Browse the repository at this point in the history
Co-authored-by: Zelda Hessler <zhessler@amazon.com>
Co-authored-by: John DiSanti <jdisanti@amazon.com>
  • Loading branch information
3 people committed Feb 10, 2023
1 parent 13b10d5 commit de18667
Show file tree
Hide file tree
Showing 53 changed files with 126 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
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
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
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
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
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
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
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
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
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
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
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
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
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-inlineable/src/http_body_checksum.rs
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
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
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
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
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
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
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
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
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
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
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)
}
}
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
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
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
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

0 comments on commit de18667

Please sign in to comment.