diff options
| author | Noah Lev <camelidcamel@gmail.com> | 2024-07-31 17:17:14 -0700 |
|---|---|---|
| committer | Noah Lev <camelidcamel@gmail.com> | 2024-08-04 12:49:28 -0700 |
| commit | e452e3def69deca6a671b6067b1faf14b4cf83f2 (patch) | |
| tree | 13e4627fdc55dcb459b67636803254698aa3678f /src | |
| parent | 4e348fa803723a38553138d9795cb2c6b7fb964a (diff) | |
| download | rust-e452e3def69deca6a671b6067b1faf14b4cf83f2.tar.gz rust-e452e3def69deca6a671b6067b1faf14b4cf83f2.zip | |
Use `match` instead of sequence of `if let`s
This is much more readable and idiomatic, and also may help performance since `match`es usually use switches while `if`s may not. I also fixed an incorrect comment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/html/render/search_index.rs | 477 |
1 files changed, 243 insertions, 234 deletions
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index e4d948b8c9c..8a2f31f7413 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -854,34 +854,70 @@ fn simplify_fn_type<'tcx, 'a>( // If this argument is a type parameter and not a trait bound or a type, we need to look // for its bounds. - if let Type::Generic(arg_s) = *arg { - // First we check if the bounds are in a `where` predicate... - let mut type_bounds = Vec::new(); - for where_pred in generics.where_predicates.iter().filter(|g| match g { - WherePredicate::BoundPredicate { ty, .. } => *ty == *arg, - _ => false, - }) { - let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]); - for bound in bounds.iter() { - if let Some(path) = bound.get_trait_path() { - let ty = Type::Path { path }; - simplify_fn_type( - self_, - generics, - &ty, - tcx, - recurse + 1, - &mut type_bounds, - rgen, - is_return, - cache, - ); + match *arg { + Type::Generic(arg_s) => { + // First we check if the bounds are in a `where` predicate... + let mut type_bounds = Vec::new(); + for where_pred in generics.where_predicates.iter().filter(|g| match g { + WherePredicate::BoundPredicate { ty, .. } => *ty == *arg, + _ => false, + }) { + let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]); + for bound in bounds.iter() { + if let Some(path) = bound.get_trait_path() { + let ty = Type::Path { path }; + simplify_fn_type( + self_, + generics, + &ty, + tcx, + recurse + 1, + &mut type_bounds, + rgen, + is_return, + cache, + ); + } + } + } + // Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`... + if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) { + for bound in bound.get_bounds().unwrap_or(&[]) { + if let Some(path) = bound.get_trait_path() { + let ty = Type::Path { path }; + simplify_fn_type( + self_, + generics, + &ty, + tcx, + recurse + 1, + &mut type_bounds, + rgen, + is_return, + cache, + ); + } } } + if let Some((idx, _)) = rgen.get(&SimplifiedParam::Symbol(arg_s)) { + res.push(RenderType { + id: Some(RenderTypeId::Index(*idx)), + generics: None, + bindings: None, + }); + } else { + let idx = -isize::try_from(rgen.len() + 1).unwrap(); + rgen.insert(SimplifiedParam::Symbol(arg_s), (idx, type_bounds)); + res.push(RenderType { + id: Some(RenderTypeId::Index(idx)), + generics: None, + bindings: None, + }); + } } - // Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`... - if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) { - for bound in bound.get_bounds().unwrap_or(&[]) { + Type::ImplTrait(ref bounds) => { + let mut type_bounds = Vec::new(); + for bound in bounds { if let Some(path) = bound.get_trait_path() { let ty = Type::Path { path }; simplify_fn_type( @@ -897,84 +933,22 @@ fn simplify_fn_type<'tcx, 'a>( ); } } - } - if let Some((idx, _)) = rgen.get(&SimplifiedParam::Symbol(arg_s)) { - res.push(RenderType { - id: Some(RenderTypeId::Index(*idx)), - generics: None, - bindings: None, - }); - } else { - let idx = -isize::try_from(rgen.len() + 1).unwrap(); - rgen.insert(SimplifiedParam::Symbol(arg_s), (idx, type_bounds)); - res.push(RenderType { - id: Some(RenderTypeId::Index(idx)), - generics: None, - bindings: None, - }); - } - } else if let Type::ImplTrait(ref bounds) = *arg { - let mut type_bounds = Vec::new(); - for bound in bounds { - if let Some(path) = bound.get_trait_path() { - let ty = Type::Path { path }; - simplify_fn_type( - self_, - generics, - &ty, - tcx, - recurse + 1, - &mut type_bounds, - rgen, - is_return, - cache, - ); + if is_return && !type_bounds.is_empty() { + // In return position, `impl Trait` is a unique thing. + res.push(RenderType { id: None, generics: Some(type_bounds), bindings: None }); + } else { + // In parameter position, `impl Trait` is the same as an unnamed generic parameter. + let idx = -isize::try_from(rgen.len() + 1).unwrap(); + rgen.insert(SimplifiedParam::Anonymous(idx), (idx, type_bounds)); + res.push(RenderType { + id: Some(RenderTypeId::Index(idx)), + generics: None, + bindings: None, + }); } } - if is_return && !type_bounds.is_empty() { - // In parameter position, `impl Trait` is a unique thing. - res.push(RenderType { id: None, generics: Some(type_bounds), bindings: None }); - } else { - // In parameter position, `impl Trait` is the same as an unnamed generic parameter. - let idx = -isize::try_from(rgen.len() + 1).unwrap(); - rgen.insert(SimplifiedParam::Anonymous(idx), (idx, type_bounds)); - res.push(RenderType { - id: Some(RenderTypeId::Index(idx)), - generics: None, - bindings: None, - }); - } - } else if let Type::Slice(ref ty) = *arg { - let mut ty_generics = Vec::new(); - simplify_fn_type( - self_, - generics, - &ty, - tcx, - recurse + 1, - &mut ty_generics, - rgen, - is_return, - cache, - ); - res.push(get_index_type(arg, ty_generics, rgen)); - } else if let Type::Array(ref ty, _) = *arg { - let mut ty_generics = Vec::new(); - simplify_fn_type( - self_, - generics, - &ty, - tcx, - recurse + 1, - &mut ty_generics, - rgen, - is_return, - cache, - ); - res.push(get_index_type(arg, ty_generics, rgen)); - } else if let Type::Tuple(ref tys) = *arg { - let mut ty_generics = Vec::new(); - for ty in tys { + Type::Slice(ref ty) => { + let mut ty_generics = Vec::new(); simplify_fn_type( self_, generics, @@ -986,15 +960,14 @@ fn simplify_fn_type<'tcx, 'a>( is_return, cache, ); + res.push(get_index_type(arg, ty_generics, rgen)); } - res.push(get_index_type(arg, ty_generics, rgen)); - } else if let Type::BareFunction(ref bf) = *arg { - let mut ty_generics = Vec::new(); - for ty in bf.decl.inputs.values.iter().map(|arg| &arg.type_) { + Type::Array(ref ty, _) => { + let mut ty_generics = Vec::new(); simplify_fn_type( self_, generics, - ty, + &ty, tcx, recurse + 1, &mut ty_generics, @@ -1002,62 +975,11 @@ fn simplify_fn_type<'tcx, 'a>( is_return, cache, ); + res.push(get_index_type(arg, ty_generics, rgen)); } - // The search index, for simplicity's sake, represents fn pointers and closures - // the same way: as a tuple for the parameters, and an associated type for the - // return type. - let mut ty_output = Vec::new(); - simplify_fn_type( - self_, - generics, - &bf.decl.output, - tcx, - recurse + 1, - &mut ty_output, - rgen, - is_return, - cache, - ); - let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)]; - res.push(RenderType { - id: get_index_type_id(&arg, rgen), - bindings: Some(ty_bindings), - generics: Some(ty_generics), - }); - } else if let Type::BorrowedRef { lifetime: _, mutability, ref type_ } = *arg { - let mut ty_generics = Vec::new(); - if mutability.is_mut() { - ty_generics.push(RenderType { - id: Some(RenderTypeId::Mut), - generics: None, - bindings: None, - }); - } - simplify_fn_type( - self_, - generics, - &type_, - tcx, - recurse + 1, - &mut ty_generics, - rgen, - is_return, - cache, - ); - res.push(get_index_type(arg, ty_generics, rgen)); - } else { - // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're - // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't. - // - // So in here, we can add it directly and look for its own type parameters (so for `Option`, - // we will look for them but not for `T`). - let mut ty_generics = Vec::new(); - let mut ty_constraints = Vec::new(); - if let Some(arg_generics) = arg.generic_args() { - for ty in arg_generics.into_iter().filter_map(|param| match param { - clean::GenericArg::Type(ty) => Some(ty), - _ => None, - }) { + Type::Tuple(ref tys) => { + let mut ty_generics = Vec::new(); + for ty in tys { simplify_fn_type( self_, generics, @@ -1070,94 +992,181 @@ fn simplify_fn_type<'tcx, 'a>( cache, ); } - for constraint in arg_generics.constraints() { - simplify_fn_constraint( + res.push(get_index_type(arg, ty_generics, rgen)); + } + Type::BareFunction(ref bf) => { + let mut ty_generics = Vec::new(); + for ty in bf.decl.inputs.values.iter().map(|arg| &arg.type_) { + simplify_fn_type( self_, generics, - &constraint, + ty, tcx, recurse + 1, - &mut ty_constraints, + &mut ty_generics, rgen, is_return, cache, ); } + // The search index, for simplicity's sake, represents fn pointers and closures + // the same way: as a tuple for the parameters, and an associated type for the + // return type. + let mut ty_output = Vec::new(); + simplify_fn_type( + self_, + generics, + &bf.decl.output, + tcx, + recurse + 1, + &mut ty_output, + rgen, + is_return, + cache, + ); + let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)]; + res.push(RenderType { + id: get_index_type_id(&arg, rgen), + bindings: Some(ty_bindings), + generics: Some(ty_generics), + }); } - // Every trait associated type on self gets assigned to a type parameter index - // this same one is used later for any appearances of these types - // - // for example, Iterator::next is: - // - // trait Iterator { - // fn next(&mut self) -> Option<Self::Item> - // } - // - // Self is technically just Iterator, but we want to pretend it's more like this: - // - // fn next<T>(self: Iterator<Item=T>) -> Option<T> - if is_self - && let Type::Path { path } = arg - && let def_id = path.def_id() - && let Some(trait_) = cache.traits.get(&def_id) - && trait_.items.iter().any(|at| at.is_ty_associated_type()) - { - for assoc_ty in &trait_.items { - if let clean::ItemKind::TyAssocTypeItem(_generics, bounds) = &*assoc_ty.kind - && let Some(name) = assoc_ty.name - { - let idx = -isize::try_from(rgen.len() + 1).unwrap(); - let (idx, stored_bounds) = rgen - .entry(SimplifiedParam::AssociatedType(def_id, name)) - .or_insert_with(|| (idx, Vec::new())); - let idx = *idx; - if stored_bounds.is_empty() { - // Can't just pass stored_bounds to simplify_fn_type, - // because it also accepts rgen as a parameter. - // Instead, have it fill in this local, then copy it into the map afterward. - let mut type_bounds = Vec::new(); - for bound in bounds { - if let Some(path) = bound.get_trait_path() { - let ty = Type::Path { path }; - simplify_fn_type( - self_, - generics, - &ty, - tcx, - recurse + 1, - &mut type_bounds, - rgen, - is_return, - cache, - ); - } - } - let stored_bounds = &mut rgen - .get_mut(&SimplifiedParam::AssociatedType(def_id, name)) - .unwrap() - .1; + Type::BorrowedRef { lifetime: _, mutability, ref type_ } => { + let mut ty_generics = Vec::new(); + if mutability.is_mut() { + ty_generics.push(RenderType { + id: Some(RenderTypeId::Mut), + generics: None, + bindings: None, + }); + } + simplify_fn_type( + self_, + generics, + &type_, + tcx, + recurse + 1, + &mut ty_generics, + rgen, + is_return, + cache, + ); + res.push(get_index_type(arg, ty_generics, rgen)); + } + _ => { + // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're + // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't. + // + // So in here, we can add it directly and look for its own type parameters (so for `Option`, + // we will look for them but not for `T`). + let mut ty_generics = Vec::new(); + let mut ty_constraints = Vec::new(); + if let Some(arg_generics) = arg.generic_args() { + for ty in arg_generics.into_iter().filter_map(|param| match param { + clean::GenericArg::Type(ty) => Some(ty), + _ => None, + }) { + simplify_fn_type( + self_, + generics, + &ty, + tcx, + recurse + 1, + &mut ty_generics, + rgen, + is_return, + cache, + ); + } + for constraint in arg_generics.constraints() { + simplify_fn_constraint( + self_, + generics, + &constraint, + tcx, + recurse + 1, + &mut ty_constraints, + rgen, + is_return, + cache, + ); + } + } + // Every trait associated type on self gets assigned to a type parameter index + // this same one is used later for any appearances of these types + // + // for example, Iterator::next is: + // + // trait Iterator { + // fn next(&mut self) -> Option<Self::Item> + // } + // + // Self is technically just Iterator, but we want to pretend it's more like this: + // + // fn next<T>(self: Iterator<Item=T>) -> Option<T> + if is_self + && let Type::Path { path } = arg + && let def_id = path.def_id() + && let Some(trait_) = cache.traits.get(&def_id) + && trait_.items.iter().any(|at| at.is_ty_associated_type()) + { + for assoc_ty in &trait_.items { + if let clean::ItemKind::TyAssocTypeItem(_generics, bounds) = &*assoc_ty.kind + && let Some(name) = assoc_ty.name + { + let idx = -isize::try_from(rgen.len() + 1).unwrap(); + let (idx, stored_bounds) = rgen + .entry(SimplifiedParam::AssociatedType(def_id, name)) + .or_insert_with(|| (idx, Vec::new())); + let idx = *idx; if stored_bounds.is_empty() { - *stored_bounds = type_bounds; + // Can't just pass stored_bounds to simplify_fn_type, + // because it also accepts rgen as a parameter. + // Instead, have it fill in this local, then copy it into the map afterward. + let mut type_bounds = Vec::new(); + for bound in bounds { + if let Some(path) = bound.get_trait_path() { + let ty = Type::Path { path }; + simplify_fn_type( + self_, + generics, + &ty, + tcx, + recurse + 1, + &mut type_bounds, + rgen, + is_return, + cache, + ); + } + } + let stored_bounds = &mut rgen + .get_mut(&SimplifiedParam::AssociatedType(def_id, name)) + .unwrap() + .1; + if stored_bounds.is_empty() { + *stored_bounds = type_bounds; + } } + ty_constraints.push(( + RenderTypeId::AssociatedType(name), + vec![RenderType { + id: Some(RenderTypeId::Index(idx)), + generics: None, + bindings: None, + }], + )) } - ty_constraints.push(( - RenderTypeId::AssociatedType(name), - vec![RenderType { - id: Some(RenderTypeId::Index(idx)), - generics: None, - bindings: None, - }], - )) } } - } - let id = get_index_type_id(&arg, rgen); - if id.is_some() || !ty_generics.is_empty() { - res.push(RenderType { - id, - bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) }, - generics: if ty_generics.is_empty() { None } else { Some(ty_generics) }, - }); + let id = get_index_type_id(&arg, rgen); + if id.is_some() || !ty_generics.is_empty() { + res.push(RenderType { + id, + bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) }, + generics: if ty_generics.is_empty() { None } else { Some(ty_generics) }, + }); + } } } } |
