Skip to content

Commit 70ae917

Browse files
committed
Rollup merge of rust-lang#49211 - varkor:chalk-lowering-Implemented-From-Env, r=nikomatsakis
Implement Chalk lowering rule "Implemented-From-Env" This extends the Chalk lowering pass with the "Implemented-From-Env" rule for generating program clauses from a trait definition as part of rust-lang#49177. r? @nikomatsakis
2 parents 34eca53 + 7791995 commit 70ae917

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

src/librustc_traits/lowering.rs

+45-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc::hir::{self, ImplPolarity};
1212
use rustc::hir::def_id::DefId;
1313
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
1414
use rustc::ty::{self, TyCtxt};
15+
use rustc::ty::subst::Substs;
1516
use rustc::traits::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom};
1617
use syntax::ast;
1718
use rustc_data_structures::sync::Lrc;
@@ -104,29 +105,69 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI
104105
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
105106
let item = tcx.hir.expect_item(node_id);
106107
match item.node {
108+
hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id),
107109
hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id),
108110

109111
// FIXME: other constructions e.g. traits, associated types...
110112
_ => Lrc::new(vec![]),
111113
}
112114
}
113115

116+
fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
117+
-> Lrc<Vec<Clause<'tcx>>>
118+
{
119+
// Rule Implemented-From-Env (see rustc guide)
120+
//
121+
// `trait Trait<P1..Pn> where WC { .. } // P0 == Self`
122+
//
123+
// ```
124+
// forall<Self, P1..Pn> {
125+
// Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)
126+
// }
127+
// ```
128+
129+
// `Self: Trait<P1..Pn>`
130+
let trait_pred = ty::TraitPredicate {
131+
trait_ref: ty::TraitRef {
132+
def_id,
133+
substs: Substs::identity_for_item(tcx, def_id)
134+
}
135+
};
136+
// `FromEnv(Self: Trait<P1..Pn>)`
137+
let from_env = Goal::DomainGoal(DomainGoal::FromEnv(trait_pred.lower()));
138+
// `Implemented(Self: Trait<P1..Pn>)`
139+
let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred));
140+
141+
// `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
142+
let clause = Clause::Implies(vec![from_env], impl_trait);
143+
Lrc::new(vec![clause])
144+
}
145+
114146
fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
115147
-> Lrc<Vec<Clause<'tcx>>>
116148
{
117149
if let ImplPolarity::Negative = tcx.impl_polarity(def_id) {
118150
return Lrc::new(vec![]);
119151
}
120152

121-
// Rule Implemented-From-Impl
153+
// Rule Implemented-From-Impl (see rustc guide)
154+
//
155+
// `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }`
122156
//
123-
// (see rustc guide)
157+
// ```
158+
// forall<P0..Pn> {
159+
// Implemented(A0: Trait<A1..An>) :- WC
160+
// }
161+
// ```
124162

125163
let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
126-
let trait_ref = ty::TraitPredicate { trait_ref }.lower();
164+
// `Implemented(A0: Trait<A1..An>)`
165+
let trait_pred = ty::TraitPredicate { trait_ref }.lower();
166+
// `WC`
127167
let where_clauses = tcx.predicates_of(def_id).predicates.lower();
128168

129-
let clause = Clause::Implies(where_clauses, trait_ref);
169+
// `Implemented(A0: Trait<A1..An>) :- WC`
170+
let clause = Clause::Implies(where_clauses, trait_pred);
130171
Lrc::new(vec![clause])
131172
}
132173

src/test/ui/chalkify/lower_trait.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2018 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+
#![feature(rustc_attrs)]
12+
13+
#[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
14+
trait Foo<S, T, U> {
15+
fn s(S) -> S;
16+
fn t(T) -> T;
17+
fn u(U) -> U;
18+
}
19+
20+
fn main() {
21+
println!("hello");
22+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: Implemented(Self: Foo<S, T, U>) :- FromEnv(Self: Foo<S, T, U>).
2+
--> $DIR/lower_trait.rs:13:1
3+
|
4+
LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo<S, T, U>) :-
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)