]> git.lizzy.rs Git - rust.git/commitdiff
Refactor `GenericArgs` to include const generics
authorvarkor <github@varkor.com>
Wed, 13 Mar 2019 23:39:56 +0000 (23:39 +0000)
committervarkor <github@varkor.com>
Mon, 18 Mar 2019 19:44:51 +0000 (19:44 +0000)
Co-Authored-By: Gabriel Smith <yodaldevoid@users.noreply.github.com>
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs

index 23b5794fb1eef45e331171e02b20c1b5488cd12b..adbe73b165ef4b812901be583e908b104929ab90 100644 (file)
@@ -444,7 +444,13 @@ fn make_final_bounds<'b, 'c, 'cx>(
                                                                 .expect("segments were empty");
 
                             let (old_input, old_output) = match last_segment.args {
-                                GenericArgs::AngleBracketed { types, .. } => (types, None),
+                                GenericArgs::AngleBracketed { args, .. } => {
+                                    let types = args.iter().filter_map(|arg| match arg {
+                                        GenericArg::Type(ty) => Some(ty.clone()),
+                                        _ => None,
+                                    }).collect();
+                                    (types, None)
+                                }
                                 GenericArgs::Parenthesized { inputs, output, .. } => {
                                     (inputs, output)
                                 }
index 8581c40c843e86bd72be8ac5dd786a5f1f76d483..50210bcb85d56575016bb828ce6c9b4ae50f1a12 100644 (file)
@@ -21,7 +21,7 @@
 use rustc::hir::def::{self, Def, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::hir::map::DisambiguatedDefPathData;
-use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef};
+use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
 use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
 use rustc::ty::fold::TypeFolder;
 use rustc::ty::layout::VariantIdx;
@@ -1089,24 +1089,37 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
     }
 }
 
-fn external_generic_args(cx: &DocContext<'_>, trait_did: Option<DefId>, has_self: bool,
-                        bindings: Vec<TypeBinding>, substs: SubstsRef<'_>) -> GenericArgs {
-    let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
-    let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
+fn external_generic_args(
+    cx: &DocContext<'_>,
+    trait_did: Option<DefId>,
+    has_self: bool,
+    bindings: Vec<TypeBinding>,
+    substs: SubstsRef<'_>,
+) -> GenericArgs {
+    let mut skip_self = has_self;
+    let mut first_ty_sty = None;
+    let args: Vec<_> = substs.iter().filter_map(|kind| match kind.unpack() {
+        UnpackedKind::Lifetime(lt) => {
+            lt.clean(cx).and_then(|lt| Some(GenericArg::Lifetime(lt)))
+        }
+        UnpackedKind::Type(_) if skip_self => {
+            skip_self = false;
+            None
+        }
+        UnpackedKind::Type(ty) => {
+            first_ty_sty = Some(&ty.sty);
+            Some(GenericArg::Type(ty.clean(cx)))
+        }
+        UnpackedKind::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
+    }).collect();
 
     match trait_did {
         // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
         Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
-            assert_eq!(types.len(), 1);
-            let inputs = match types[0].sty {
-                ty::Tuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(),
-                _ => {
-                    return GenericArgs::AngleBracketed {
-                        lifetimes,
-                        types: types.clean(cx),
-                        bindings,
-                    }
-                }
+            assert!(first_ty_sty.is_some());
+            let inputs = match first_ty_sty {
+                Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.clean(cx)).collect(),
+                _ => return GenericArgs::AngleBracketed { args, bindings },
             };
             let output = None;
             // FIXME(#20299) return type comes from a projection now
@@ -1114,17 +1127,10 @@ fn external_generic_args(cx: &DocContext<'_>, trait_did: Option<DefId>, has_self
             //     ty::Tuple(ref v) if v.is_empty() => None, // -> ()
             //     _ => Some(types[1].clean(cx))
             // };
-            GenericArgs::Parenthesized {
-                inputs,
-                output,
-            }
+            GenericArgs::Parenthesized { inputs, output }
         },
         _ => {
-            GenericArgs::AngleBracketed {
-                lifetimes,
-                types: types.clean(cx),
-                bindings,
-            }
+            GenericArgs::AngleBracketed { args, bindings }
         }
     }
 }
@@ -1462,7 +1468,7 @@ pub fn is_synthetic_type_param(&self) -> bool {
     }
 }
 
-impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
+impl Clean<GenericParamDef> for ty::GenericParamDef {
     fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
         let (name, kind) = match self.kind {
             ty::GenericParamDefKind::Lifetime => {
@@ -1484,7 +1490,10 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
                 })
             }
             ty::GenericParamDefKind::Const { .. } => {
-                unimplemented!() // FIXME(const_generics)
+                (self.name.clean(cx), GenericParamDefKind::Const {
+                    did: self.def_id,
+                    ty: cx.tcx.type_of(self.def_id).clean(cx),
+                })
             }
         };
 
@@ -1685,9 +1694,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Generics {
                         .flat_map(|param| match param.kind {
                             ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
                             ty::GenericParamDefKind::Type { .. } => None,
-                            ty::GenericParamDefKind::Const { .. } => {
-                                unimplemented!() // FIXME(const_generics)
-                            }
+                            ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
                         }).chain(simplify::ty_params(stripped_typarams).into_iter())
                         .collect(),
             where_predicates: simplify::where_clauses(cx, where_predicates),
@@ -2365,12 +2372,15 @@ pub fn is_self_type(&self) -> bool {
         }
     }
 
-    pub fn generics(&self) -> Option<&[Type]> {
+    pub fn generics(&self) -> Option<Vec<Type>> {
         match *self {
             ResolvedPath { ref path, .. } => {
                 path.segments.last().and_then(|seg| {
-                    if let GenericArgs::AngleBracketed { ref types, .. } = seg.args {
-                        Some(&**types)
+                    if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
+                        Some(args.iter().filter_map(|arg| match arg {
+                            GenericArg::Type(ty) => Some(ty.clone()),
+                            _ => None,
+                        }).collect())
                     } else {
                         None
                     }
@@ -3267,8 +3277,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
 pub enum GenericArgs {
     AngleBracketed {
-        lifetimes: Vec<Lifetime>,
-        types: Vec<Type>,
+        args: Vec<GenericArg>,
         bindings: Vec<TypeBinding>,
     },
     Parenthesized {
@@ -3286,27 +3295,19 @@ fn clean(&self, cx: &DocContext<'_>) -> GenericArgs {
                 output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
             }
         } else {
-            let (mut lifetimes, mut types) = (vec![], vec![]);
-            let mut elided_lifetimes = true;
-            for arg in &self.args {
-                match arg {
-                    GenericArg::Lifetime(lt) => {
-                        if !lt.is_elided() {
-                            elided_lifetimes = false;
-                        }
-                        lifetimes.push(lt.clean(cx));
-                    }
-                    GenericArg::Type(ty) => {
-                        types.push(ty.clean(cx));
-                    }
-                    GenericArg::Const(..) => {
-                        unimplemented!() // FIXME(const_generics)
-                    }
-                }
-            }
+            let elide_lifetimes = self.args.iter().all(|arg| match arg {
+                hir::GenericArg::Lifetime(lt) => lt.is_elided(),
+                _ => true,
+            });
             GenericArgs::AngleBracketed {
-                lifetimes: if elided_lifetimes { vec![] } else { lifetimes },
-                types,
+                args: self.args.iter().filter_map(|arg| match arg {
+                    hir::GenericArg::Lifetime(lt) if !elide_lifetimes => {
+                        Some(GenericArg::Lifetime(lt.clean(cx)))
+                    }
+                    hir::GenericArg::Lifetime(_) => None,
+                    hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
+                    hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
+                }).collect(),
                 bindings: self.bindings.clean(cx),
             }
         }
@@ -3358,9 +3359,8 @@ fn strip_path(path: &Path) -> Path {
         PathSegment {
             name: s.name.clone(),
             args: GenericArgs::AngleBracketed {
-                lifetimes: Vec::new(),
-                types: Vec::new(),
-                bindings: Vec::new(),
+                args: vec![],
+                bindings: vec![],
             }
         }
     }).collect();
@@ -3511,7 +3511,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub struct Constant {
     pub type_: Type,
     pub expr: String,
index 2cba3c58889abc607768b26ebba1b4abe2d17fe3..116839edc2f80f032534068aa2c6c97db2ad4064 100644 (file)
@@ -306,32 +306,23 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 impl fmt::Display for clean::GenericArgs {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            clean::GenericArgs::AngleBracketed {
-                ref lifetimes, ref types, ref bindings
-            } => {
-                if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
+            clean::GenericArgs::AngleBracketed { ref args, ref bindings } => {
+            if !args.is_empty() || !bindings.is_empty() {
                     if f.alternate() {
                         f.write_str("<")?;
                     } else {
                         f.write_str("&lt;")?;
                     }
                     let mut comma = false;
-                    for lifetime in lifetimes {
-                        if comma {
-                            f.write_str(", ")?;
-                        }
-                        comma = true;
-                        write!(f, "{}", *lifetime)?;
-                    }
-                    for ty in types {
+                    for arg in args {
                         if comma {
                             f.write_str(", ")?;
                         }
                         comma = true;
                         if f.alternate() {
-                            write!(f, "{:#}", *ty)?;
+                            write!(f, "{:#}", *arg)?;
                         } else {
-                            write!(f, "{}", *ty)?;
+                            write!(f, "{}", *arg)?;
                         }
                     }
                     for binding in bindings {