Skip to content

Commit

Permalink
Auto merge of #41504 - eddyb:query-api, r=nikomatsakis
Browse files Browse the repository at this point in the history
Improve the librustc on-demand/query API ergonomics.

Queries are now performed through these two forms:
* `tcx.type_of(def_id)` (the most common usage)
* `tcx.at(span).type_of(def_id)` (to provide a more specific location in the cycle stack)

Several queries were renamed to work better as method names, i.e. by suffixing with `_of`.

r? @nikomatsakis
  • Loading branch information
bors committed Apr 26, 2017
2 parents dad9814 + decf759 commit b0a4074
Show file tree
Hide file tree
Showing 84 changed files with 508 additions and 557 deletions.
2 changes: 1 addition & 1 deletion src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

// Find the tables for this body.
let owner_def_id = tcx.hir.local_def_id(tcx.hir.body_owner(body.id()));
let tables = tcx.item_tables(owner_def_id);
let tables = tcx.typeck_tables_of(owner_def_id);

let mut cfg_builder = CFGBuilder {
tcx: tcx,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ impl<'a, 'tcx> InferEnv<'a, 'tcx> for hir::BodyId {
Option<ty::TypeckTables<'tcx>>,
Option<ty::ParameterEnvironment<'tcx>>) {
let item_id = tcx.hir.body_owner(self);
(Some(tcx.item_tables(tcx.hir.local_def_id(item_id))),
(Some(tcx.typeck_tables_of(tcx.hir.local_def_id(item_id))),
None,
Some(ty::ParameterEnvironment::for_item(tcx, item_id)))
}
Expand Down Expand Up @@ -1237,7 +1237,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
substs: &[Kind<'tcx>])
-> Ty<'tcx> {
let default = if def.has_default {
let default = self.tcx.item_type(def.def_id);
let default = self.tcx.type_of(def.def_id);
Some(type_variable::Default {
ty: default.subst_spanned(self.tcx, substs, Some(span)),
origin_span: span,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use std::fmt;
use syntax::attr;
use syntax::ast;
use syntax::symbol::Symbol;
use syntax_pos::{DUMMY_SP, MultiSpan, Span};
use syntax_pos::{MultiSpan, Span};
use errors::{self, Diagnostic, DiagnosticBuilder};
use hir;
use hir::def_id::LOCAL_CRATE;
Expand Down Expand Up @@ -1234,7 +1234,7 @@ fn check_lint_name_cmdline(sess: &Session, lint_cx: &LintStore,
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck);

let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);

let krate = tcx.hir.krate();

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/const_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub use rustc_const_math::ConstInt;
use hir;
use hir::def::Def;
use hir::def_id::DefId;
use ty::{self, TyCtxt};
use ty::TyCtxt;
use ty::subst::Substs;
use util::common::ErrorReported;
use rustc_const_math::*;
Expand Down Expand Up @@ -228,7 +228,7 @@ pub fn eval_length(tcx: TyCtxt,
let count_expr = &tcx.hir.body(count).value;
let count_def_id = tcx.hir.body_owner_def_id(count);
let substs = Substs::empty();
match ty::queries::const_eval::get(tcx, count_expr.span, (count_def_id, substs)) {
match tcx.at(count_expr.span).const_eval((count_def_id, substs)) {
Ok(Integral(Usize(count))) => {
let val = count.as_u64(tcx.sess.target.uint_type);
assert_eq!(val as usize as u64, val);
Expand Down
7 changes: 3 additions & 4 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use util::nodemap::FxHashSet;

use syntax::{ast, codemap};
use syntax::attr;
use syntax::codemap::DUMMY_SP;
use syntax_pos;

// Any local node that may call something in its body block should be
Expand Down Expand Up @@ -160,7 +159,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
match item.node {
hir::ItemStruct(..) | hir::ItemUnion(..) => {
let def_id = self.tcx.hir.local_def_id(item.id);
let def = self.tcx.lookup_adt_def(def_id);
let def = self.tcx.adt_def(def_id);
self.struct_has_extern_repr = def.repr.c();

intravisit::walk_item(self, &item);
Expand Down Expand Up @@ -433,7 +432,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
}

fn should_warn_about_field(&mut self, field: &hir::StructField) -> bool {
let field_type = self.tcx.item_type(self.tcx.hir.local_def_id(field.id));
let field_type = self.tcx.type_of(self.tcx.hir.local_def_id(field.id));
let is_marker_field = match field_type.ty_to_def_id() {
Some(def_id) => self.tcx.lang_items.items().iter().any(|item| *item == Some(def_id)),
_ => false
Expand Down Expand Up @@ -593,7 +592,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
let krate = tcx.hir.krate();
let live_symbols = find_live(tcx, access_levels, krate);
let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
Def::Variant(variant_did) |
Def::VariantCtor(variant_did, ..) => {
let enum_did = tcx.parent_def_id(variant_did).unwrap();
let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() {
let downcast_cmt = if tcx.adt_def(enum_did).is_univariant() {
cmt_pat
} else {
let cmt_pat_ty = cmt_pat.ty;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
let intrinsic = match self.infcx.tcx.item_type(def_id).sty {
let intrinsic = match self.infcx.tcx.type_of(def_id).sty {
ty::TyFnDef(.., bfty) => bfty.abi() == RustIntrinsic,
_ => return false
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
entry_ln: LiveNode,
body: &hir::Body)
{
let fn_ty = self.ir.tcx.item_type(self.ir.tcx.hir.local_def_id(id));
let fn_ty = self.ir.tcx.type_of(self.ir.tcx.hir.local_def_id(id));
let fn_sig = match fn_ty.sty {
ty::TyClosure(closure_def_id, substs) => {
self.ir.tcx.closure_type(closure_def_id)
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
Def::VariantCtor(variant_did, ..) => {
// univariant enums do not need downcasts
let enum_did = self.tcx().parent_def_id(variant_did).unwrap();
if !self.tcx().lookup_adt_def(enum_did).is_univariant() {
if !self.tcx().adt_def(enum_did).is_univariant() {
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
} else {
cmt
Expand All @@ -1177,7 +1177,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
let expected_len = match def {
Def::VariantCtor(def_id, CtorKind::Fn) => {
let enum_def = self.tcx().parent_def_id(def_id).unwrap();
self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len()
self.tcx().adt_def(enum_def).variant_with_id(def_id).fields.len()
}
Def::StructCtor(_, CtorKind::Fn) => {
match self.pat_ty(&pat)?.sty {
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use util::nodemap::{NodeSet, FxHashSet};
use syntax::abi::Abi;
use syntax::ast;
use syntax::attr;
use syntax::codemap::DUMMY_SP;
use hir;
use hir::def_id::LOCAL_CRATE;
use hir::intravisit::{Visitor, NestedVisitorMap};
Expand Down Expand Up @@ -364,13 +363,13 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
}

pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<NodeSet> {
ty::queries::reachable_set::get(tcx, DUMMY_SP, LOCAL_CRATE)
tcx.reachable_set(LOCAL_CRATE)
}

fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> Rc<NodeSet> {
debug_assert!(crate_num == LOCAL_CRATE);

let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);

let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let sess = &tcx.sess;

let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);

if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api {
let krate = tcx.hir.krate();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ impl<'tcx> Operand<'tcx> {
) -> Self {
Operand::Constant(Constant {
span: span,
ty: tcx.item_type(def_id).subst(tcx, substs),
ty: tcx.type_of(def_id).subst(tcx, substs),
literal: Literal::Value { value: ConstVal::Function(def_id, substs) },
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl<'tcx> Rvalue<'tcx> {
)
}
AggregateKind::Adt(def, _, substs, _) => {
tcx.item_type(def.did).subst(tcx, substs)
tcx.type_of(def.did).subst(tcx, substs)
}
AggregateKind::Closure(did, substs) => {
tcx.mk_closure_from_closure_substs(did, substs)
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let mut self_match_impls = vec![];
let mut fuzzy_match_impls = vec![];

self.tcx.lookup_trait_def(trait_ref.def_id)
self.tcx.trait_def(trait_ref.def_id)
.for_each_relevant_impl(self.tcx, trait_self_ty, |def_id| {
let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
let impl_trait_ref = tcx
Expand Down Expand Up @@ -314,7 +314,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let trait_str = self.tcx.item_path_str(trait_ref.def_id);
if let Some(istring) = item.value_str() {
let istring = &*istring.as_str();
let generics = self.tcx.item_generics(trait_ref.def_id);
let generics = self.tcx.generics_of(trait_ref.def_id);
let generic_map = generics.types.iter().map(|param| {
(param.name.as_str().to_string(),
trait_ref.substs.type_for_def(param).to_string())
Expand Down Expand Up @@ -372,7 +372,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trait_ref.skip_binder().self_ty(),
true);
let mut impl_candidates = Vec::new();
let trait_def = self.tcx.lookup_trait_def(trait_ref.def_id());
let trait_def = self.tcx.trait_def(trait_ref.def_id());

match simp {
Some(simp) => trait_def.for_each_impl(self.tcx, |def_id| {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ pub fn get_vtable_methods<'a, 'tcx>(
// do not hold for this particular set of type parameters.
// Note that this method could then never be called, so we
// do not want to try and trans it, in that case (see #23435).
let predicates = tcx.item_predicates(def_id).instantiate_own(tcx, substs);
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
if !normalize_and_test_predicates(tcx, predicates.predicates) {
debug!("get_vtable_methods: predicates do not hold");
return None;
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub enum MethodViolationCode {
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn is_object_safe(self, trait_def_id: DefId) -> bool {
// Because we query yes/no results frequently, we keep a cache:
let def = self.lookup_trait_def(trait_def_id);
let def = self.trait_def(trait_def_id);

let result = def.object_safety().unwrap_or_else(|| {
let result = self.object_safety_violations(trait_def_id).is_empty();
Expand Down Expand Up @@ -167,9 +167,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
substs: Substs::identity_for_item(self, trait_def_id)
});
let predicates = if supertraits_only {
self.item_super_predicates(trait_def_id)
self.super_predicates_of(trait_def_id)
} else {
self.item_predicates(trait_def_id)
self.predicates_of(trait_def_id)
};
predicates
.predicates
Expand Down Expand Up @@ -208,7 +208,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let free_substs = self.construct_free_substs(def_id,
self.region_maps.node_extent(ast::DUMMY_NODE_ID));
let predicates = self.item_predicates(def_id);
let predicates = self.predicates_of(def_id);
let predicates = predicates.instantiate(self, free_substs).predicates;
elaborate_predicates(self, predicates)
.any(|predicate| {
Expand Down Expand Up @@ -281,7 +281,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

// The `Self` type is erased, so it should not appear in list of
// arguments or return type apart from the receiver.
let ref sig = self.item_type(method.def_id).fn_sig();
let ref sig = self.type_of(method.def_id).fn_sig();
for input_ty in &sig.skip_binder().inputs()[1..] {
if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
return Some(MethodViolationCode::ReferencesSelf);
Expand All @@ -292,7 +292,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

// We can't monomorphize things like `fn foo<A>(...)`.
if !self.item_generics(method.def_id).types.is_empty() {
if !self.generics_of(method.def_id).types.is_empty() {
return Some(MethodViolationCode::Generic);
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => { // (*)
// Only normalize `impl Trait` after type-checking, usually in trans.
if self.selcx.projection_mode() == Reveal::All {
let generic_ty = self.tcx().item_type(def_id);
let generic_ty = self.tcx().type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx(), substs);
self.fold_ty(concrete_ty)
} else {
Expand Down Expand Up @@ -787,7 +787,7 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
};

// If so, extract what we know from the trait and try to come up with a good answer.
let trait_predicates = selcx.tcx().item_predicates(def_id);
let trait_predicates = selcx.tcx().predicates_of(def_id);
let bounds = trait_predicates.instantiate(selcx.tcx(), substs);
let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates);
assemble_candidates_from_predicates(selcx,
Expand Down Expand Up @@ -1288,7 +1288,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
obligation.predicate.trait_ref);
tcx.types.err
} else {
tcx.item_type(node_item.item.def_id)
tcx.type_of(node_item.item.def_id)
};
let substs = translate_substs(selcx.infcx(), impl_def_id, substs, node_item.node);
Progress {
Expand Down Expand Up @@ -1317,7 +1317,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>(
-> Option<specialization_graph::NodeItem<ty::AssociatedItem>>
{
let trait_def_id = selcx.tcx().impl_trait_ref(impl_def_id).unwrap().def_id;
let trait_def = selcx.tcx().lookup_trait_def(trait_def_id);
let trait_def = selcx.tcx().trait_def(trait_def_id);

if !trait_def.is_complete(selcx.tcx()) {
let impl_node = specialization_graph::Node::Impl(impl_def_id);
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn filter_negative_impls(&self, candidate: SelectionCandidate<'tcx>)
-> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
if let ImplCandidate(def_id) = candidate {
if self.tcx().trait_impl_polarity(def_id) == hir::ImplPolarity::Negative {
if self.tcx().impl_polarity(def_id) == hir::ImplPolarity::Negative {
return Err(Unimplemented)
}
}
Expand Down Expand Up @@ -1222,8 +1222,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
def_id={:?}, substs={:?}",
def_id, substs);

let item_predicates = self.tcx().item_predicates(def_id);
let bounds = item_predicates.instantiate(self.tcx(), substs);
let predicates_of = self.tcx().predicates_of(def_id);
let bounds = predicates_of.instantiate(self.tcx(), substs);
debug!("match_projection_obligation_against_definition_bounds: \
bounds={:?}",
bounds);
Expand Down Expand Up @@ -1432,7 +1432,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
{
debug!("assemble_candidates_from_impls(obligation={:?})", obligation);

let def = self.tcx().lookup_trait_def(obligation.predicate.def_id());
let def = self.tcx().trait_def(obligation.predicate.def_id());

def.for_each_relevant_impl(
self.tcx(),
Expand Down Expand Up @@ -1947,7 +1947,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
vec![self.tcx().item_type(def_id).subst(self.tcx(), substs)]
vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]
}
}
}
Expand Down Expand Up @@ -2526,7 +2526,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
(&ty::TyAdt(def, substs_a), &ty::TyAdt(_, substs_b)) => {
let fields = def
.all_fields()
.map(|f| tcx.item_type(f.did))
.map(|f| tcx.type_of(f.did))
.collect::<Vec<_>>();

// The last field of the structure has to exist and contain type parameters.
Expand Down Expand Up @@ -2844,7 +2844,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
// `$1: Copy`, so we must ensure the obligations are emitted in
// that order.
let predicates = tcx.item_predicates(def_id);
let predicates = tcx.predicates_of(def_id);
assert_eq!(predicates.parent, None);
let predicates = predicates.predicates.iter().flat_map(|predicate| {
let predicate = normalize_with_depth(self, cause.clone(), recursion_depth,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub fn find_associated_item<'a, 'tcx>(
assert!(!substs.needs_infer());

let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
let trait_def = tcx.lookup_trait_def(trait_def_id);
let trait_def = tcx.trait_def(trait_def_id);

let ancestors = trait_def.ancestors(impl_data.impl_def_id);
match ancestors.defs(tcx, item.name, item.kind).next() {
Expand Down Expand Up @@ -175,7 +175,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// See RFC 1210 for more details and justification.

// Currently we do not allow e.g. a negative impl to specialize a positive one
if tcx.trait_impl_polarity(impl1_def_id) != tcx.trait_impl_polarity(impl2_def_id) {
if tcx.impl_polarity(impl1_def_id) != tcx.impl_polarity(impl2_def_id) {
return false;
}

Expand Down
Loading

0 comments on commit b0a4074

Please sign in to comment.