about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-01 23:51:47 +0000
committerbors <bors@rust-lang.org>2015-09-01 23:51:47 +0000
commit7780408af6d59b6e0216ff1b4df1b1d3b31d9fac (patch)
tree88571cda13fafe5cb230fccc6eea64bd02cbc7c9
parent40c00e9c064f2e89ad9e5dbfc81c8a38bae717b8 (diff)
parent321f8d81b878da1ead6c73fb7877d494619ef284 (diff)
downloadrust-7780408af6d59b6e0216ff1b4df1b1d3b31d9fac.tar.gz
rust-7780408af6d59b6e0216ff1b4df1b1d3b31d9fac.zip
Auto merge of #28132 - arielb1:uninstantiable, r=nikomatsakis
It is *very* easy to bypass, and is a relic of a bygone age where the type-checker was *much* less robust.

Fixes #27497

r? @nikomatsakis 
-rw-r--r--src/librustc/middle/ty.rs94
-rw-r--r--src/librustc_typeck/check/mod.rs19
-rw-r--r--src/test/run-pass/uninstantiable-struct.rs (renamed from src/test/compile-fail/static-recursion-gate-2.rs)3
3 files changed, 1 insertions, 115 deletions
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 372bbfc9a1a..483f2873166 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -4821,100 +4821,6 @@ impl<'tcx> TyS<'tcx> {
 
         result
     }
-
-    // True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
-    pub fn is_instantiable(&'tcx self, cx: &ctxt<'tcx>) -> bool {
-        fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<AdtDef<'tcx>>,
-                               r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
-            debug!("type_requires({:?}, {:?})?",
-                   r_ty, ty);
-
-            let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
-
-            debug!("type_requires({:?}, {:?})? {:?}",
-                   r_ty, ty, r);
-            return r;
-        }
-
-        fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<AdtDef<'tcx>>,
-                                  r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
-            debug!("subtypes_require({:?}, {:?})?",
-                   r_ty, ty);
-
-            let r = match ty.sty {
-                // fixed length vectors need special treatment compared to
-                // normal vectors, since they don't necessarily have the
-                // possibility to have length zero.
-                TyArray(_, 0) => false, // don't need no contents
-                TyArray(ty, _) => type_requires(cx, seen, r_ty, ty),
-
-                TyBool |
-                TyChar |
-                TyInt(_) |
-                TyUint(_) |
-                TyFloat(_) |
-                TyStr |
-                TyBareFn(..) |
-                TyParam(_) |
-                TyProjection(_) |
-                TySlice(_) => {
-                    false
-                }
-                TyBox(typ) => {
-                    type_requires(cx, seen, r_ty, typ)
-                }
-                TyRef(_, ref mt) => {
-                    type_requires(cx, seen, r_ty, mt.ty)
-                }
-
-                TyRawPtr(..) => {
-                    false           // unsafe ptrs can always be NULL
-                }
-
-                TyTrait(..) => {
-                    false
-                }
-
-                TyStruct(def, substs) | TyEnum(def, substs) => {
-                    if seen.contains(&def) {
-                        // FIXME(#27497) ???
-                        false
-                    } else if def.is_empty() {
-                        // HACK: required for empty types to work. This
-                        // check is basically a lint anyway.
-                        false
-                    } else {
-                        seen.push(def);
-                        let r = def.variants.iter().all(|v| v.fields.iter().any(|f| {
-                            type_requires(cx, seen, r_ty, f.ty(cx, substs))
-                        }));
-                        seen.pop().unwrap();
-                        r
-                    }
-                }
-
-                TyError |
-                TyInfer(_) |
-                TyClosure(..) => {
-                    // this check is run on type definitions, so we don't expect to see
-                    // inference by-products or closure types
-                    cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
-                }
-
-                TyTuple(ref ts) => {
-                    ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
-                }
-            };
-
-            debug!("subtypes_require({:?}, {:?})? {:?}",
-                   r_ty, ty, r);
-
-            return r;
-        }
-
-        let mut seen = Vec::new();
-        !subtypes_require(cx, &mut seen, self, self)
-    }
 }
 
 /// Describes whether a type is representable. For types that are not
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index b21f683b169..e9d78b3b7d7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -117,7 +117,6 @@ use syntax::attr::AttrMetaMethods;
 use syntax::ast::{self, Visibility};
 use syntax::ast_util;
 use syntax::codemap::{self, Span};
-use syntax::feature_gate::emit_feature_err;
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::{self, InternedString};
 use syntax::print::pprust;
@@ -669,7 +668,6 @@ pub fn check_struct(ccx: &CrateCtxt, id: ast::NodeId, span: Span) {
     let tcx = ccx.tcx;
 
     check_representable(tcx, span, id, "struct");
-    check_instantiable(tcx, span, id);
 
     if tcx.lookup_simd(DefId::local(id)) {
         check_simd(tcx, span, id);
@@ -4202,22 +4200,6 @@ pub fn check_representable(tcx: &ty::ctxt,
     return true
 }
 
-/// Checks whether a type can be constructed at runtime without
-/// an existing instance of that type.
-pub fn check_instantiable(tcx: &ty::ctxt,
-                          sp: Span,
-                          item_id: ast::NodeId) {
-    let item_ty = tcx.node_id_to_type(item_id);
-    if !item_ty.is_instantiable(tcx) &&
-            !tcx.sess.features.borrow().static_recursion {
-        emit_feature_err(&tcx.sess.parse_sess.span_diagnostic,
-                         "static_recursion",
-                         sp,
-                         "this type cannot be instantiated at runtime \
-                          without an instance of itself");
-    }
-}
-
 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
     let t = tcx.node_id_to_type(id);
     match t.sty {
@@ -4352,7 +4334,6 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     do_check(ccx, vs, id, hint);
 
     check_representable(ccx.tcx, sp, id, "enum");
-    check_instantiable(ccx.tcx, sp, id);
 }
 
 // Returns the type parameter count and the type for the given definition.
diff --git a/src/test/compile-fail/static-recursion-gate-2.rs b/src/test/run-pass/uninstantiable-struct.rs
index de038924840..d9740171576 100644
--- a/src/test/compile-fail/static-recursion-gate-2.rs
+++ b/src/test/run-pass/uninstantiable-struct.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Z(&'static Z);
-//~^ ERROR this type cannot be instantiated
+pub struct Z(&'static Z);
 
 pub fn main() {}