about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-12 11:42:58 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-19 21:16:04 +0300
commit887feeeaf7d40c25caa9532f2d9121cb79fca899 (patch)
treeb1078b39f5eb7198125a384abe44cfa26eb97bc8
parente79b2a18a21e6b178d73473bb8fdbf3d18c66051 (diff)
downloadrust-887feeeaf7d40c25caa9532f2d9121cb79fca899.tar.gz
rust-887feeeaf7d40c25caa9532f2d9121cb79fca899.zip
rustc: replace `GenericArgs::with_generic_args` hack with a plain getter.
-rw-r--r--src/librustc/hir/mod.rs18
-rw-r--r--src/librustc/hir/print.rs49
-rw-r--r--src/librustc_typeck/astconv.rs106
-rw-r--r--src/librustdoc/clean/mod.rs7
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/ptr.rs11
6 files changed, 91 insertions, 102 deletions
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 527f18f57dc..de8c75345fe 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -383,17 +383,13 @@ impl PathSegment {
         }
     }
 
-    // FIXME: hack required because you can't create a static
-    // `GenericArgs`, so you can't just return a `&GenericArgs`.
-    pub fn with_generic_args<F, R>(&self, f: F) -> R
-        where F: FnOnce(&GenericArgs) -> R
-    {
-        let dummy = GenericArgs::none();
-        f(if let Some(ref args) = self.args {
-            &args
+    pub fn generic_args(&self) -> &GenericArgs {
+        if let Some(ref args) = self.args {
+            args
         } else {
-            &dummy
-        })
+            const DUMMY: &GenericArgs = &GenericArgs::none();
+            DUMMY
+        }
     }
 }
 
@@ -449,7 +445,7 @@ pub struct GenericArgs {
 }
 
 impl GenericArgs {
-    pub fn none() -> Self {
+    pub const fn none() -> Self {
         Self {
             args: HirVec::new(),
             bindings: HirVec::new(),
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index e1c713b537c..8111ac44a87 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1194,12 +1194,11 @@ impl<'a> State<'a> {
         self.s.word(".")?;
         self.print_ident(segment.ident)?;
 
-        segment.with_generic_args(|generic_args| {
-            if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
-                return self.print_generic_args(&generic_args, segment.infer_args, true);
-            }
-            Ok(())
-        })?;
+        let generic_args = segment.generic_args();
+        if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
+            self.print_generic_args(generic_args, segment.infer_args, true)?;
+        }
+
         self.print_call_post(base_args)
     }
 
@@ -1559,11 +1558,9 @@ impl<'a> State<'a> {
                 self.s.word("::")?
             }
             if segment.ident.name != kw::PathRoot {
-               self.print_ident(segment.ident)?;
-               segment.with_generic_args(|generic_args| {
-                   self.print_generic_args(generic_args, segment.infer_args,
-                                           colons_before_params)
-               })?;
+                self.print_ident(segment.ident)?;
+                self.print_generic_args(segment.generic_args(), segment.infer_args,
+                                        colons_before_params)?;
             }
         }
 
@@ -1572,10 +1569,8 @@ impl<'a> State<'a> {
 
     pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> {
         if segment.ident.name != kw::PathRoot {
-           self.print_ident(segment.ident)?;
-           segment.with_generic_args(|generic_args| {
-               self.print_generic_args(generic_args, segment.infer_args, false)
-           })?;
+            self.print_ident(segment.ident)?;
+            self.print_generic_args(segment.generic_args(), segment.infer_args, false)?;
         }
         Ok(())
     }
@@ -1600,11 +1595,9 @@ impl<'a> State<'a> {
                     }
                     if segment.ident.name != kw::PathRoot {
                         self.print_ident(segment.ident)?;
-                        segment.with_generic_args(|generic_args| {
-                            self.print_generic_args(generic_args,
-                                                    segment.infer_args,
-                                                    colons_before_params)
-                        })?;
+                        self.print_generic_args(segment.generic_args(),
+                                                segment.infer_args,
+                                                colons_before_params)?;
                     }
                 }
 
@@ -1612,11 +1605,9 @@ impl<'a> State<'a> {
                 self.s.word("::")?;
                 let item_segment = path.segments.last().unwrap();
                 self.print_ident(item_segment.ident)?;
-                item_segment.with_generic_args(|generic_args| {
-                    self.print_generic_args(generic_args,
-                                            item_segment.infer_args,
-                                            colons_before_params)
-                })
+                self.print_generic_args(item_segment.generic_args(),
+                                        item_segment.infer_args,
+                                        colons_before_params)
             }
             hir::QPath::TypeRelative(ref qself, ref item_segment) => {
                 self.s.word("<")?;
@@ -1624,11 +1615,9 @@ impl<'a> State<'a> {
                 self.s.word(">")?;
                 self.s.word("::")?;
                 self.print_ident(item_segment.ident)?;
-                item_segment.with_generic_args(|generic_args| {
-                    self.print_generic_args(generic_args,
-                                            item_segment.infer_args,
-                                            colons_before_params)
-                })
+                self.print_generic_args(item_segment.generic_args(),
+                                        item_segment.infer_args,
+                                        colons_before_params)
             }
         }
     }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 8236cd1f738..b6d123c72ac 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -191,15 +191,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         item_segment: &hir::PathSegment)
         -> SubstsRef<'tcx>
     {
-        let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| {
-            self.create_substs_for_ast_path(
-                span,
-                def_id,
-                generic_args,
-                item_segment.infer_args,
-                None,
-            )
-        });
+        let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
+            span,
+            def_id,
+            item_segment.generic_args(),
+            item_segment.infer_args,
+            None,
+        );
 
         assoc_bindings.first().map(|b| Self::prohibit_assoc_ty_binding(self.tcx(), b.span));
 
@@ -874,8 +872,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let trait_def = self.tcx().trait_def(trait_def_id);
 
         if !self.tcx().features().unboxed_closures &&
-            trait_segment.with_generic_args(|generic_args| generic_args.parenthesized)
-            != trait_def.paren_sugar {
+            trait_segment.generic_args().parenthesized != trait_def.paren_sugar
+        {
             // For now, require that parenthetical notation be used only with `Fn()` etc.
             let msg = if trait_def.paren_sugar {
                 "the precise format of `Fn`-family traits' type parameters is subject to change. \
@@ -887,13 +885,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                              span, GateIssue::Language, msg);
         }
 
-        trait_segment.with_generic_args(|generic_args| {
-            self.create_substs_for_ast_path(span,
-                                            trait_def_id,
-                                            generic_args,
-                                            trait_segment.infer_args,
-                                            Some(self_ty))
-        })
+        self.create_substs_for_ast_path(span,
+                                        trait_def_id,
+                                        trait_segment.generic_args(),
+                                        trait_segment.infer_args,
+                                        Some(self_ty))
     }
 
     fn trait_defines_associated_type_named(&self,
@@ -1765,47 +1761,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             &self, segments: T) -> bool {
         let mut has_err = false;
         for segment in segments {
-            segment.with_generic_args(|generic_args| {
-                let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
-                for arg in &generic_args.args {
-                    let (span, kind) = match arg {
-                        hir::GenericArg::Lifetime(lt) => {
-                            if err_for_lt { continue }
-                            err_for_lt = true;
-                            has_err = true;
-                            (lt.span, "lifetime")
-                        }
-                        hir::GenericArg::Type(ty) => {
-                            if err_for_ty { continue }
-                            err_for_ty = true;
-                            has_err = true;
-                            (ty.span, "type")
-                        }
-                        hir::GenericArg::Const(ct) => {
-                            if err_for_ct { continue }
-                            err_for_ct = true;
-                            (ct.span, "const")
-                        }
-                    };
-                    let mut err = struct_span_err!(
-                        self.tcx().sess,
-                        span,
-                        E0109,
-                        "{} arguments are not allowed for this type",
-                        kind,
-                    );
-                    err.span_label(span, format!("{} argument not allowed", kind));
-                    err.emit();
-                    if err_for_lt && err_for_ty && err_for_ct {
-                        break;
+            let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
+            for arg in &segment.generic_args().args {
+                let (span, kind) = match arg {
+                    hir::GenericArg::Lifetime(lt) => {
+                        if err_for_lt { continue }
+                        err_for_lt = true;
+                        has_err = true;
+                        (lt.span, "lifetime")
                     }
-                }
-                for binding in &generic_args.bindings {
-                    has_err = true;
-                    Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
+                    hir::GenericArg::Type(ty) => {
+                        if err_for_ty { continue }
+                        err_for_ty = true;
+                        has_err = true;
+                        (ty.span, "type")
+                    }
+                    hir::GenericArg::Const(ct) => {
+                        if err_for_ct { continue }
+                        err_for_ct = true;
+                        (ct.span, "const")
+                    }
+                };
+                let mut err = struct_span_err!(
+                    self.tcx().sess,
+                    span,
+                    E0109,
+                    "{} arguments are not allowed for this type",
+                    kind,
+                );
+                err.span_label(span, format!("{} argument not allowed", kind));
+                err.emit();
+                if err_for_lt && err_for_ty && err_for_ct {
                     break;
                 }
-            })
+            }
+            for binding in &segment.generic_args().bindings {
+                has_err = true;
+                Self::prohibit_assoc_ty_binding(self.tcx(), binding.span);
+                break;
+            }
         }
         has_err
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 4becb42d305..9968118d2ec 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2809,7 +2809,8 @@ impl Clean<Type> for hir::Ty {
                     let mut ty_substs = FxHashMap::default();
                     let mut lt_substs = FxHashMap::default();
                     let mut ct_substs = FxHashMap::default();
-                    provided_params.with_generic_args(|generic_args| {
+                    let generic_args = provided_params.generic_args();
+                    {
                         let mut indices: GenericParamCount = Default::default();
                         for param in generics.params.iter() {
                             match param.kind {
@@ -2884,7 +2885,7 @@ impl Clean<Type> for hir::Ty {
                                 }
                             }
                         }
-                    });
+                    }
                     return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
                 }
                 resolve_type(cx, path.clean(cx), self.hir_id)
@@ -3537,7 +3538,7 @@ impl Clean<PathSegment> for hir::PathSegment {
     fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
         PathSegment {
             name: self.ident.name.clean(cx),
-            args: self.with_generic_args(|generic_args| generic_args.clean(cx))
+            args: self.generic_args().clean(cx),
         }
     }
 }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 55db8da3276..337b8424736 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -12,6 +12,8 @@
 #![deny(unused_lifetimes)]
 
 #![feature(bind_by_move_pattern_guards)]
+#![feature(const_fn)]
+#![feature(const_transmute)]
 #![feature(crate_visibility_modifier)]
 #![feature(label_break_value)]
 #![feature(nll)]
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index d577243fb3d..f0cfa5a84a8 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -133,8 +133,15 @@ impl<T: Encodable> Encodable for P<T> {
 }
 
 impl<T> P<[T]> {
-    pub fn new() -> P<[T]> {
-        P { ptr: Default::default() }
+    pub const fn new() -> P<[T]> {
+        // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>`
+        // (as trait methods, `default` in this case, can't be `const fn` yet).
+        P {
+            ptr: unsafe {
+                use std::ptr::NonNull;
+                std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>)
+            },
+        }
     }
 
     #[inline(never)]