use_existing_destructuring
v0.4.0 Warning Fix Pattern Matching
This rule flags user.email when a destructuring of user already exists earlier in the same scope. The property belongs in that pattern; the quick fix adds it there and rewrites the access to the new variable.
Why use this rule
Section titled “Why use this rule”Once a destructuring exists, it is the place a reader looks to see what this function uses from the object. A property read that bypasses it hides one field from that list, and the next person adding a field has to decide, for no reason, which of the two styles to follow.
See also: Dart patterns
class Session { const Session({ required this.userId, required this.token, required this.expiresAt, });
final String userId; final String token; final DateTime expiresAt;}
void audit(Session session) { final Session(:userId) = session;
print(userId); print(session.token); // LINT: add :token to the destructuring print(session.expiresAt); // LINT: add :expiresAt too}void audit(Session session) { final Session(:userId, :token, :expiresAt) = session;
print(userId); print(token); print(expiresAt);}Records too
Section titled “Records too”The same applies to a record destructuring:
// Don'tvoid describe(({int width, int height}) size) { final (:width) = size; print('$width x ${size.height}'); // LINT}
// Dovoid describe(({int width, int height}) size) { final (:width, :height) = size; print('$width x $height');}Known limitations
Section titled “Known limitations”The rule reports only where adding the field to the pattern would be a behaviour-preserving edit. It stays silent when:
No destructuring exists. Plain session.token in a function that never destructures session is fine — this rule does not ask you to start.
The access comes first. A read above the destructuring cannot use a variable that is not bound yet.
It is a method call, not a property. session.refresh() is a call; patterns bind fields and getters, not invocations.
It is an assignment target. session.token = 'x' writes through the object, which a destructured copy cannot do.
The receiver is not a local variable. A top-level or field object (globalSession.token), or a call result (currentSession().token), is left alone.
The access is inside a closure. A property read inside a () { ... } runs later, so the rule treats it as a separate context.
A different variable is being read. final Session(:userId) = a; print(b.token); touches two objects and is not reported.
Configuration
Section titled “Configuration”This rule is in the opinionated preset, so it is on with
preset: opinionated, or by name:
rules: use_existing_destructuring: trueTo turn it off again:
rules: use_existing_destructuring: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”avoid_single_field_destructuring— Avoid destructuring a single field when direct property access is simpler.use_existing_variable— Use an existing variable instead of repeating its initializer expression.avoid_wildcard_cases_with_enums— Keep exhaustiveness checking by listing enum cases explicitly.prefer_switch_with_enums— Use a switch instead of an if-else chain over enum constants.