Skip to content

Commit 3ac9768

Browse files
committed
avoid translating roots with predicates that do not hold
Fixes #37725.
1 parent 1143eb2 commit 3ac9768

File tree

4 files changed

+41
-12
lines changed

4 files changed

+41
-12
lines changed

src/librustc/traits/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
597597
debug!("normalize_and_test_predicates(predicates={:?})",
598598
predicates);
599599

600-
tcx.infer_ctxt().enter(|infcx| {
600+
let result = tcx.infer_ctxt().enter(|infcx| {
601601
let param_env = ty::ParamEnv::empty(Reveal::All);
602602
let mut selcx = SelectionContext::new(&infcx);
603603
let mut fulfill_cx = FulfillmentContext::new();
@@ -613,7 +613,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
613613
}
614614

615615
fulfill_cx.select_all_or_error(&infcx).is_ok()
616-
})
616+
});
617+
debug!("normalize_and_test_predicates(predicates={:?}) = {:?}",
618+
predicates, result);
619+
result
617620
}
618621

619622
/// Given a trait `trait_ref`, iterates the vtable entries

src/librustc_trans/collector.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ use rustc::hir::map as hir_map;
195195
use rustc::hir::def_id::DefId;
196196
use rustc::middle::lang_items::{ExchangeMallocFnLangItem};
197197
use rustc::traits;
198-
use rustc::ty::subst::{Substs, Subst};
198+
use rustc::ty::subst::Substs;
199199
use rustc::ty::{self, TypeFoldable, TyCtxt};
200200
use rustc::ty::adjustment::CustomCoerceUnsized;
201201
use rustc::mir::{self, Location};
@@ -304,6 +304,7 @@ fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
304304
scx.tcx().hir.krate().visit_all_item_likes(&mut visitor);
305305
}
306306

307+
roots.retain(|root| root.is_instantiable(scx.tcx()));
307308
roots
308309
}
309310

@@ -937,14 +938,9 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
937938
let instance =
938939
monomorphize::resolve(scx, method.def_id, callee_substs);
939940

940-
let predicates = tcx.predicates_of(instance.def_id()).predicates
941-
.subst(tcx, instance.substs);
942-
if !traits::normalize_and_test_predicates(tcx, predicates) {
943-
continue;
944-
}
945-
946-
if should_trans_locally(tcx, &instance) {
947-
output.push(create_fn_trans_item(instance));
941+
let trans_item = create_fn_trans_item(instance);
942+
if trans_item.is_instantiable(tcx) && should_trans_locally(tcx, &instance) {
943+
output.push(trans_item);
948944
}
949945
}
950946
}

src/librustc_trans/trans_item.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ use llvm;
2525
use monomorphize::Instance;
2626
use rustc::hir;
2727
use rustc::hir::def_id::DefId;
28+
use rustc::traits;
2829
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
29-
use rustc::ty::subst::Substs;
30+
use rustc::ty::subst::{Subst, Substs};
3031
use syntax::ast::{self, NodeId};
3132
use syntax::attr;
3233
use syntax_pos::Span;
@@ -250,6 +251,21 @@ impl<'a, 'tcx> TransItem<'tcx> {
250251
}
251252
}
252253

254+
/// Returns whether this instance is instantiable - whether it has no unsatisfied
255+
/// predicates.
256+
pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
257+
debug!("is_instantiable({:?})", self);
258+
let (def_id, substs) = match *self {
259+
TransItem::Fn(ref instance) => (instance.def_id(), instance.substs),
260+
TransItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()),
261+
// global asm never has predicates
262+
TransItem::GlobalAsm(..) => return true
263+
};
264+
265+
let predicates = tcx.predicates_of(def_id).predicates.subst(tcx, substs);
266+
traits::normalize_and_test_predicates(tcx, predicates)
267+
}
268+
253269
pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
254270
let hir_map = &tcx.hir;
255271

src/test/run-pass/issue-37725.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
12+
s.clone();
13+
}
14+
fn main() {}

0 commit comments

Comments
 (0)