]> git.lizzy.rs Git - rust.git/commitdiff
avoid translating roots with predicates that do not hold
authorAriel Ben-Yehuda <ariel.byd@gmail.com>
Wed, 21 Jun 2017 11:50:43 +0000 (14:50 +0300)
committerAriel Ben-Yehuda <ariel.byd@gmail.com>
Wed, 21 Jun 2017 13:16:19 +0000 (16:16 +0300)
Fixes #37725.

src/librustc/traits/mod.rs
src/librustc_trans/collector.rs
src/librustc_trans/trans_item.rs
src/test/run-pass/issue-37725.rs [new file with mode: 0644]

index e9196cd12431bc825b13e3ffde7bf5edd5a883f4..d5d92cfcc3ecbd67bbc1d4b8915a091ad5d183df 100644 (file)
@@ -597,7 +597,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("normalize_and_test_predicates(predicates={:?})",
            predicates);
 
-    tcx.infer_ctxt().enter(|infcx| {
+    let result = tcx.infer_ctxt().enter(|infcx| {
         let param_env = ty::ParamEnv::empty(Reveal::All);
         let mut selcx = SelectionContext::new(&infcx);
         let mut fulfill_cx = FulfillmentContext::new();
@@ -613,7 +613,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
 
         fulfill_cx.select_all_or_error(&infcx).is_ok()
-    })
+    });
+    debug!("normalize_and_test_predicates(predicates={:?}) = {:?}",
+           predicates, result);
+    result
 }
 
 /// Given a trait `trait_ref`, iterates the vtable entries
index d723cf325718ea86de681f451e32c53091ffad08..3536dcf16e5b6e55997d48409054fe7dd5071d08 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc::middle::lang_items::{ExchangeMallocFnLangItem};
 use rustc::traits;
-use rustc::ty::subst::{Substs, Subst};
+use rustc::ty::subst::Substs;
 use rustc::ty::{self, TypeFoldable, TyCtxt};
 use rustc::ty::adjustment::CustomCoerceUnsized;
 use rustc::mir::{self, Location};
@@ -304,6 +304,7 @@ fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
         scx.tcx().hir.krate().visit_all_item_likes(&mut visitor);
     }
 
+    roots.retain(|root| root.is_instantiable(scx.tcx()));
     roots
 }
 
@@ -937,14 +938,9 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
                     let instance =
                         monomorphize::resolve(scx, method.def_id, callee_substs);
 
-                    let predicates = tcx.predicates_of(instance.def_id()).predicates
-                        .subst(tcx, instance.substs);
-                    if !traits::normalize_and_test_predicates(tcx, predicates) {
-                        continue;
-                    }
-
-                    if should_trans_locally(tcx, &instance) {
-                        output.push(create_fn_trans_item(instance));
+                    let trans_item = create_fn_trans_item(instance);
+                    if trans_item.is_instantiable(tcx) && should_trans_locally(tcx, &instance) {
+                        output.push(trans_item);
                     }
                 }
             }
index 0dc2bc85e30e63d4722daf3d5eedf2acb812eb34..6e8b2e0a2a6bafa69eefee375c770b500e85686b 100644 (file)
@@ -25,8 +25,9 @@
 use monomorphize::Instance;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
+use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::subst::Substs;
+use rustc::ty::subst::{Subst, Substs};
 use syntax::ast::{self, NodeId};
 use syntax::attr;
 use syntax_pos::Span;
@@ -250,6 +251,21 @@ pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<llvm::Link
         }
     }
 
+    /// Returns whether this instance is instantiable - whether it has no unsatisfied
+    /// predicates.
+    pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
+        debug!("is_instantiable({:?})", self);
+        let (def_id, substs) = match *self {
+            TransItem::Fn(ref instance) => (instance.def_id(), instance.substs),
+            TransItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()),
+            // global asm never has predicates
+            TransItem::GlobalAsm(..) => return true
+        };
+
+        let predicates = tcx.predicates_of(def_id).predicates.subst(tcx, substs);
+        traits::normalize_and_test_predicates(tcx, predicates)
+    }
+
     pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
         let hir_map = &tcx.hir;
 
diff --git a/src/test/run-pass/issue-37725.rs b/src/test/run-pass/issue-37725.rs
new file mode 100644 (file)
index 0000000..5ed1295
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
+    s.clone();
+}
+fn main() {}