about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-07-26 16:16:28 -0700
committerPaul Stansifer <paul.stansifer@gmail.com>2012-07-26 16:16:28 -0700
commit97422f0f0fdcbdd17a769fa9588e76b8bf8a5bdf (patch)
treea91f89c585b54fccf34cd873d2488d2cb3c09909 /src/rustc
parent8209b2e9b383b9e38a09b1ec79c7b5691aeb5d22 (diff)
parent44631722ff234241cb7100103320a402fe4fdfa9 (diff)
Merge branch 'incoming' of github.com:mozilla/rust
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/driver/driver.rs7
-rw-r--r--src/rustc/driver/session.rs4
-rw-r--r--src/rustc/lib/llvm.rs3
-rw-r--r--src/rustc/metadata/csearch.rs9
-rw-r--r--src/rustc/metadata/decoder.rs19
-rw-r--r--src/rustc/metadata/encoder.rs12
-rw-r--r--src/rustc/middle/astencode.rs4
-rw-r--r--src/rustc/middle/borrowck/categorization.rs2
-rw-r--r--src/rustc/middle/lang_items.rs209
-rw-r--r--src/rustc/middle/region.rs2
-rw-r--r--src/rustc/middle/resolve3.rs23
-rw-r--r--src/rustc/middle/ty.rs2
-rw-r--r--src/rustc/middle/typeck/astconv.rs2
-rw-r--r--src/rustc/middle/typeck/check.rs4
-rw-r--r--src/rustc/middle/typeck/check/regionmanip.rs2
-rw-r--r--src/rustc/rustc.rc1
16 files changed, 284 insertions, 21 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index 52aa88e6cb6..a6734b285a1 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -14,6 +14,7 @@ import io::{reader_util, writer_util};
 import getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
 import back::{x86, x86_64};
 import std::map::hashmap;
+import lib::llvm::llvm;
 
 enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
               ppm_expanded_identified }
@@ -169,6 +170,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
                              session::sess_os_to_meta_os(sess.targ_cfg.os),
                              sess.opts.static));
 
+    time(time_passes, ~"language item collection", ||
+         middle::lang_items::collect_language_items(crate, sess));
+
     let { def_map: def_map,
           exp_map: exp_map,
           impl_map: impl_map,
@@ -440,6 +444,9 @@ fn build_session_options(match: getopts::match,
         }
         debugging_opts |= this_bit;
     }
+    if debugging_opts & session::debug_llvm != 0 {
+        llvm::LLVMSetDebug(1);
+    }
 
     let output_type =
         if parse_only || no_trans {
diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs
index 64ae30895c4..61ef9f73c3f 100644
--- a/src/rustc/driver/session.rs
+++ b/src/rustc/driver/session.rs
@@ -40,6 +40,7 @@ const borrowck_stats: uint = 1024u;
 const borrowck_note_pure: uint = 2048;
 const borrowck_note_loan: uint = 4096;
 const no_landing_pads: uint = 8192;
+const debug_llvm: uint = 16384;
 
 fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
     ~[(~"ppregions", ~"prettyprint regions with \
@@ -61,7 +62,8 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
      (~"borrowck-note-loan", ~"note where loans are req'd",
       borrowck_note_loan),
      (~"no-landing-pads", ~"omit landing pads for unwinding",
-      no_landing_pads)
+      no_landing_pads),
+     (~"debug-llvm", ~"enable debug output from LLVM", debug_llvm)
     ]
 }
 
diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs
index 376012dcf4e..7dbefa8e498 100644
--- a/src/rustc/lib/llvm.rs
+++ b/src/rustc/lib/llvm.rs
@@ -969,6 +969,9 @@ extern mod llvm {
 
     fn LLVMConstNamedStruct(S: TypeRef, ConstantVals: *ValueRef,
                             Count: c_uint) -> ValueRef;
+
+    /** Enables LLVM debug output. */
+    fn LLVMSetDebug(Enabled: c_int);
 }
 
 fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) {
diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs
index 7f97583fe3d..0ba76c49246 100644
--- a/src/rustc/metadata/csearch.rs
+++ b/src/rustc/metadata/csearch.rs
@@ -25,6 +25,7 @@ export get_enum_variants;
 export get_impls_for_mod;
 export get_trait_methods;
 export get_method_names_if_trait;
+export get_item_attrs;
 export each_path;
 export get_type;
 export get_impl_traits;
@@ -149,6 +150,14 @@ fn get_method_names_if_trait(cstore: cstore::cstore, def: ast::def_id)
     ret decoder::get_method_names_if_trait(cdata, def.node);
 }
 
+fn get_item_attrs(cstore: cstore::cstore,
+                  def_id: ast::def_id,
+                  f: fn(~[@ast::meta_item])) {
+
+    let cdata = cstore::get_crate_data(cstore, def_id.crate);
+    decoder::get_item_attrs(cdata, def_id.node, f)
+}
+
 fn get_class_fields(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::field_ty] {
     let cstore = tcx.cstore;
     let cdata = cstore::get_crate_data(cstore, def.crate);
diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs
index 3ff9ded3f1e..83684413641 100644
--- a/src/rustc/metadata/decoder.rs
+++ b/src/rustc/metadata/decoder.rs
@@ -39,6 +39,7 @@ export get_crate_vers;
 export get_impls_for_mod;
 export get_trait_methods;
 export get_method_names_if_trait;
+export get_item_attrs;
 export get_crate_module_paths;
 export def_like;
 export dl_def;
@@ -282,7 +283,8 @@ fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num)
     let fam_ch = item_family(item);
     alt fam_ch {
       'c' { dl_def(ast::def_const(did)) }
-      'C' { dl_def(ast::def_class(did)) }
+      'C' { dl_def(ast::def_class(did, true)) }
+      'S' { dl_def(ast::def_class(did, false)) }
       'u' { dl_def(ast::def_fn(did, ast::unsafe_fn)) }
       'f' { dl_def(ast::def_fn(did, ast::impure_fn)) }
       'p' { dl_def(ast::def_fn(did, ast::pure_fn)) }
@@ -659,6 +661,18 @@ fn get_method_names_if_trait(cdata: cmd, node_id: ast::node_id)
     ret some(resulting_method_names);
 }
 
+fn get_item_attrs(cdata: cmd,
+                  node_id: ast::node_id,
+                  f: fn(~[@ast::meta_item])) {
+
+    let item = lookup_item(node_id, cdata.data);
+    do ebml::tagged_docs(item, tag_attributes) |attributes| {
+        do ebml::tagged_docs(attributes, tag_attribute) |attribute| {
+            f(get_meta_items(attribute));
+        }
+    }
+}
+
 // Helper function that gets either fields or methods
 fn get_class_members(cdata: cmd, id: ast::node_id,
                      p: fn(char) -> bool) -> ~[ty::field_ty] {
@@ -694,7 +708,7 @@ fn family_has_type_params(fam_ch: char) -> bool {
     alt check fam_ch {
       'c' | 'T' | 'm' | 'n' | 'g' | 'h' | 'j' { false }
       'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' | 'C'
-          | 'a'
+          | 'a' | 'S'
           { true }
     }
 }
@@ -738,6 +752,7 @@ fn item_family_to_str(fam: char) -> ~str {
       'i' { ret ~"impl"; }
       'I' { ret ~"trait"; }
       'C' { ret ~"class"; }
+      'S' { ret ~"struct"; }
       'g' { ret ~"public field"; }
       'j' { ret ~"private field"; }
     }
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index b2847b3acc5..e1ed9fe396a 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -663,7 +663,16 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
         /* Now, make an item for the class itself */
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
-        encode_family(ebml_w, 'C');
+
+        alt ctor {
+            none {
+                encode_family(ebml_w, 'S');
+            }
+            some(_) {
+                encode_family(ebml_w, 'C');
+            }
+        }
+
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ebml_w, item.ident);
@@ -759,6 +768,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ebml_w, item.ident);
+        encode_attributes(ebml_w, item.attrs);
         let mut i = 0u;
         for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
             alt ms[i] {
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index 002b4d97e23..1f5f7c4518d 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -369,8 +369,8 @@ impl of tr for ast::def {
           ast::def_upvar(nid1, def, nid2) {
             ast::def_upvar(xcx.tr_id(nid1), @(*def).tr(xcx), xcx.tr_id(nid2))
           }
-          ast::def_class(did) {
-            ast::def_class(did.tr(xcx))
+          ast::def_class(did, has_constructor) {
+            ast::def_class(did.tr(xcx), has_constructor)
           }
           ast::def_region(nid) { ast::def_region(xcx.tr_id(nid)) }
         }
diff --git a/src/rustc/middle/borrowck/categorization.rs b/src/rustc/middle/borrowck/categorization.rs
index f5879145a9d..4088945e550 100644
--- a/src/rustc/middle/borrowck/categorization.rs
+++ b/src/rustc/middle/borrowck/categorization.rs
@@ -196,7 +196,7 @@ impl public_methods for borrowck_ctxt {
           ast::def_foreign_mod(_) | ast::def_const(_) |
           ast::def_use(_) | ast::def_variant(_, _) |
           ast::def_ty(_) | ast::def_prim_ty(_) |
-          ast::def_ty_param(_, _) | ast::def_class(_) |
+          ast::def_ty_param(_, _) | ast::def_class(_, _) |
           ast::def_region(_) {
             @{id:id, span:span,
               cat:cat_special(sk_static_item), lp:none,
diff --git a/src/rustc/middle/lang_items.rs b/src/rustc/middle/lang_items.rs
new file mode 100644
index 00000000000..2353da51f98
--- /dev/null
+++ b/src/rustc/middle/lang_items.rs
@@ -0,0 +1,209 @@
+// Detecting language items.
+//
+// Language items are items that represent concepts intrinsic to the language
+// itself. Examples are:
+//
+// * Traits that specify "kinds"; e.g. "const", "copy", "send".
+//
+// * Traits that represent operators; e.g. "add", "sub", "index".
+//
+// * Functions called by the compiler itself.
+
+import driver::session::session;
+import metadata::csearch::{each_path, get_item_attrs};
+import metadata::cstore::{iter_crate_data};
+import metadata::decoder::{dl_def, dl_field, dl_impl};
+import syntax::ast::{crate, def_id, def_ty, lit_str, meta_item, meta_list};
+import syntax::ast::{meta_name_value, meta_word};
+import syntax::ast_util::{local_def};
+import syntax::visit::{default_simple_visitor, mk_simple_visitor};
+import syntax::visit::{visit_crate, visit_item};
+
+import std::map::{hashmap, str_hash};
+import str_eq = str::eq;
+
+class LanguageItems {
+    let mut const_trait: option<def_id>;
+    let mut copy_trait: option<def_id>;
+    let mut send_trait: option<def_id>;
+    let mut owned_trait: option<def_id>;
+
+    let mut add_trait: option<def_id>;
+    let mut sub_trait: option<def_id>;
+    let mut mul_trait: option<def_id>;
+    let mut div_trait: option<def_id>;
+    let mut modulo_trait: option<def_id>;
+    let mut neg_trait: option<def_id>;
+    let mut bitops_trait: option<def_id>;
+    let mut index_trait: option<def_id>;
+
+    new() {
+        self.const_trait = none;
+        self.copy_trait = none;
+        self.send_trait = none;
+        self.owned_trait = none;
+
+        self.add_trait = none;
+        self.sub_trait = none;
+        self.mul_trait = none;
+        self.div_trait = none;
+        self.modulo_trait = none;
+        self.neg_trait = none;
+        self.bitops_trait = none;
+        self.index_trait = none;
+    }
+}
+
+class LanguageItemCollector {
+    let items: LanguageItems;
+
+    let crate: @crate;
+    let session: session;
+
+    let item_refs: hashmap<~str,&mut option<def_id>>;
+
+    new(crate: @crate, session: session) {
+        self.crate = crate;
+        self.session = session;
+
+        self.items = LanguageItems();
+
+        self.item_refs = str_hash();
+    }
+
+    // XXX: Needed to work around an issue with constructors.
+    fn init() {
+        self.item_refs.insert(~"const", &mut self.items.const_trait);
+        self.item_refs.insert(~"copy", &mut self.items.copy_trait);
+        self.item_refs.insert(~"send", &mut self.items.send_trait);
+        self.item_refs.insert(~"owned", &mut self.items.owned_trait);
+
+        self.item_refs.insert(~"add", &mut self.items.add_trait);
+        self.item_refs.insert(~"sub", &mut self.items.sub_trait);
+        self.item_refs.insert(~"mul", &mut self.items.mul_trait);
+        self.item_refs.insert(~"div", &mut self.items.div_trait);
+        self.item_refs.insert(~"modulo", &mut self.items.modulo_trait);
+        self.item_refs.insert(~"neg", &mut self.items.neg_trait);
+        self.item_refs.insert(~"bitops", &mut self.items.bitops_trait);
+        self.item_refs.insert(~"index", &mut self.items.index_trait);
+    }
+
+    fn match_and_collect_meta_item(item_def_id: def_id,
+                                   meta_item: meta_item) {
+
+        alt meta_item.node {
+            meta_name_value(key, literal) => {
+                alt literal.node {
+                    lit_str(value) => {
+                        self.match_and_collect_item(item_def_id,
+                                                    *key,
+                                                    *value);
+                    }
+                    _ => {
+                        // Skip.
+                    }
+                }
+            }
+            meta_word(*) | meta_list(*) {
+                // Skip.
+            }
+        }
+    }
+
+    fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) {
+        if !str_eq(key, ~"lang") {
+            ret;    // Didn't match.
+        }
+
+        alt self.item_refs.find(value) {
+            none => {
+                // Didn't match.
+            }
+            some(item_ref) => {
+                // Check for duplicates.
+                alt copy *item_ref {
+                    some(original_def_id)
+                            if original_def_id != item_def_id => {
+
+                        self.session.warn(#fmt("duplicate entry for `%s`",
+                                               value));
+                    }
+                    some(_) | none => {
+                        // OK.
+                    }
+                }
+
+                // Matched.
+                *item_ref = some(item_def_id);
+            }
+        }
+    }
+
+    fn collect_local_language_items() {
+        let this = unsafe { ptr::addr_of(self) };
+        visit_crate(*self.crate, (), mk_simple_visitor(@{
+            visit_item: |item| {
+                for item.attrs.each |attribute| {
+                    unsafe {
+                        (*this).match_and_collect_meta_item(local_def(item
+                                                                      .id),
+                                                            attribute.node
+                                                                     .value);
+                    }
+                }
+            }
+            with *default_simple_visitor()
+        }));
+    }
+
+    fn collect_external_language_items() {
+        let crate_store = self.session.cstore;
+        do iter_crate_data(crate_store) |crate_number, _crate_metadata| {
+            for each_path(crate_store, crate_number) |path_entry| {
+                let def_id;
+                alt path_entry.def_like {
+                    dl_def(def_ty(did)) => {
+                        def_id = did;
+                    }
+                    dl_def(_) | dl_impl(_) | dl_field {
+                        // Skip this.
+                        again;
+                    }
+                }
+
+                do get_item_attrs(crate_store, def_id) |meta_items| {
+                    for meta_items.each |meta_item| {
+                        self.match_and_collect_meta_item(def_id, *meta_item);
+                    }
+                }
+            }
+        }
+    }
+
+    fn check_completeness() {
+        for self.item_refs.each |key, item_ref| {
+            alt copy *item_ref {
+                none => {
+                    self.session.warn(#fmt("no item found for `%s`", key));
+                }
+                some(did) => {
+                    // OK.
+                }
+            }
+        }
+    }
+
+    fn collect() {
+        self.init();
+        self.collect_local_language_items();
+        self.collect_external_language_items();
+        self.check_completeness();
+    }
+}
+
+fn collect_language_items(crate: @crate, session: session) -> LanguageItems {
+    let collector = LanguageItemCollector(crate, session);
+    collector.collect();
+    copy collector.items
+}
+
diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs
index ca00aeaa0f4..cc6874bc967 100644
--- a/src/rustc/middle/region.rs
+++ b/src/rustc/middle/region.rs
@@ -467,7 +467,7 @@ fn determine_rp_in_ty(ty: @ast::ty,
     alt ty.node {
       ast::ty_path(_, id) {
         alt cx.def_map.get(id) {
-          ast::def_ty(did) | ast::def_class(did) {
+          ast::def_ty(did) | ast::def_class(did, _) {
             if did.crate == ast::local_crate {
                 cx.add_dep(did.node, cx.item_id);
             } else {
diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs
index bddf83c429e..e75268cde7f 100644
--- a/src/rustc/middle/resolve3.rs
+++ b/src/rustc/middle/resolve3.rs
@@ -41,7 +41,7 @@ import syntax::visit::{visit_mod, visit_ty, vt};
 
 import box::ptr_eq;
 import dvec::{dvec, extensions};
-import option::get;
+import option::{get, is_some};
 import str::{connect, split_str};
 import vec::pop;
 
@@ -604,7 +604,7 @@ class Resolver {
     let unused_import_lint_level: level;
 
     let trait_info: hashmap<def_id,@hashmap<Atom,()>>;
-    let structs: hashmap<def_id,()>;
+    let structs: hashmap<def_id,bool>;
 
     // The number of imports that are currently unresolved.
     let mut unresolved_imports: uint;
@@ -926,7 +926,8 @@ class Resolver {
                 (*name_bindings).define_impl(impl_info);
 
                 // Record the def ID of this struct.
-                self.structs.insert(local_def(item.id), ());
+                self.structs.insert(local_def(item.id),
+                                    is_some(optional_ctor));
 
                 visit_item(item, new_parent, visitor);
             }
@@ -1378,12 +1379,16 @@ class Resolver {
 
                             (*child_name_bindings).define_type(def);
                         }
-                        def_class(def_id) {
+                        def_class(def_id, has_constructor) {
                             #debug("(building reduced graph for external \
-                                    crate) building value and type %s",
-                                    final_ident);
-                            (*child_name_bindings).define_value(def);
+                                    crate) building type %s (value? %d)",
+                                    final_ident,
+                                    if has_constructor { 1 } else { 0 });
                             (*child_name_bindings).define_type(def);
+
+                            if has_constructor {
+                                (*child_name_bindings).define_value(def);
+                            }
                         }
                         def_self(*) | def_arg(*) | def_local(*) |
                         def_prim_ty(*) | def_ty_param(*) | def_binding(*) |
@@ -4201,7 +4206,9 @@ class Resolver {
                     some(definition @ def_ty(class_id))
                             if self.structs.contains_key(class_id) {
 
-                        self.record_def(expr.id, def_class(class_id));
+                        let has_constructor = self.structs.get(class_id);
+                        let class_def = def_class(class_id, has_constructor);
+                        self.record_def(expr.id, class_def);
                     }
                     _ {
                         self.session.span_err(path.span,
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index b6b1873b1dc..465aeebe3af 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -2587,7 +2587,7 @@ fn type_err_to_str(cx: ctxt, err: type_err) -> ~str {
 
 fn def_has_ty_params(def: ast::def) -> bool {
     alt def {
-      ast::def_fn(_, _) | ast::def_variant(_, _) | ast::def_class(_)
+      ast::def_fn(_, _) | ast::def_variant(_, _) | ast::def_class(_, _)
         { true }
       _ { false }
     }
diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs
index ebd189a15b7..3baea12ab48 100644
--- a/src/rustc/middle/typeck/astconv.rs
+++ b/src/rustc/middle/typeck/astconv.rs
@@ -270,7 +270,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>(
                                                        path_to_str(path))); }
           some(d) { d }};
         alt a_def {
-          ast::def_ty(did) | ast::def_class(did) {
+          ast::def_ty(did) | ast::def_class(did, _) {
             ast_path_to_ty(self, rscope, did, path, id).ty
           }
           ast::def_prim_ty(nty) {
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 0b78fd1a505..eaf0e90b26d 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -1649,7 +1649,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         // Resolve the path.
         let class_id;
         alt tcx.def_map.find(id) {
-            some(ast::def_class(type_def_id)) => {
+            some(ast::def_class(type_def_id, _)) => {
                 class_id = type_def_id;
             }
             _ => {
@@ -2160,7 +2160,7 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
       }
 
       ast::def_fn(id, _) | ast::def_const(id) |
-      ast::def_variant(_, id) | ast::def_class(id) {
+      ast::def_variant(_, id) | ast::def_class(id, _) {
         ret ty::lookup_item_type(fcx.ccx.tcx, id);
       }
       ast::def_binding(nid) {
diff --git a/src/rustc/middle/typeck/check/regionmanip.rs b/src/rustc/middle/typeck/check/regionmanip.rs
index 2231d9b320a..d1052fd6a2a 100644
--- a/src/rustc/middle/typeck/check/regionmanip.rs
+++ b/src/rustc/middle/typeck/check/regionmanip.rs
@@ -200,7 +200,7 @@ fn region_of(fcx: @fn_ctxt, expr: @ast::expr) -> ty::region {
           ast::def_foreign_mod(_) | ast::def_const(_) |
           ast::def_use(_) | ast::def_variant(_, _) |
           ast::def_ty(_) | ast::def_prim_ty(_) |
-          ast::def_ty_param(_, _) | ast::def_class(_) |
+          ast::def_ty_param(_, _) | ast::def_class(_, _) |
           ast::def_region(_) {
             ty::re_static
           }
diff --git a/src/rustc/rustc.rc b/src/rustc/rustc.rc
index 406c46cc6c6..b2cce508e57 100644
--- a/src/rustc/rustc.rc
+++ b/src/rustc/rustc.rc
@@ -88,6 +88,7 @@ mod middle {
     mod region;
     mod const_eval;
     mod astencode;
+    mod lang_items;
 }
 
 mod front {