Skip to content

Commit

Permalink
Merge pull request #194 from dtolnay/parambounds
Browse files Browse the repository at this point in the history
Move bounds from generic param list to where-clause after 'async_trait bound
  • Loading branch information
dtolnay authored Mar 25, 2022
2 parents 0b31ad9 + 46c3023 commit e572d92
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 21 deletions.
51 changes: 32 additions & 19 deletions src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
use proc_macro2::TokenStream;
use quote::{format_ident, quote, quote_spanned, ToTokens};
use std::collections::BTreeSet as Set;
use std::mem;
use syn::punctuated::Punctuated;
use syn::visit_mut::{self, VisitMut};
use syn::{
parse_quote, parse_quote_spanned, Attribute, Block, FnArg, GenericParam, Generics, Ident,
ImplItem, Lifetime, Pat, PatIdent, Receiver, ReturnType, Signature, Stmt, Token, TraitItem,
Type, TypeParamBound, TypePath, WhereClause,
ImplItem, Lifetime, LifetimeDef, Pat, PatIdent, Receiver, ReturnType, Signature, Stmt, Token,
TraitItem, Type, TypeParamBound, TypePath, WhereClause,
};

impl ToTokens for Item {
Expand All @@ -34,17 +35,18 @@ enum Context<'a> {
}

impl Context<'_> {
fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator<Item = &'a GenericParam> {
fn lifetimes<'a>(&'a self, used: &'a [Lifetime]) -> impl Iterator<Item = &'a LifetimeDef> {
let generics = match self {
Context::Trait { generics, .. } => generics,
Context::Impl { impl_generics, .. } => impl_generics,
};
generics.params.iter().filter(move |param| {
generics.params.iter().filter_map(move |param| {
if let GenericParam::Lifetime(param) = param {
used.contains(&param.lifetime)
} else {
false
if used.contains(&param.lifetime) {
return Some(param);
}
}
None
})
}
}
Expand Down Expand Up @@ -178,31 +180,42 @@ fn transform_sig(
}
}

for param in sig
.generics
.params
.iter()
.chain(context.lifetimes(&lifetimes.explicit))
{
for param in &mut sig.generics.params {
match param {
GenericParam::Type(param) => {
let param = &param.ident;
let span = param.span();
let param_name = &param.ident;
let span = match param.colon_token.take() {
Some(colon_token) => colon_token.span,
None => param_name.span(),
};
let bounds = mem::replace(&mut param.bounds, Punctuated::new());
where_clause_or_default(&mut sig.generics.where_clause)
.predicates
.push(parse_quote_spanned!(span=> #param: 'async_trait));
.push(parse_quote_spanned!(span=> #param_name: 'async_trait + #bounds));
}
GenericParam::Lifetime(param) => {
let param = &param.lifetime;
let span = param.span();
let param_name = &param.lifetime;
let span = match param.colon_token.take() {
Some(colon_token) => colon_token.span,
None => param_name.span(),
};
let bounds = mem::replace(&mut param.bounds, Punctuated::new());
where_clause_or_default(&mut sig.generics.where_clause)
.predicates
.push(parse_quote_spanned!(span=> #param: 'async_trait));
.push(parse_quote_spanned!(span=> #param: 'async_trait + #bounds));
}
GenericParam::Const(_) => {}
}
}

for param in context.lifetimes(&lifetimes.explicit) {
let param = &param.lifetime;
let span = param.span();
where_clause_or_default(&mut sig.generics.where_clause)
.predicates
.push(parse_quote_spanned!(span=> #param: 'async_trait));
}

if sig.generics.lt_token.is_none() {
sig.generics.lt_token = Some(Token![<](sig.ident.span()));
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/consider-restricting.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ note: captured value is not `Send`
= note: required for the cast to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting this bound
|
16 | async fn publish<T + std::marker::Send: IntoUrl>(&self, url: T) {}
| +++++++++++++++++++
16 | async fn publish<T: IntoUrl + std::marker::Send>(&self, url: T) {}
| +++++++++++++++++++

error: future cannot be sent between threads safely
--> tests/ui/consider-restricting.rs:23:40
Expand Down

0 comments on commit e572d92

Please sign in to comment.