about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-10-01 11:27:23 +0000
committerbors <bors@rust-lang.org>2014-10-01 11:27:23 +0000
commit8ab6fce95e9b8a4ed27ecb7bee69784a02610e1d (patch)
tree1fba572bb05c2be5fd0dbe66dd74967b1e2958a9
parentff2616e847ddf913e007d715732b5669b0f22672 (diff)
parent065a5b0424221b246d59fd068d4e6eb5d1ae5be1 (diff)
downloadrust-8ab6fce95e9b8a4ed27ecb7bee69784a02610e1d.tar.gz
rust-8ab6fce95e9b8a4ed27ecb7bee69784a02610e1d.zip
auto merge of #17653 : kaini/rust/master, r=alexcrichton
Fixes that unit-like structs cannot be used if they are re-exported and used in another crate. (ICE)
The relevant changes are in `rustc::metadata::{decoder, encoder}` and `rustc::middle::ty`.

A test case is included.

The problem is that the expressoin `UnitStruct` is an `ExprPath` to an `DefFn`, which is of expr kind `RvalueDatumExpr`, but for unit-struct ctors the expr kind should be `RvalueDpsExpr`. I fixed this (in a I guess clean way) by introducing `CtorFn` in the metadata and including a `is_ctor` flag in `DefFn`.
-rw-r--r--src/librustc/metadata/decoder.rs7
-rw-r--r--src/librustc/metadata/encoder.rs2
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/check_const.rs2
-rw-r--r--src/librustc/middle/def.rs4
-rw-r--r--src/librustc/middle/intrinsicck.rs2
-rw-r--r--src/librustc/middle/privacy.rs2
-rw-r--r--src/librustc/middle/resolve.rs10
-rw-r--r--src/librustc/middle/save/mod.rs12
-rw-r--r--src/librustc/middle/trans/callee.rs6
-rw-r--r--src/librustc/middle/trans/closure.rs2
-rw-r--r--src/librustc/middle/trans/consts.rs2
-rw-r--r--src/librustc/middle/trans/expr.rs2
-rw-r--r--src/librustc/middle/ty.rs6
-rw-r--r--src/librustc/middle/typeck/check/mod.rs2
-rw-r--r--src/librustdoc/clean/inline.rs6
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/test/auxiliary/issue-12660-aux.rs21
-rw-r--r--src/test/run-pass/issue-12660.rs21
19 files changed, 81 insertions, 32 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 44f6f5f5470..6d4407f96a7 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -112,6 +112,7 @@ enum Family {
     MutStatic,             // b
     Fn,                    // f
     UnsafeFn,              // u
+    CtorFn,                // o
     StaticMethod,          // F
     UnsafeStaticMethod,    // U
     Type,                  // y
@@ -135,6 +136,7 @@ fn item_family(item: rbml::Doc) -> Family {
       'b' => MutStatic,
       'f' => Fn,
       'u' => UnsafeFn,
+      'o' => CtorFn,
       'F' => StaticMethod,
       'U' => UnsafeStaticMethod,
       'y' => Type,
@@ -304,8 +306,9 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
         ImmStatic => DlDef(def::DefStatic(did, false)),
         MutStatic => DlDef(def::DefStatic(did, true)),
         Struct    => DlDef(def::DefStruct(did)),
-        UnsafeFn  => DlDef(def::DefFn(did, ast::UnsafeFn)),
-        Fn        => DlDef(def::DefFn(did, ast::NormalFn)),
+        UnsafeFn  => DlDef(def::DefFn(did, ast::UnsafeFn, false)),
+        Fn        => DlDef(def::DefFn(did, ast::NormalFn, false)),
+        CtorFn    => DlDef(def::DefFn(did, ast::NormalFn, true)),
         StaticMethod | UnsafeStaticMethod => {
             let fn_style = if fam == UnsafeStaticMethod {
                 ast::UnsafeFn
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index f8cf7887924..6bcad25f4b1 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -761,7 +761,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
 
     rbml_w.start_tag(tag_items_data_item);
     encode_def_id(rbml_w, local_def(ctor_id));
-    encode_family(rbml_w, 'f');
+    encode_family(rbml_w, 'o');
     encode_bounds_and_type(rbml_w, ecx,
                            &lookup_item_type(ecx.tcx, local_def(ctor_id)));
     encode_name(rbml_w, name.name);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index f40d6d47281..2bd145706aa 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -440,7 +440,7 @@ fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
 impl tr for def::Def {
     fn tr(&self, dcx: &DecodeContext) -> def::Def {
         match *self {
-          def::DefFn(did, p) => def::DefFn(did.tr(dcx), p),
+          def::DefFn(did, p, is_ctor) => def::DefFn(did.tr(dcx), p, is_ctor),
           def::DefStaticMethod(did, wrapped_did2, p) => {
             def::DefStaticMethod(did.tr(dcx),
                                    match wrapped_did2 {
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 9b699a240cb..cc3679ec31d 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -133,7 +133,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
             }
             match v.tcx.def_map.borrow().find(&e.id) {
               Some(&DefStatic(..)) |
-              Some(&DefFn(_, _)) |
+              Some(&DefFn(..)) |
               Some(&DefVariant(_, _, _)) |
               Some(&DefStruct(_)) => { }
 
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 1863a19b56d..bd42586435f 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -14,7 +14,7 @@ use syntax::ast_util::local_def;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Def {
-    DefFn(ast::DefId, ast::FnStyle),
+    DefFn(ast::DefId, ast::FnStyle, bool /* is_ctor */),
     DefStaticMethod(/* method */ ast::DefId, MethodProvenance, ast::FnStyle),
     DefSelfTy(/* trait id */ ast::NodeId),
     DefMod(ast::DefId),
@@ -57,7 +57,7 @@ pub enum MethodProvenance {
 impl Def {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
-            DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
+            DefFn(id, _, _) | DefStaticMethod(id, _, _) | DefMod(id) |
             DefForeignMod(id) | DefStatic(id, _) |
             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
             DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index 9d0d21d6d2a..dccb93f58cc 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -121,7 +121,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
         match expr.node {
             ast::ExprPath(..) => {
                 match ty::resolve_expr(self.tcx, expr) {
-                    DefFn(did, _) if self.def_id_is_transmute(did) => {
+                    DefFn(did, _, _) if self.def_id_is_transmute(did) => {
                         let typ = ty::node_id_to_type(self.tcx, expr.id);
                         match ty::get(typ).sty {
                             ty_bare_fn(ref bare_fn_ty)
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index bf16f772775..6c69d64a1ee 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -934,7 +934,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                     }
                     // Tuple struct constructors across crates are identified as
                     // DefFn types, so we explicitly handle that case here.
-                    Some(&def::DefFn(did, _)) if !is_local(did) => {
+                    Some(&def::DefFn(did, _, _)) if !is_local(did) => {
                         match csearch::get_tuple_struct_definition_if_ctor(
                                     &self.tcx.sess.cstore, did) {
                             Some(did) => guard(did),
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 5f0750d2653..e1bed359ffe 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1247,7 +1247,7 @@ impl<'a> Resolver<'a> {
                 let name_bindings =
                     self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
 
-                let def = DefFn(local_def(item.id), fn_style);
+                let def = DefFn(local_def(item.id), fn_style, false);
                 name_bindings.define_value(def, sp, is_public);
                 parent
             }
@@ -1705,7 +1705,7 @@ impl<'a> Resolver<'a> {
 
         match foreign_item.node {
             ForeignItemFn(_, ref generics) => {
-                let def = DefFn(local_def(foreign_item.id), UnsafeFn);
+                let def = DefFn(local_def(foreign_item.id), UnsafeFn, false);
                 name_bindings.define_value(def, foreign_item.span, is_public);
 
                 self.with_type_parameter_rib(
@@ -2022,7 +2022,8 @@ impl<'a> Resolver<'a> {
                                                        DUMMY_SP);
                                     let def = DefFn(
                                         static_method_info.def_id,
-                                        static_method_info.fn_style);
+                                        static_method_info.fn_style,
+                                        false);
 
                                     method_name_bindings.define_value(
                                         def, DUMMY_SP,
@@ -2591,7 +2592,8 @@ impl<'a> Resolver<'a> {
 
         match value_result {
             BoundResult(ref target_module, ref name_bindings) => {
-                debug!("(resolving single import) found value target");
+                debug!("(resolving single import) found value target: {:?}",
+                       { name_bindings.value_def.borrow().clone().unwrap().def });
                 self.check_for_conflicting_import(
                     &import_resolution.value_target,
                     directive.span,
diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs
index 0f4ed202ec2..c956c2d2b00 100644
--- a/src/librustc/middle/save/mod.rs
+++ b/src/librustc/middle/save/mod.rs
@@ -234,7 +234,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             def::DefVariant(_, _, _) |
             def::DefUpvar(..) => Some(recorder::VarRef),
 
-            def::DefFn(_, _) => Some(recorder::FnRef),
+            def::DefFn(..) => Some(recorder::FnRef),
 
             def::DefSelfTy(_) |
             def::DefRegion(_) |
@@ -792,10 +792,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                                        Some(declid),
                                        self.cur_scope);
             },
-            def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
-                                                          sub_span,
-                                                          def_id,
-                                                          self.cur_scope),
+            def::DefFn(def_id, _, _) => self.fmt.fn_call_str(ex.span,
+                                                             sub_span,
+                                                             def_id,
+                                                             self.cur_scope),
             _ => self.sess.span_bug(ex.span,
                                     format!("Unexpected def kind while looking up path in '{}'",
                                             self.span.snippet(ex.span)).as_slice()),
@@ -808,7 +808,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             def::DefLocal(_) |
             def::DefStatic(_,_) |
             def::DefStruct(_) |
-            def::DefFn(_, _) => self.write_sub_paths_truncated(path),
+            def::DefFn(..) => self.write_sub_paths_truncated(path),
             _ => {},
         }
 
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 5962bee023a..7942a0211e4 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -142,7 +142,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
         debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
         let expr_ty = node_id_type(bcx, ref_expr.id);
         match def {
-            def::DefFn(did, _) if {
+            def::DefFn(did, _, _) if {
                 let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
                 let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
                                                                              .find(def_id.node));
@@ -157,7 +157,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                     data: NamedTupleConstructor(substs, 0)
                 }
             }
-            def::DefFn(did, _) if match ty::get(expr_ty).sty {
+            def::DefFn(did, _, _) if match ty::get(expr_ty).sty {
                 ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
                 _ => false
             } => {
@@ -165,7 +165,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
                 Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
             }
-            def::DefFn(did, _) |
+            def::DefFn(did, _, _) |
             def::DefStaticMethod(did, def::FromImpl(_), _) => {
                 fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
             }
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index fa8c6b8b448..f08736335c3 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -532,7 +532,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext,
                                is_local: bool) -> ValueRef {
 
     let def_id = match def {
-        def::DefFn(did, _) | def::DefStaticMethod(did, _, _) |
+        def::DefFn(did, _, _) | def::DefStaticMethod(did, _, _) |
         def::DefVariant(_, did, _) | def::DefStruct(did) => did,
         _ => {
             ccx.sess().bug(format!("get_wrapper_for_bare_fn: \
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index d39fe4a1e70..c499fcf4bf8 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -623,7 +623,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
 
             let opt_def = cx.tcx().def_map.borrow().find_copy(&e.id);
             match opt_def {
-                Some(def::DefFn(def_id, _fn_style)) => {
+                Some(def::DefFn(def_id, _fn_style, _)) => {
                     if !ast_util::is_local(def_id) {
                         let ty = csearch::get_type(cx.tcx(), def_id).ty;
                         (base::trans_external_path(cx, def_id, ty), true)
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index eeea10e8eb0..37a39ef8e3b 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1194,7 +1194,7 @@ fn trans_def_fn_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_def_datum_unadjusted");
 
     let llfn = match def {
-        def::DefFn(did, _) |
+        def::DefFn(did, _, _) |
         def::DefStruct(did) | def::DefVariant(_, did, _) |
         def::DefStaticMethod(did, def::FromImpl(_), _) => {
             callee::trans_fn_ref(bcx, did, ExprId(ref_expr.id))
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 2c11f60caf6..b38f362dcf1 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3592,6 +3592,12 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
                     }
                 }
 
+                // Special case: A unit like struct's constructor must be called without () at the
+                // end (like `UnitStruct`) which means this is an ExprPath to a DefFn. But in case
+                // of unit structs this is should not be interpretet as function pointer but as
+                // call to the constructor.
+                def::DefFn(_, _, true) => RvalueDpsExpr,
+
                 // Fn pointers are just scalar values.
                 def::DefFn(..) | def::DefStaticMethod(..) => RvalueDatumExpr,
 
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index e49936f5a4c..b0c0a8a571b 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -5086,7 +5086,7 @@ pub fn polytype_for_def(fcx: &FnCtxt,
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
       }
-      def::DefFn(id, _) | def::DefStaticMethod(id, _, _) |
+      def::DefFn(id, _, _) | def::DefStaticMethod(id, _, _) |
       def::DefStatic(id, _) | def::DefVariant(_, id, _) |
       def::DefStruct(id) => {
         return ty::lookup_item_type(fcx.ccx.tcx, id);
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 1a324e25472..b86f4d8cfb5 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -73,12 +73,8 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
             record_extern_fqn(cx, did, clean::TypeTrait);
             clean::TraitItem(build_external_trait(cx, tcx, did))
         }
-        def::DefFn(did, style) => {
+        def::DefFn(did, style, false) => {
             // If this function is a tuple struct constructor, we just skip it
-            if csearch::get_tuple_struct_definition_if_ctor(&tcx.sess.cstore,
-                                                            did).is_some() {
-                return None
-            }
             record_extern_fqn(cx, did, clean::TypeFunction);
             clean::FunctionItem(build_external_function(cx, tcx, did, style))
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 666be2debda..054fbda7337 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2078,7 +2078,7 @@ fn resolve_type(cx: &DocContext, path: Path,
 
 fn register_def(cx: &DocContext, def: def::Def) -> ast::DefId {
     let (did, kind) = match def {
-        def::DefFn(i, _) => (i, TypeFunction),
+        def::DefFn(i, _, _) => (i, TypeFunction),
         def::DefTy(i, false) => (i, TypeTypedef),
         def::DefTy(i, true) => (i, TypeEnum),
         def::DefTrait(i) => (i, TypeTrait),
diff --git a/src/test/auxiliary/issue-12660-aux.rs b/src/test/auxiliary/issue-12660-aux.rs
new file mode 100644
index 00000000000..9f2bd5d0e93
--- /dev/null
+++ b/src/test/auxiliary/issue-12660-aux.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type="lib"]
+#![crate_name="issue12660aux"]
+
+pub use my_mod::{MyStruct, my_fn};
+
+mod my_mod {
+    pub struct MyStruct;
+
+    pub fn my_fn(my_struct: MyStruct) {
+    }
+}
diff --git a/src/test/run-pass/issue-12660.rs b/src/test/run-pass/issue-12660.rs
new file mode 100644
index 00000000000..6b3fa587bc5
--- /dev/null
+++ b/src/test/run-pass/issue-12660.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue-12660-aux.rs
+
+extern crate issue12660aux;
+
+use issue12660aux::{my_fn, MyStruct};
+
+#[allow(path_statement)]
+fn main() {
+    my_fn(MyStruct);
+    MyStruct;
+}