Bug 1888590 - Mark some subtests on trusted-types-event-handlers.html as failing...
[gecko.git] / third_party / rust / async-trait / src / lifetime.rs
bloba7babfb61b5b10a7dc0fa440c3a890ab40e73b10
1 use proc_macro2::{Span, TokenStream};
2 use std::mem;
3 use syn::visit_mut::{self, VisitMut};
4 use syn::{
5     parse_quote_spanned, token, Expr, GenericArgument, Lifetime, Receiver, ReturnType, Token, Type,
6     TypeBareFn, TypeImplTrait, TypeParen, TypePtr, TypeReference,
7 };
9 pub struct CollectLifetimes {
10     pub elided: Vec<Lifetime>,
11     pub explicit: Vec<Lifetime>,
14 impl CollectLifetimes {
15     pub fn new() -> Self {
16         CollectLifetimes {
17             elided: Vec::new(),
18             explicit: Vec::new(),
19         }
20     }
22     fn visit_opt_lifetime(&mut self, reference: Token![&], lifetime: &mut Option<Lifetime>) {
23         match lifetime {
24             None => *lifetime = Some(self.next_lifetime(reference.span)),
25             Some(lifetime) => self.visit_lifetime(lifetime),
26         }
27     }
29     fn visit_lifetime(&mut self, lifetime: &mut Lifetime) {
30         if lifetime.ident == "_" {
31             *lifetime = self.next_lifetime(lifetime.span());
32         } else {
33             self.explicit.push(lifetime.clone());
34         }
35     }
37     fn next_lifetime(&mut self, span: Span) -> Lifetime {
38         let name = format!("'life{}", self.elided.len());
39         let life = Lifetime::new(&name, span);
40         self.elided.push(life.clone());
41         life
42     }
45 impl VisitMut for CollectLifetimes {
46     fn visit_receiver_mut(&mut self, arg: &mut Receiver) {
47         if let Some((reference, lifetime)) = &mut arg.reference {
48             self.visit_opt_lifetime(*reference, lifetime);
49         } else {
50             visit_mut::visit_type_mut(self, &mut arg.ty);
51         }
52     }
54     fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) {
55         self.visit_opt_lifetime(ty.and_token, &mut ty.lifetime);
56         visit_mut::visit_type_reference_mut(self, ty);
57     }
59     fn visit_generic_argument_mut(&mut self, gen: &mut GenericArgument) {
60         if let GenericArgument::Lifetime(lifetime) = gen {
61             self.visit_lifetime(lifetime);
62         }
63         visit_mut::visit_generic_argument_mut(self, gen);
64     }
67 pub struct AddLifetimeToImplTrait;
69 impl VisitMut for AddLifetimeToImplTrait {
70     fn visit_type_impl_trait_mut(&mut self, ty: &mut TypeImplTrait) {
71         let span = ty.impl_token.span;
72         let lifetime = parse_quote_spanned!(span=> 'async_trait);
73         ty.bounds.insert(0, lifetime);
74         if let Some(punct) = ty.bounds.pairs_mut().next().unwrap().punct_mut() {
75             punct.span = span;
76         }
77         visit_mut::visit_type_impl_trait_mut(self, ty);
78     }
80     fn visit_type_reference_mut(&mut self, ty: &mut TypeReference) {
81         parenthesize_impl_trait(&mut ty.elem, ty.and_token.span);
82         visit_mut::visit_type_reference_mut(self, ty);
83     }
85     fn visit_type_ptr_mut(&mut self, ty: &mut TypePtr) {
86         parenthesize_impl_trait(&mut ty.elem, ty.star_token.span);
87         visit_mut::visit_type_ptr_mut(self, ty);
88     }
90     fn visit_type_bare_fn_mut(&mut self, ty: &mut TypeBareFn) {
91         if let ReturnType::Type(arrow, return_type) = &mut ty.output {
92             parenthesize_impl_trait(return_type, arrow.spans[0]);
93         }
94         visit_mut::visit_type_bare_fn_mut(self, ty);
95     }
97     fn visit_expr_mut(&mut self, _e: &mut Expr) {
98         // Do not recurse into impl Traits inside of an array length expression.
99         //
100         //    fn outer(arg: [u8; { fn inner(_: impl Trait) {}; 0 }]);
101     }
104 fn parenthesize_impl_trait(elem: &mut Type, paren_span: Span) {
105     if let Type::ImplTrait(_) = *elem {
106         let placeholder = Type::Verbatim(TokenStream::new());
107         *elem = Type::Paren(TypeParen {
108             paren_token: token::Paren(paren_span),
109             elem: Box::new(mem::replace(elem, placeholder)),
110         });
111     }