Review comments.
This commit is contained in:
parent
513eb744c0
commit
fc73e196d9
8 changed files with 77 additions and 76 deletions
|
@ -31,7 +31,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_trait_lang_item(&self, id: DefId) -> Option<ty::ClosureKind> {
|
pub fn fn_trait_kind_from_lang_item(&self, id: DefId) -> Option<ty::ClosureKind> {
|
||||||
let items = self.lang_items();
|
let items = self.lang_items();
|
||||||
match Some(id) {
|
match Some(id) {
|
||||||
x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
|
x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
|
||||||
|
|
|
@ -1634,7 +1634,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) -> Result<(), SelectionError<'tcx>> {
|
||||||
let kind = match self.tcx().fn_trait_lang_item(obligation.predicate.def_id()) {
|
let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) {
|
||||||
Some(k) => k,
|
Some(k) => k,
|
||||||
None => {
|
None => {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -1677,7 +1677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) -> Result<(), SelectionError<'tcx>> {
|
||||||
// We provide impl of all fn traits for fn pointers.
|
// We provide impl of all fn traits for fn pointers.
|
||||||
if self.tcx().fn_trait_lang_item(obligation.predicate.def_id()).is_none() {
|
if self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()).is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2889,7 +2889,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
let kind = self
|
let kind = self
|
||||||
.tcx()
|
.tcx()
|
||||||
.fn_trait_lang_item(obligation.predicate.def_id())
|
.fn_trait_kind_from_lang_item(obligation.predicate.def_id())
|
||||||
.unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
|
.unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
|
||||||
|
|
||||||
// Okay to skip binder because the substs on closure types never
|
// Okay to skip binder because the substs on closure types never
|
||||||
|
|
|
@ -450,7 +450,7 @@ fn resolve_associated_item<'tcx>(
|
||||||
substs: generator_data.substs,
|
substs: generator_data.substs,
|
||||||
}),
|
}),
|
||||||
traits::VtableClosure(closure_data) => {
|
traits::VtableClosure(closure_data) => {
|
||||||
let trait_closure_kind = tcx.fn_trait_lang_item(trait_id).unwrap();
|
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
|
||||||
Some(Instance::resolve_closure(
|
Some(Instance::resolve_closure(
|
||||||
tcx,
|
tcx,
|
||||||
closure_data.closure_def_id,
|
closure_data.closure_def_id,
|
||||||
|
|
|
@ -724,7 +724,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
let mut resugared = false;
|
let mut resugared = false;
|
||||||
|
|
||||||
// Special-case `Fn(...) -> ...` and resugar it.
|
// Special-case `Fn(...) -> ...` and resugar it.
|
||||||
let fn_trait_kind = self.tcx().fn_trait_lang_item(principal.def_id);
|
let fn_trait_kind = self.tcx().fn_trait_kind_from_lang_item(principal.def_id);
|
||||||
if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
|
if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
|
||||||
if let ty::Tuple(ref args) = principal.substs.type_at(0).kind {
|
if let ty::Tuple(ref args) = principal.substs.type_at(0).kind {
|
||||||
let mut projections = predicates.projection_bounds();
|
let mut projections = predicates.projection_bounds();
|
||||||
|
|
|
@ -28,76 +28,76 @@ macro_rules! language_item_table {
|
||||||
$( $variant:ident, $name:expr, $method:ident, $target:path; )*
|
$( $variant:ident, $name:expr, $method:ident, $target:path; )*
|
||||||
) => {
|
) => {
|
||||||
|
|
||||||
enum_from_u32! {
|
enum_from_u32! {
|
||||||
/// A representation of all the valid language items in Rust.
|
/// A representation of all the valid language items in Rust.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||||
pub enum LangItem {
|
pub enum LangItem {
|
||||||
$($variant,)*
|
$($variant,)*
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl LangItem {
|
|
||||||
/// Returns the `name` in `#[lang = "$name"]`.
|
|
||||||
/// For example, `LangItem::EqTraitLangItem`,
|
|
||||||
/// that is `#[lang = "eq"]` would result in `"eq"`.
|
|
||||||
pub fn name(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
$( $variant => $name, )*
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(HashStable_Generic)]
|
impl LangItem {
|
||||||
pub struct LanguageItems {
|
/// Returns the `name` in `#[lang = "$name"]`.
|
||||||
/// Mappings from lang items to their possibly found `DefId`s.
|
/// For example, `LangItem::EqTraitLangItem`,
|
||||||
/// The index corresponds to the order in `LangItem`.
|
/// that is `#[lang = "eq"]` would result in `"eq"`.
|
||||||
pub items: Vec<Option<DefId>>,
|
pub fn name(self) -> &'static str {
|
||||||
/// Lang items that were not found during collection.
|
match self {
|
||||||
pub missing: Vec<LangItem>,
|
$( $variant => $name, )*
|
||||||
}
|
}
|
||||||
|
}
|
||||||
impl LanguageItems {
|
|
||||||
/// Construct an empty collection of lang items and no missing ones.
|
|
||||||
pub fn new() -> Self {
|
|
||||||
fn init_none(_: LangItem) -> Option<DefId> { None }
|
|
||||||
|
|
||||||
Self {
|
|
||||||
items: vec![$(init_none($variant)),*],
|
|
||||||
missing: Vec::new(),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the mappings to the possibly found `DefId`s for each lang item.
|
#[derive(HashStable_Generic)]
|
||||||
pub fn items(&self) -> &[Option<DefId>] {
|
pub struct LanguageItems {
|
||||||
&*self.items
|
/// Mappings from lang items to their possibly found `DefId`s.
|
||||||
}
|
/// The index corresponds to the order in `LangItem`.
|
||||||
|
pub items: Vec<Option<DefId>>,
|
||||||
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
|
/// Lang items that were not found during collection.
|
||||||
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
|
pub missing: Vec<LangItem>,
|
||||||
/// returns an error message as a string.
|
|
||||||
pub fn require(&self, it: LangItem) -> Result<DefId, String> {
|
|
||||||
self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name()))
|
|
||||||
}
|
|
||||||
|
|
||||||
$(
|
|
||||||
/// Returns the corresponding `DefId` for the lang item
|
|
||||||
#[doc = $name]
|
|
||||||
/// if it exists.
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn $method(&self) -> Option<DefId> {
|
|
||||||
self.items[$variant as usize]
|
|
||||||
}
|
}
|
||||||
)*
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
impl LanguageItems {
|
||||||
/// A mapping from the name of the lang item to its order and the form it must be of.
|
/// Construct an empty collection of lang items and no missing ones.
|
||||||
pub static ref ITEM_REFS: FxHashMap<&'static str, (usize, Target)> = {
|
pub fn new() -> Self {
|
||||||
let mut item_refs = FxHashMap::default();
|
fn init_none(_: LangItem) -> Option<DefId> { None }
|
||||||
$( item_refs.insert($name, ($variant as usize, $target)); )*
|
|
||||||
item_refs
|
Self {
|
||||||
};
|
items: vec![$(init_none($variant)),*],
|
||||||
}
|
missing: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the mappings to the possibly found `DefId`s for each lang item.
|
||||||
|
pub fn items(&self) -> &[Option<DefId>] {
|
||||||
|
&*self.items
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
|
||||||
|
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
|
||||||
|
/// returns an error message as a string.
|
||||||
|
pub fn require(&self, it: LangItem) -> Result<DefId, String> {
|
||||||
|
self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name()))
|
||||||
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
/// Returns the corresponding `DefId` for the lang item
|
||||||
|
#[doc = $name]
|
||||||
|
/// if it exists.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn $method(&self) -> Option<DefId> {
|
||||||
|
self.items[$variant as usize]
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// A mapping from the name of the lang item to its order and the form it must be of.
|
||||||
|
pub static ref ITEM_REFS: FxHashMap<&'static str, (usize, Target)> = {
|
||||||
|
let mut item_refs = FxHashMap::default();
|
||||||
|
$( item_refs.insert($name, ($variant as usize, $target)); )*
|
||||||
|
item_refs
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// End of the macro
|
// End of the macro
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
|
||||||
),
|
),
|
||||||
ty::InstanceDef::FnPtrShim(def_id, ty) => {
|
ty::InstanceDef::FnPtrShim(def_id, ty) => {
|
||||||
let trait_ = tcx.trait_of_item(def_id).unwrap();
|
let trait_ = tcx.trait_of_item(def_id).unwrap();
|
||||||
let adjustment = match tcx.fn_trait_lang_item(trait_) {
|
let adjustment = match tcx.fn_trait_kind_from_lang_item(trait_) {
|
||||||
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
|
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
|
||||||
Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref,
|
Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref,
|
||||||
None => bug!("fn pointer {:?} is not an fn", ty),
|
None => bug!("fn pointer {:?} is not an fn", ty),
|
||||||
|
|
|
@ -174,8 +174,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.deduce_sig_from_projection(None, &pb)
|
self.deduce_sig_from_projection(None, &pb)
|
||||||
})
|
})
|
||||||
.next();
|
.next();
|
||||||
let kind =
|
let kind = object_type
|
||||||
object_type.principal_def_id().and_then(|did| self.tcx.fn_trait_lang_item(did));
|
.principal_def_id()
|
||||||
|
.and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did));
|
||||||
(sig, kind)
|
(sig, kind)
|
||||||
}
|
}
|
||||||
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
|
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
|
||||||
|
@ -213,7 +214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// many viable options, so pick the most restrictive.
|
// many viable options, so pick the most restrictive.
|
||||||
let expected_kind = self
|
let expected_kind = self
|
||||||
.obligations_for_self_ty(expected_vid)
|
.obligations_for_self_ty(expected_vid)
|
||||||
.filter_map(|(tr, _)| self.tcx.fn_trait_lang_item(tr.def_id()))
|
.filter_map(|(tr, _)| self.tcx.fn_trait_kind_from_lang_item(tr.def_id()))
|
||||||
.fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur))));
|
.fold(None, |best, cur| Some(best.map_or(cur, |best| cmp::min(best, cur))));
|
||||||
|
|
||||||
(expected_sig, expected_kind)
|
(expected_sig, expected_kind)
|
||||||
|
@ -236,7 +237,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let trait_ref = projection.to_poly_trait_ref(tcx);
|
let trait_ref = projection.to_poly_trait_ref(tcx);
|
||||||
|
|
||||||
let is_fn = tcx.fn_trait_lang_item(trait_ref.def_id()).is_some();
|
let is_fn = tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some();
|
||||||
let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem, cause_span);
|
let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem, cause_span);
|
||||||
let is_gen = gen_trait == trait_ref.def_id();
|
let is_gen = gen_trait == trait_ref.def_id();
|
||||||
if !is_fn && !is_gen {
|
if !is_fn && !is_gen {
|
||||||
|
|
|
@ -138,7 +138,7 @@ pub fn external_generic_args(
|
||||||
|
|
||||||
match trait_did {
|
match trait_did {
|
||||||
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
||||||
Some(did) if cx.tcx.fn_trait_lang_item(did).is_some() => {
|
Some(did) if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() => {
|
||||||
assert!(ty_kind.is_some());
|
assert!(ty_kind.is_some());
|
||||||
let inputs = match ty_kind {
|
let inputs = match ty_kind {
|
||||||
Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
|
Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue