proptest_derive/
error.rs

1// Copyright 2018 The proptest developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Provides error messages and some checkers.
10
11use std::fmt::Display;
12
13use proc_macro2::TokenStream;
14use quote::ToTokens;
15
16use crate::attr::ParsedAttributes;
17use syn;
18
19//==============================================================================
20// Item descriptions
21//==============================================================================
22
23/// Item name of structs.
24pub const STRUCT: &str = "struct";
25
26/// Item name of struct fields.
27pub const STRUCT_FIELD: &str = "struct field";
28
29/// Item name of enums.
30pub const ENUM: &str = "enum";
31
32/// Item name of enum variants.
33pub const ENUM_VARIANT: &str = "enum variant";
34
35/// Item name of enum variant fields.
36pub const ENUM_VARIANT_FIELD: &str = "enum variant field";
37
38/// Item name for a type variable.
39pub const TY_VAR: &str = "a type variable";
40
41//==============================================================================
42// Checkers
43//==============================================================================
44
45/// Ensures that the type is not parametric over lifetimes.
46pub fn if_has_lifetimes(ctx: Ctx, ast: &syn::DeriveInput) {
47    if ast.generics.lifetimes().count() > 0 {
48        has_lifetimes(ctx);
49    }
50}
51
52/// Ensures that no attributes were specified on `item`.
53pub fn if_anything_specified(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
54    if_enum_attrs_present(ctx, attrs, item);
55    if_strategy_present(ctx, attrs, item);
56    if_specified_params(ctx, attrs, item);
57    if_specified_filter(ctx, attrs, item);
58}
59
60/// Ensures that things only allowed on an enum variant is not present on
61/// `item` which is not an enum variant.
62pub fn if_enum_attrs_present(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
63    if_skip_present(ctx, attrs, item);
64    if_weight_present(ctx, attrs, item);
65}
66
67/// Ensures that parameters is not present on `item`.
68pub fn if_specified_filter(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
69    if !attrs.filter.is_empty() {
70        meaningless_filter(ctx, item);
71    }
72}
73
74/// Ensures that parameters is not present on `item`.
75pub fn if_specified_params(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
76    if attrs.params.is_set() {
77        parent_has_param(ctx, item);
78    }
79}
80
81/// Ensures that an explicit strategy or value is not present on `item`.
82pub fn if_strategy_present(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
83    use crate::attr::StratMode::*;
84    match attrs.strategy {
85        Arbitrary => {}
86        Strategy(_) => illegal_strategy(ctx, "strategy", item),
87        Value(_) => illegal_strategy(ctx, "value", item),
88        Regex(_) => illegal_regex(ctx, item),
89    }
90}
91
92/// Ensures that a strategy, value, params, filter is not present on a unit variant.
93pub fn if_present_on_unit_variant(ctx: Ctx, attrs: &ParsedAttributes) {
94    /// Ensures that an explicit strategy or value is not present on a unit variant.
95    use crate::attr::StratMode::*;
96    match attrs.strategy {
97        Arbitrary => {}
98        Strategy(_) => strategy_on_unit_variant(ctx, "strategy"),
99        Value(_) => strategy_on_unit_variant(ctx, "value"),
100        Regex(_) => regex_on_unit_variant(ctx),
101    }
102
103    if attrs.params.is_set() {
104        params_on_unit_variant(ctx)
105    }
106
107    if !attrs.filter.is_empty() {
108        filter_on_unit_variant(ctx)
109    }
110}
111
112/// Ensures that parameters or filter is not present on a unit struct.
113pub fn if_present_on_unit_struct(ctx: Ctx, attrs: &ParsedAttributes) {
114    if attrs.params.is_set() {
115        params_on_unit_struct(ctx)
116    }
117
118    if !attrs.filter.is_empty() {
119        filter_on_unit_struct(ctx)
120    }
121}
122
123/// Ensures that skip is not present on `item`.
124pub fn if_skip_present(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
125    if attrs.skip {
126        illegal_skip(ctx, item)
127    }
128}
129
130/// Ensures that a weight is not present on `item`.
131pub fn if_weight_present(ctx: Ctx, attrs: &ParsedAttributes, item: &str) {
132    if attrs.weight.is_some() {
133        illegal_weight(ctx, item)
134    }
135}
136
137//==============================================================================
138// Messages
139//==============================================================================
140
141/// Denotes that a fatal error happened in dealing somewhere in the
142/// procedural macro pipeline. A fatal error is different from a
143/// normal error in the sense that it halts progress in the macro
144/// immediately instead of allowing other errors to be accumulated.
145#[derive(Debug)]
146pub struct Fatal;
147
148/// The return type of a possibly fatal computation in the macro.
149pub type DeriveResult<T> = Result<T, Fatal>;
150
151/// A mutable view / shorthand for the context.
152/// Prefer this type over `Context` in functions.
153pub type Ctx<'ctx> = &'ctx mut Context;
154
155/// The context / environment that the macro is operating in.
156/// Right now, it simply tracks all the errors collected during
157/// the running of the macro.
158#[derive(Default)]
159pub struct Context {
160    errors: Vec<String>,
161}
162
163impl Context {
164    /// Add a non-fatal error to the context.
165    pub fn error<T: Display>(&mut self, msg: T) {
166        self.errors.push(msg.to_string());
167    }
168
169    /// Add an error to the context and produce an erroring
170    /// computation that will halt the macro.
171    pub fn fatal<T: Display, A>(&mut self, msg: T) -> DeriveResult<A> {
172        self.error(msg);
173        Err(Fatal)
174    }
175
176    /// Consume the context and if there were any errors,
177    /// emit `compile_error!(..)` such that the crate using
178    /// `#[derive(Arbitrary)]` will fail to compile.
179    pub fn check(mut self) -> Result<(), TokenStream> {
180        fn compile_error(msg: &str) -> TokenStream {
181            quote! {
182                compile_error!(#msg);
183            }
184        }
185
186        match self.errors.len() {
187            0 => Ok(()),
188            1 => Err(compile_error(&self.errors.pop().unwrap())),
189            n => {
190                let mut msg = format!("{} errors:", n);
191                for err in self.errors {
192                    msg.push_str("\n\t# ");
193                    msg.push_str(&err);
194                }
195                Err(compile_error(&msg))
196            }
197        }
198    }
199}
200
201//==============================================================================
202// Messages
203//==============================================================================
204
205/// Produce an error string with the error `$code` which corresponds
206/// to the given `$message`.
207macro_rules! mk_err_msg {
208    ($code: ident, $msg: expr) => {
209        concat!(
210            "[proptest_derive, ",
211            stringify!($code),
212            "]",
213            " during #[derive(Arbitrary)]:\n",
214            $msg,
215            " Please see: https://PATH/TO/foo#",
216            stringify!($code),
217            " for more information."
218        )
219    };
220}
221
222/// A macro constructing errors that do halt compilation immediately.
223macro_rules! fatal {
224    ($error: ident, $code: ident, $msg: expr) => {
225        pub fn $error<T>(ctx: Ctx) -> DeriveResult<T> {
226            ctx.fatal(mk_err_msg!($code, $msg))
227        }
228    };
229    ($error: ident ($($arg: ident: $arg_ty: ty),*), $code: ident,
230     $msg: expr, $($fmt: tt)+) => {
231        pub fn $error<T>(ctx: Ctx, $($arg: $arg_ty),*) -> DeriveResult<T> {
232            ctx.fatal(format!(mk_err_msg!($code, $msg), $($fmt)+))
233        }
234    };
235}
236
237/// A macro constructing fatal errors that do not halt compilation immediately.
238macro_rules! error {
239    ($error: ident, $code: ident, $msg: expr) => {
240        pub fn $error(ctx: Ctx) {
241            ctx.error(mk_err_msg!($code, $msg))
242        }
243    };
244    ($error: ident ($($arg: ident: $arg_ty: ty),*), $code: ident,
245     $msg: expr, $($fmt: tt)+) => {
246        pub fn $error(ctx: Ctx, $($arg: $arg_ty),*) {
247            ctx.error(format!(mk_err_msg!($code, $msg), $($fmt)+))
248        }
249    };
250}
251
252// Happens when we've been asked to derive `Arbitrary` for a type
253// that is parametric over lifetimes. Since proptest does not support
254// such types (yet), neither can we.
255error!(
256    has_lifetimes,
257    E0001,
258    "Cannot derive `Arbitrary` for types with generic lifetimes, such as: \
259     `struct Foo<'a> { bar: &'a str }`. Currently, strategies for such types \
260     are impossible to define."
261);
262
263// Happens when we've been asked to derive `Arbitrary` for something
264// that is neither an enum nor a struct. Most likely, we've been given
265// a union type. This might be supported in the future, but not yet.
266fatal!(
267    not_struct_or_enum,
268    E0002,
269    "Deriving is only possible for structs and enums. \
270     It is currently not defined unions."
271);
272
273// Happens when a struct has at least one field that is uninhabited.
274// There must at least exist one variant that we can construct.
275error!(
276    uninhabited_struct,
277    E0003,
278    "The struct you are deriving `Arbitrary` for is uninhabited since one of \
279    its fields is uninhabited. An uninhabited type is by definition impossible \
280    to generate."
281);
282
283// Happens when an enum has zero variants. Such an enum is obviously
284// uninhabited and can not be constructed. There must at least exist
285// one variant that we can construct.
286fatal!(
287    uninhabited_enum_with_no_variants,
288    E0004,
289    "The enum you are deriving `Arbitrary` for is uninhabited since it has no \
290     variants. An example of such an `enum` is: `enum Void {}`. \
291     An uninhabited type is by definition impossible to generate."
292);
293
294// Happens when an enum is uninhabited due all its variants being
295// uninhabited (why has the user given us such a weird enum?..
296// Nonetheless, we do our best to ensure soundness).
297// There must at least exist one variant that we can construct.
298fatal!(
299    uninhabited_enum_variants_uninhabited,
300    E0005,
301    "The enum you are deriving `Arbitrary` for is uninhabited since all its \
302     variants are uninhabited. \
303     An uninhabited type is by definition impossible to generate."
304);
305
306// Happens when an enum becomes effectively uninhabited due
307// to all inhabited variants having been skipped. There must
308// at least exist one variant that we can construct.
309error!(
310    uninhabited_enum_because_of_skipped_variants,
311    E0006,
312    "The enum you are deriving `Arbitrary` for is uninhabited for all intents \
313     and purposes since you have `#[proptest(skip)]`ed all inhabited variants. \
314     An uninhabited type is by definition impossible to generate."
315);
316
317// Happens when `#[proptest(strategy = "<expr>")]` or
318// `#[proptest(value = "<expr>")]` is specified on an `item`
319// that does not support setting an explicit value or strategy.
320// An enum or struct does not support that.
321error!(illegal_strategy(attr: &str, item: &str), E0007,
322    "`#[proptest({0} = \"<expr>\")]` is not allowed on {1}. Only struct fields, \
323    enum variants and fields inside those can use an explicit {0}.",
324    attr, item);
325
326// Happens when `#[proptest(regex = "<string>")]` is specified on an `item`
327// that does not support setting an explicit value or strategy.
328// See `illegal_strategy` for more.
329error!(
330    illegal_regex(item: &str),
331    E0007,
332    "`#[proptest(regex = \"<string>\")]` is not allowed on {0}. Only struct \
333     fields, enum variant fields can use an explicit regex.",
334    item
335);
336
337// Happens when `#[proptest(skip)]` is specified on an `item` that does
338// not support skipping. Only enum variants support skipping.
339error!(
340    illegal_skip(item: &str),
341    E0008,
342    "A {} can't be `#[proptest(skip)]`ed, only enum variants can be skipped.",
343    item
344);
345
346// Happens when `#[proptest(weight = <integer>)]` is specified on an
347// `item` that does not support weighting.
348error!(
349    illegal_weight(item: &str),
350    E0009,
351    "`#[proptest(weight = <integer>)]` is not allowed on {} as it is \
352     meaningless. Only enum variants can be assigned weights.",
353    item
354);
355
356// Happens when `#[proptest(params = <type>)]` is set on `item`
357// but also on the parent of `item`. If the parent has set `params`
358// then that applies, and the `params` on `item` would be meaningless
359// wherefore it is forbidden.
360error!(
361    parent_has_param(item: &str),
362    E0010,
363    "Cannot set the associated type `Parameters` of `Arbitrary` with either \
364     `#[proptest(no_params)]` or `#[proptest(params(<type>)]` on {} since it \
365     was set on the parent.",
366    item
367);
368
369// Happens when `#[proptest(params = <type>)]` is set on `item`
370// but not `#[proptest(strategy = <expr>)]`.
371// This does not apply to the top level type declaration.
372fatal!(
373    cant_set_param_but_not_strat(self_ty: &syn::Type, item: &str),
374    E0011,
375    "Cannot set `#[proptest(params = <type>)]` on {0} while not providing a \
376     strategy for the {0} to use it since `<{1} as Arbitrary<'a>>::Strategy` \
377     may require a different type than the one provided in `<type>`.",
378    item,
379    quote! { #self_ty }
380);
381
382// Happens when `#[proptest(filter = "<expr>")]` is set on `item`,
383// but the parent of the `item` explicitly specifies a value or strategy,
384// which would cause the value to be generated without consulting the
385// `filter`.
386error!(
387    meaningless_filter(item: &str),
388    E0012,
389    "Cannot set `#[proptest(filter = <expr>)]` on {} since it is set on the \
390     item which it is inside of that outer item specifies how to generate \
391     itself.",
392    item
393);
394
395// Happens when the form `#![proptest<..>]` is used. This will probably never
396// happen - but just in case it does, we catch it and emit an error.
397error!(
398    inner_attr,
399    E0013, "Inner attributes `#![proptest(..)]` are not currently supported."
400);
401
402// Happens when the form `#[proptest]` is used. The form contains no
403// information for us to process, so we disallow it.
404error!(
405    bare_proptest_attr,
406    E0014, "Bare `#[proptest]` attributes are not allowed."
407);
408
409// Happens when the form `#[proptest = <literal>)]` is used.
410// Only the form `#[proptest(<contents>)]` is supported.
411error!(
412    literal_set_proptest,
413    E0015, "The attribute form `#[proptest = <literal>]` is not allowed."
414);
415
416// Happens when `<modifier>` in `#[proptest(<modifier>)]` is a literal and
417// not a real modifier.
418error!(
419    immediate_literals,
420    E0016,
421    "Literals immediately inside `#[proptest(..)]` as in \
422     `#[proptest(<lit>, ..)]` are not allowed."
423);
424
425// Happens when `<modifier>` in `#[proptest(<modifier>)]` is set more than
426// once.
427error!(
428    set_again(meta: &syn::Meta),
429    E0017,
430    "The attribute modifier `{}` inside `#[proptest(..)]` has already been \
431     set. To fix the error, please remove at least one such modifier.",
432    meta.path().into_token_stream()
433);
434
435// Happens when `<modifier>` in `#[proptest(<modifier>)]` is unknown to
436// us but we can make an educated guess as to what the user meant.
437error!(
438    did_you_mean(found: &str, expected: &str),
439    E0018,
440    "Unknown attribute modifier `{}` inside #[proptest(..)] is not allowed. \
441     Did you mean to use `{}` instead?",
442    found,
443    expected
444);
445
446// TODO: `unkown_modifier` is misspelled
447// Happens when `<modifier>` in `#[proptest(<modifier>)]` is unknown to us.
448error!(
449    unkown_modifier(modifier: &str),
450    E0018,
451    "Unknown attribute modifier `{}` inside `#[proptest(..)]` is not allowed.",
452    modifier
453);
454
455// Happens when `#[proptest(no_params)]` is malformed.
456error!(
457    no_params_malformed,
458    E0019,
459    "The attribute modifier `no_params` inside `#[proptest(..)]` does not \
460     support any further configuration and must be a plain modifier as in \
461     `#[proptest(no_params)]`."
462);
463
464// Happens when `#[proptest(skip)]` is malformed.
465error!(
466    skip_malformed,
467    E0020,
468    "The attribute modifier `skip` inside `#[proptest(..)]` does not support \
469     any further configuration and must be a plain modifier as in \
470     `#[proptest(skip)]`."
471);
472
473// Happens when `#[proptest(weight..)]` is malformed.
474error!(
475    weight_malformed(meta: &syn::Meta),
476    E0021,
477    "The attribute modifier `{0}` inside `#[proptest(..)]` must have the \
478    format `#[proptest({0} = <integer>)]` where `<integer>` is an integer that \
479    fits within a `u32`. An example: `#[proptest({0} = 2)]` to set a relative \
480    weight of 2.",
481    meta.path().into_token_stream()
482);
483
484// Happens when both `#[proptest(params = "<type>")]` and
485// `#[proptest(no_params)]` were specified. They are mutually
486// exclusive choices. The user can resolve this by picking one.
487fatal!(
488    overspecified_param,
489    E0022,
490    "Cannot set `#[proptest(no_params)]` as well as \
491     `#[proptest(params(<type>))]` simultaneously. \
492     Please pick one of these attributes."
493);
494
495// This happens when `#[proptest(params..)]` is malformed.
496// For example, `#[proptest(params)]` is malformed. Another example is when
497// `<type>` inside `#[proptest(params = "<type>")]` or
498// `#[proptest(params("<type>"))]` is malformed. In other words, `<type>` is
499// not a valid Rust type. Note that `syn` may not cover all valid Rust types.
500error!(
501    param_malformed,
502    E0023,
503    "The attribute modifier `params` inside #[proptest(..)] must have the \
504     format `#[proptest(params = \"<type>\")]` where `<type>` is a valid type \
505     in Rust. An example: `#[proptest(params = \"ComplexType<Foo>\")]`."
506);
507
508// Happens when more than one of `#[proptest(strategy..)]`,
509// `#[proptest(value..)]`, or `#[proptest(regex..)]` were specified.
510// They are mutually exclusive choices.
511// The user can resolve this by picking one.
512fatal!(
513    overspecified_strat,
514    E0025,
515    "Cannot set more than one of `#[proptest(value = \"<expr>\")]`,
516    `#[proptest(strategy = \"<expr>\")]`, `#[proptest(regex = \"<string>\")]` \
517    simultaneously. Please pick one of these attributes."
518);
519
520// Happens when `#[proptest(strategy..)]` or `#[proptest(value..)]` is
521// malformed. For example, `<expr>` inside `#[proptest(strategy = "<expr>")]`
522// or `#[proptest(value = "<expr>")]` is malformed. In other words, `<expr>`
523// is not a valid Rust expression.
524error!(
525    strategy_malformed(meta: &syn::Meta),
526    E0026,
527    "The attribute modifier `{0}` inside `#[proptest(..)]` must have the \
528     format `#[proptest({0} = \"<expr>\")]` where `<expr>` is a valid Rust \
529     expression.",
530    meta.path().into_token_stream()
531);
532
533// Happens when `#[proptest(filter..)]` is malformed.
534// For example, `<expr>` inside `#[proptest(filter = "<expr>")]` or
535// is malformed. In other words, `<expr>` is not a valid Rust expression.
536error!(
537    filter_malformed(meta: &syn::Meta),
538    E0027,
539    "The attribute modifier `{0}` inside `#[proptest(..)]` must have the \
540     format `#[proptest({0} = \"<expr>\")]` where `<expr>` is a valid Rust \
541     expression.",
542    meta.path().into_token_stream()
543);
544
545// Any attributes on a skipped variant has no effect - so we emit this error
546// to the user so that they are aware.
547error!(
548    skipped_variant_has_weight(item: &str),
549    E0028,
550    "A variant has been skipped. Setting `#[proptest(weight = <value>)]` on \
551     the {} is meaningless and is not allowed.",
552    item
553);
554
555// Any attributes on a skipped variant has no effect - so we emit this error
556// to the user so that they are aware.
557error!(
558    skipped_variant_has_param(item: &str),
559    E0028,
560    "A variant has been skipped. Setting `#[proptest(no_param)]` or \
561    `#[proptest(params(<type>))]` on the {} is meaningless and is not allowed.",
562    item
563);
564
565// Any attributes on a skipped variant has no effect - so we emit this error
566// to the user so that they are aware.
567error!(
568    skipped_variant_has_strat(item: &str),
569    E0028,
570    "A variant has been skipped. Setting `#[proptest(value = \"<expr>\")]` or \
571     `#[proptest(strategy = \"<expr>\")]` on the {} is meaningless and is not \
572     allowed.",
573    item
574);
575
576// Any attributes on a skipped variant has no effect - so we emit this error
577// to the user so that they are aware. Unfortunately, there's no way to
578// emit a warning to the user, so we emit an error instead.
579error!(skipped_variant_has_filter(item: &str), E0028,
580    "A variant has been skipped. Setting `#[proptest(filter = \"<expr>\")]` or \
581    on the {} is meaningless and is not allowed.",
582    item);
583
584// There's only one way to produce a specific unit variant, so setting
585// `#[proptest(strategy = "<expr>")]` or `#[proptest(value = "<expr>")]`
586// would be pointless.
587error!(
588    strategy_on_unit_variant(what: &str),
589    E0029,
590    "Setting `#[proptest({0} = \"<expr>\")]` on a unit variant has no effect \
591     and is redundant because there is nothing to configure.",
592    what
593);
594
595// See `strategy_on_unit_variant`.
596error!(regex_on_unit_variant, E0029,
597    "Setting `#[proptest(regex = \"<string>\")]` on a unit variant has no effect \
598    and is redundant because there is nothing to configure.");
599
600// There's only one way to produce a specific unit variant, so setting
601// `#[proptest(params = "<type>")]` would be pointless.
602error!(
603    params_on_unit_variant,
604    E0029,
605    "Setting `#[proptest(params = \"<type>\")]` on a unit variant has \
606     no effect and is redundant because there is nothing to configure."
607);
608
609// There's only one way to produce a specific unit variant, so setting
610// `#[proptest(filter = "<expr>")]` would be pointless.
611error!(
612    filter_on_unit_variant,
613    E0029,
614    "Setting `#[proptest(filter = \"<expr>\")]` on a unit variant has \
615     no effect and is redundant because there is nothing to further filter."
616);
617
618// Occurs when `#[proptest(params = "<type>")]` is specified on a unit
619// struct. There's only one way to produce a unit struct, so specifying
620// `Parameters` would be pointless.
621error!(params_on_unit_struct, E0030,
622    "Setting `#[proptest(params = \"<type>\")]` on a unit struct has no effect \
623    and is redundant because there is nothing to configure.");
624
625// Occurs when `#[proptest(filter = "<expr>")]` is specified on a unit
626// struct. There's only one way to produce a unit struct, so filtering
627// would be pointless.
628error!(filter_on_unit_struct, E0030,
629    "Setting `#[proptest(filter = \"<expr>\")]` on a unit struct has no effect \
630    and is redundant because there is nothing to filter.");
631
632// Occurs when `#[proptest(no_bound)]` is specified
633// on something that is not a type variable.
634error!(
635    no_bound_set_on_non_tyvar,
636    E0031,
637    "Setting `#[proptest(no_bound)]` on something that is not a type variable \
638     has no effect and is redundant. Therefore it is not allowed."
639);
640
641// Happens when `#[proptest(no_bound)]` is malformed.
642error!(
643    no_bound_malformed,
644    E0032,
645    "The attribute modifier `no_bound` inside `#[proptest(..)]` does not \
646     support any further configuration and must be a plain modifier as in \
647     `#[proptest(no_bound)]`."
648);
649
650// Happens when the sum of weights on enum variants overflowing an u32.
651error!(
652    weight_overflowing,
653    E0033,
654    "The sum of the weights specified on variants of the enum you are \
655     deriving `Arbitrary` for overflows an `u32` which it can't do."
656);
657
658// Happens when `#[proptest(regex..)]` is malformed.
659// For example, `#[proptest(regex = 1)]` is not a valid form.
660error!(
661    regex_malformed,
662    E0034,
663    "The attribute modifier `regex` inside `#[proptest(..)]` must have the \
664    format `#[proptest(regex = \"<string>\")]` where `<string>` is a valid
665    regular expression embedded in a Rust string slice."
666);
667
668// Happens when `#[proptest(params = <type>)]` is set on `item` and then
669// `#[proptest(regex = "<string>")]` is also set. We reject this because
670// the params can't be used. TODO: reduce this to a warning once we can
671// emit warnings.
672error!(
673    cant_set_param_and_regex(item: &str),
674    E0035,
675    "Cannot set #[proptest(regex = \"<string>\")] and \
676     `#[proptest(params = <type>)]` on {0} because the latter is a logic bug \
677     since `params` cannot be used in `<string>`.",
678    item
679);