Skip to content

Commit

Permalink
Bump up MSRV to 1.57
Browse files Browse the repository at this point in the history
- improve error reporting for `const` assertions
- tune up lints for 1.57 Rust
  • Loading branch information
tyranron committed Dec 3, 2021
1 parent e7387d4 commit cef3d48
Show file tree
Hide file tree
Showing 22 changed files with 145 additions and 128 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
strategy:
fail-fast: false
matrix:
msrv: ['1.56.0']
msrv: ['1.57.0']
crate:
- cucumber-codegen
- cucumber
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ All user visible changes to `cucumber` crate will be documented in this file. Th
- Moved `World` type parameter of `WriterExt` trait to methods. ([#160])
- Renamed `Normalized` and `Summarized` `Writer`s to `Normalize` and `Summarize`. ([#162])
- Removed `writer::Basic` `Default` impl and change `writer::Basic::new()` return type to `writer::Normalize<writer::Basic>`. ([#162])
- Bump up [MSRV] to 1.57 for better error reporting in `const` assertions. ([rev])

### Added

Expand Down Expand Up @@ -49,6 +50,7 @@ All user visible changes to `cucumber` crate will be documented in this file. Th
[#165]: /../../pull/165
[#166]: /../../pull/166
[#168]: /../../pull/168
[rev]: /../../commit/rev-full
[0110-1]: https://llg.cubic.org/docs/junit
[0110-2]: https://github.com/cucumber/cucumber-json-schema

Expand Down Expand Up @@ -273,4 +275,5 @@ All user visible changes to `cucumber` crate will be documented in this file. Th
[`gherkin_rust`]: https://docs.rs/gherkin_rust

[Cucumber Expressions]: https://cucumber.github.io/cucumber-expressions
[MSRV]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field
[Semantic Versioning 2.0.0]: https://semver.org
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cucumber"
version = "0.11.0-dev"
edition = "2021"
rust-version = "1.56"
rust-version = "1.57"
description = """\
Cucumber testing framework for Rust, with async support. \
Fully native, no external test runners or dependencies.\
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Cucumber testing framework for Rust

[![Documentation](https://docs.rs/cucumber/badge.svg)](https://docs.rs/cucumber)
[![CI](https://github.com/cucumber-rs/cucumber/workflows/CI/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber/actions?query=workflow%3ACI+branch%3Amain)
[![Rust 1.56+](https://img.shields.io/badge/rustc-1.56+-lightgray.svg "Rust 1.56+")](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
[![Rust 1.57+](https://img.shields.io/badge/rustc-1.57+-lightgray.svg "Rust 1.57+")](https://blog.rust-lang.org/2021/12/02/Rust-1.57.0.html)
[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)

An implementation of the [Cucumber] testing framework for Rust. Fully native, no external test runners or dependencies.
Expand Down
6 changes: 6 additions & 0 deletions codegen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ All user visible changes to `cucumber-codegen` crate will be documented in this

[Milestone](/../../milestone/3)

### BC Breaks

- Bump up [MSRV] to 1.57 for better error reporting in `const` assertions. ([rev])

### Added

- Unwrapping `Result`s returned by step functions. ([#151])
Expand All @@ -20,6 +24,7 @@ All user visible changes to `cucumber-codegen` crate will be documented in this
[#151]: /../../pull/151
[#157]: /../../pull/157
[#168]: /../../pull/168
[rev]: /../../commit/rev-full



Expand Down Expand Up @@ -81,4 +86,5 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0


[Cucumber Expressions]: https://cucumber.github.io/cucumber-expressions
[MSRV]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field
[Semantic Versioning 2.0.0]: https://semver.org
2 changes: 1 addition & 1 deletion codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cucumber-codegen"
version = "0.11.0-dev" # should be the same as main crate version
edition = "2021"
rust-version = "1.56"
rust-version = "1.57"
description = "Code generation for `cucumber` crate."
license = "MIT OR Apache-2.0"
authors = [
Expand Down
2 changes: 1 addition & 1 deletion codegen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[![Documentation](https://docs.rs/cucumber-codegen/badge.svg)](https://docs.rs/cucumber-codegen)
[![CI](https://github.com/cucumber-rs/cucumber/workflows/CI/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber/actions?query=workflow%3ACI+branch%3Amain)
[![Rust 1.56+](https://img.shields.io/badge/rustc-1.56+-lightgray.svg "Rust 1.56+")](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
[![Rust 1.57+](https://img.shields.io/badge/rustc-1.57+-lightgray.svg "Rust 1.57+")](https://blog.rust-lang.org/2021/12/02/Rust-1.57.0.html)
[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)

- [Changelog](https://github.com/cucumber-rs/cucumber/blob/main/codegen/CHANGELOG.md)
Expand Down
44 changes: 26 additions & 18 deletions codegen/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ impl Step {

Ok((func_args, addon_parsing))
} else {
// false positive: impl of `FnOnce` is not general enough
#[allow(clippy::redundant_closure_for_method_calls)]
let (idents, parsings): (Vec<_>, Vec<_>) =
itertools::process_results(
Expand Down Expand Up @@ -483,13 +484,14 @@ impl<'p> Parameters<'p> {
| SingleExpression::Whitespaces(_) => None,
})
.zip(param_tys.into_iter().map(Some).chain(iter::repeat(None)))
.filter_map(|(ast, ty)| {
.filter_map(|(ast, param_ty)| {
if DEFAULT_PARAMETERS.iter().any(|s| s == &**ast) {
// If parameter is default, it's ok if there is no type
// If parameter is default, it's OK if there is no type
// corresponding to it, as we know its regex.
ty.cloned()
param_ty
.cloned()
.map(|ty| Ok(ParameterProvider { param: ast, ty }))
} else if let Some(ty) = ty.cloned() {
} else if let Some(ty) = param_ty.cloned() {
Some(Ok(ParameterProvider { param: ast, ty }))
} else {
Some(Err(syn::Error::new(
Expand Down Expand Up @@ -534,14 +536,16 @@ impl<'p> Parameters<'p> {
// existing one from `const_assertions` crate, for the
// purpose of better errors reporting when the assertion
// fails.

let trait_with_hint = format_ident!(
"UseParameterNameInsteadOf{}",
to_pascal_case(name),
);

quote! {
// In case we encounter default parameter, we should
// assert that corresponding type __doesn't__ implement
// a `Parameter` trait.
// assert that corresponding argument's type __doesn't__
// implement a `Parameter` trait.
#[automatically_derived]
const _: fn() = || {
// Generic trait with a blanket impl over `()` for
Expand Down Expand Up @@ -572,25 +576,29 @@ impl<'p> Parameters<'p> {
};
}
} else {
// Here we use double escaping to properly render `{name}`
// in the assertion message of the generated code.
let assert_msg = format!(
"Type `{}` doesn't implement a custom parameter \
`{{{{{}}}}}`",
quote! { #ty },
name,
);

quote! {
// In case we encounter a custom parameter, we should
// assert that the corresponding type implements
// `Parameter` and has correct `Parameter::NAME`.
// TODO: Panic here, once `const_panic` is stabilized.
// https://github.com/rust-lang/rust/pull/89508
#[automatically_derived]
#[allow(unknown_lints, eq_op)]
const _: [
();
0 - !{
const ASSERT: bool =
::cucumber::codegen::str_eq(
<#ty as ::cucumber::Parameter>::NAME,
#name,
);
ASSERT
} as usize
] = [];
const _: () = ::std::assert!(
::cucumber::codegen::str_eq(
<#ty as ::cucumber::Parameter>::NAME,
#name,
),
#assert_msg,
);
}
}
})
Expand Down
2 changes: 2 additions & 0 deletions codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
clippy::decimal_literal_representation,
clippy::else_if_without_else,
clippy::empty_line_after_outer_attr,
clippy::equatable_if_let,
clippy::exit,
clippy::expect_used,
clippy::fallible_impl_from,
Expand All @@ -57,6 +58,7 @@
clippy::rc_buffer,
clippy::rc_mutex,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_name_method,
clippy::shadow_unrelated,
clippy::str_to_string,
clippy::string_add,
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/world_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use proc_macro2::TokenStream;
use quote::{format_ident, quote};

/// Generates code of `#[derive(WorldInit)]` macro expansion.
#[allow(clippy::similar_names)]
#[allow(clippy::similar_names)] // because of `when_ty` vs `then_ty`
pub(crate) fn derive(
input: TokenStream,
steps: &[&str],
Expand Down
1 change: 1 addition & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ where
pub struct Empty {
/// This field exists only because [`StructOpt`] derive macro doesn't
/// support unit structs.
#[allow(dead_code)]
#[structopt(skip)]
skipped: (),
}
Expand Down
24 changes: 12 additions & 12 deletions src/cucumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,29 +813,29 @@ where
..
} = self.cli.unwrap_or_else(cli::Opts::<_, _, _, _>::from_args);

let filter = move |f: &gherkin::Feature,
r: Option<&gherkin::Rule>,
s: &gherkin::Scenario| {
let filter = move |feat: &gherkin::Feature,
rule: Option<&gherkin::Rule>,
scenario: &gherkin::Scenario| {
re_filter.as_ref().map_or_else(
|| {
tags_filter.as_ref().map_or_else(
|| filter(f, r, s),
|| filter(feat, rule, scenario),
|tags| {
// The order `Feature` -> `Rule` -> `Scenario`
// matters here.
tags.eval(
f.tags
feat.tags
.iter()
.chain(
r.into_iter()
rule.into_iter()
.flat_map(|r| r.tags.iter()),
)
.chain(s.tags.iter()),
.chain(scenario.tags.iter()),
)
},
)
},
|re| re.is_match(&s.name),
|re| re.is_match(&scenario.name),
)
};

Expand All @@ -850,16 +850,16 @@ where

let filtered = features.map(move |feature| {
let mut feature = feature?;
let scenarios = mem::take(&mut feature.scenarios);
feature.scenarios = scenarios
let feat_scenarios = mem::take(&mut feature.scenarios);
feature.scenarios = feat_scenarios
.into_iter()
.filter(|s| filter(&feature, None, s))
.collect();

let mut rules = mem::take(&mut feature.rules);
for r in &mut rules {
let scenarios = mem::take(&mut r.scenarios);
r.scenarios = scenarios
let rule_scenarios = mem::take(&mut r.scenarios);
r.scenarios = rule_scenarios
.into_iter()
.filter(|s| filter(&feature, Some(r), s))
.collect();
Expand Down
1 change: 0 additions & 1 deletion src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ impl<World> Cucumber<World> {
) -> Self {
Self::Feature(
feat,
#[allow(clippy::option_if_let_else)] // use of moved value: `event`
if let Some(r) = rule {
Feature::Rule(r, Rule::Scenario(scenario, event))
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
clippy::decimal_literal_representation,
clippy::else_if_without_else,
clippy::empty_line_after_outer_attr,
clippy::equatable_if_let,
clippy::exit,
clippy::expect_used,
clippy::fallible_impl_from,
Expand All @@ -59,6 +60,7 @@
clippy::rc_buffer,
clippy::rc_mutex,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_name_method,
clippy::shadow_unrelated,
clippy::str_to_string,
clippy::string_add,
Expand Down
14 changes: 7 additions & 7 deletions src/parser/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<I: AsRef<Path>> Parser<I> for Basic {
.collect::<Vec<_>>()
};

let get_path = || {
let get_features_path = || {
let path = path.as_ref();
path.canonicalize()
.or_else(|_| {
Expand All @@ -106,26 +106,26 @@ impl<I: AsRef<Path>> Parser<I> for Basic {
let features = if let Some(walker) = cli.features {
walk(walker.0)
} else {
let path = match get_path() {
Ok(path) => path,
let feats_path = match get_features_path() {
Ok(p) => p,
Err(e) => return vec![Err(e.into())],
};

if path.is_file() {
if feats_path.is_file() {
let env = self
.language
.as_ref()
.and_then(|l| GherkinEnv::new(l).ok())
.unwrap_or_default();
vec![gherkin::Feature::parse_path(path, env)]
vec![gherkin::Feature::parse_path(feats_path, env)]
} else {
let walker = GlobWalkerBuilder::new(path, "*.feature")
let w = GlobWalkerBuilder::new(feats_path, "*.feature")
.case_insensitive(true)
.build()
.unwrap_or_else(|e| {
unreachable!("GlobWalkerBuilder panicked: {}", e)
});
walk(walker)
walk(w)
}
};

Expand Down
Loading

0 comments on commit cef3d48

Please sign in to comment.