2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 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.
|
|
|
|
|
2012-07-25 20:36:18 -05:00
|
|
|
// Detecting language items.
|
|
|
|
//
|
|
|
|
// Language items are items that represent concepts intrinsic to the language
|
|
|
|
// itself. Examples are:
|
|
|
|
//
|
2014-08-05 18:40:04 -05:00
|
|
|
// * Traits that specify "kinds"; e.g. "Sync", "Send".
|
2012-07-25 20:36:18 -05:00
|
|
|
//
|
2013-06-05 16:52:27 -05:00
|
|
|
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
|
2012-07-25 20:36:18 -05:00
|
|
|
//
|
|
|
|
// * Functions called by the compiler itself.
|
|
|
|
|
2014-11-06 02:05:53 -06:00
|
|
|
pub use self::LangItem::*;
|
2013-05-17 17:28:44 -05:00
|
|
|
|
2014-11-15 19:30:33 -06:00
|
|
|
use session::Session;
|
2013-03-26 15:38:07 -05:00
|
|
|
use metadata::csearch::each_lang_item;
|
2014-03-03 16:27:46 -06:00
|
|
|
use middle::ty;
|
2014-05-19 11:30:09 -05:00
|
|
|
use middle::weak_lang_items;
|
2014-11-09 16:59:56 -06:00
|
|
|
use util::nodemap::FnvHashMap;
|
|
|
|
|
2013-10-22 17:13:18 -05:00
|
|
|
use syntax::ast;
|
2013-03-26 15:38:07 -05:00
|
|
|
use syntax::ast_util::local_def;
|
2013-07-19 06:51:37 -05:00
|
|
|
use syntax::attr::AttrMetaMethods;
|
2014-07-17 12:56:37 -05:00
|
|
|
use syntax::codemap::{DUMMY_SP, Span};
|
2014-01-10 16:02:36 -06:00
|
|
|
use syntax::parse::token::InternedString;
|
2013-08-13 08:30:08 -05:00
|
|
|
use syntax::visit::Visitor;
|
2014-01-10 16:02:36 -06:00
|
|
|
use syntax::visit;
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2013-09-29 19:34:36 -05:00
|
|
|
use std::iter::Enumerate;
|
2014-03-08 17:11:52 -06:00
|
|
|
use std::slice;
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2013-12-05 22:24:25 -06:00
|
|
|
// The actual lang items defined come at the end of this file in one handy table.
|
|
|
|
// So you probably just want to nip down to the end.
|
|
|
|
macro_rules! lets_do_this {
|
2014-01-18 21:15:57 -06:00
|
|
|
(
|
2014-01-07 22:39:15 -06:00
|
|
|
$( $variant:ident, $name:expr, $method:ident; )*
|
2013-12-05 22:24:25 -06:00
|
|
|
) => {
|
|
|
|
|
2014-05-31 12:43:52 -05:00
|
|
|
#[deriving(FromPrimitive, PartialEq, Eq, Hash)]
|
2013-01-06 14:05:34 -06:00
|
|
|
pub enum LangItem {
|
2013-12-05 22:24:25 -06:00
|
|
|
$($variant),*
|
2013-01-06 14:05:34 -06:00
|
|
|
}
|
|
|
|
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 19:01:33 -06:00
|
|
|
impl Copy for LangItem {}
|
|
|
|
|
2013-01-30 15:44:24 -06:00
|
|
|
pub struct LanguageItems {
|
2014-05-19 11:30:09 -05:00
|
|
|
pub items: Vec<Option<ast::DefId>>,
|
|
|
|
pub missing: Vec<LangItem>,
|
2012-08-27 16:08:37 -05:00
|
|
|
}
|
|
|
|
|
2013-05-31 17:17:22 -05:00
|
|
|
impl LanguageItems {
|
2013-03-21 21:07:54 -05:00
|
|
|
pub fn new() -> LanguageItems {
|
2014-01-07 22:39:15 -06:00
|
|
|
fn foo(_: LangItem) -> Option<ast::DefId> { None }
|
|
|
|
|
2012-08-27 16:08:37 -05:00
|
|
|
LanguageItems {
|
2014-05-19 11:30:09 -05:00
|
|
|
items: vec!($(foo($variant)),*),
|
|
|
|
missing: Vec::new(),
|
2012-08-27 16:08:37 -05:00
|
|
|
}
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
|
2014-03-08 17:11:52 -06:00
|
|
|
pub fn items<'a>(&'a self) -> Enumerate<slice::Items<'a, Option<ast::DefId>>> {
|
2013-09-29 19:34:36 -05:00
|
|
|
self.items.iter().enumerate()
|
2013-05-03 12:08:08 -05:00
|
|
|
}
|
2013-01-07 12:51:53 -06:00
|
|
|
|
2013-03-21 21:07:54 -05:00
|
|
|
pub fn item_name(index: uint) -> &'static str {
|
2014-01-07 22:39:15 -06:00
|
|
|
let item: Option<LangItem> = FromPrimitive::from_uint(index);
|
|
|
|
match item {
|
|
|
|
$( Some($variant) => $name, )*
|
|
|
|
None => "???"
|
2013-01-07 12:51:53 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:57:53 -05:00
|
|
|
pub fn require(&self, it: LangItem) -> Result<ast::DefId, String> {
|
2014-10-15 01:05:01 -05:00
|
|
|
match self.items[it as uint] {
|
|
|
|
Some(id) => Ok(id),
|
|
|
|
None => {
|
2014-05-27 22:44:58 -05:00
|
|
|
Err(format!("requires `{}` lang_item",
|
|
|
|
LanguageItems::item_name(it as uint)))
|
2014-03-08 14:36:22 -06:00
|
|
|
}
|
2013-07-15 22:42:13 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-12 09:53:35 -05:00
|
|
|
pub fn from_builtin_kind(&self, bound: ty::BuiltinBound)
|
|
|
|
-> Result<ast::DefId, String>
|
|
|
|
{
|
|
|
|
match bound {
|
|
|
|
ty::BoundSend => self.require(SendTraitLangItem),
|
|
|
|
ty::BoundSized => self.require(SizedTraitLangItem),
|
|
|
|
ty::BoundCopy => self.require(CopyTraitLangItem),
|
|
|
|
ty::BoundSync => self.require(SyncTraitLangItem),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-03 16:27:46 -06:00
|
|
|
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
|
2014-03-21 18:16:56 -05:00
|
|
|
if Some(id) == self.send_trait() {
|
2014-03-03 16:27:46 -06:00
|
|
|
Some(ty::BoundSend)
|
2013-08-16 15:57:42 -05:00
|
|
|
} else if Some(id) == self.sized_trait() {
|
2014-03-03 16:27:46 -06:00
|
|
|
Some(ty::BoundSized)
|
2014-03-26 18:01:11 -05:00
|
|
|
} else if Some(id) == self.copy_trait() {
|
|
|
|
Some(ty::BoundCopy)
|
2014-08-05 18:40:04 -05:00
|
|
|
} else if Some(id) == self.sync_trait() {
|
|
|
|
Some(ty::BoundSync)
|
2013-08-16 15:57:42 -05:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2013-08-14 17:13:16 -05:00
|
|
|
}
|
|
|
|
|
2013-12-05 22:24:25 -06:00
|
|
|
$(
|
2014-04-01 09:26:21 -05:00
|
|
|
#[allow(dead_code)]
|
2013-12-05 22:24:25 -06:00
|
|
|
pub fn $method(&self) -> Option<ast::DefId> {
|
2014-10-15 01:05:01 -05:00
|
|
|
self.items[$variant as uint]
|
2013-12-05 22:24:25 -06:00
|
|
|
}
|
|
|
|
)*
|
2013-01-06 14:05:34 -06:00
|
|
|
}
|
|
|
|
|
2014-03-05 08:36:01 -06:00
|
|
|
struct LanguageItemCollector<'a> {
|
2013-03-15 14:24:24 -05:00
|
|
|
items: LanguageItems,
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2014-03-05 08:36:01 -06:00
|
|
|
session: &'a Session,
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2014-11-09 16:59:56 -06:00
|
|
|
item_refs: FnvHashMap<&'static str, uint>,
|
2012-09-07 21:04:40 -05:00
|
|
|
}
|
|
|
|
|
2014-09-09 17:54:36 -05:00
|
|
|
impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
|
2014-09-12 05:10:30 -05:00
|
|
|
fn visit_item(&mut self, item: &ast::Item) {
|
2014-02-28 17:25:15 -06:00
|
|
|
match extract(item.attrs.as_slice()) {
|
2013-10-22 17:13:18 -05:00
|
|
|
Some(value) => {
|
2014-11-12 17:51:51 -06:00
|
|
|
let item_index = self.item_refs.get(value.get()).map(|x| *x);
|
2013-10-22 17:13:18 -05:00
|
|
|
|
|
|
|
match item_index {
|
|
|
|
Some(item_index) => {
|
2014-07-17 12:56:37 -05:00
|
|
|
self.collect_item(item_index, local_def(item.id), item.span)
|
2013-08-13 08:30:08 -05:00
|
|
|
}
|
2013-10-22 17:13:18 -05:00
|
|
|
None => {}
|
2013-08-13 08:30:08 -05:00
|
|
|
}
|
2013-10-22 17:13:18 -05:00
|
|
|
}
|
|
|
|
None => {}
|
|
|
|
}
|
2013-08-13 08:30:08 -05:00
|
|
|
|
2014-09-12 05:10:30 -05:00
|
|
|
visit::walk_item(self, item);
|
2013-08-13 08:30:08 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-05 08:36:01 -06:00
|
|
|
impl<'a> LanguageItemCollector<'a> {
|
|
|
|
pub fn new(session: &'a Session) -> LanguageItemCollector<'a> {
|
2014-11-09 16:59:56 -06:00
|
|
|
let mut item_refs = FnvHashMap::new();
|
2013-06-27 08:04:22 -05:00
|
|
|
|
2013-12-05 22:24:25 -06:00
|
|
|
$( item_refs.insert($name, $variant as uint); )*
|
2013-06-27 08:04:22 -05:00
|
|
|
|
|
|
|
LanguageItemCollector {
|
|
|
|
session: session,
|
|
|
|
items: LanguageItems::new(),
|
|
|
|
item_refs: item_refs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-17 12:56:37 -05:00
|
|
|
pub fn collect_item(&mut self, item_index: uint,
|
|
|
|
item_def_id: ast::DefId, span: Span) {
|
2013-01-07 12:51:53 -06:00
|
|
|
// Check for duplicates.
|
2014-10-15 01:05:01 -05:00
|
|
|
match self.items.items[item_index] {
|
|
|
|
Some(original_def_id) if original_def_id != item_def_id => {
|
2014-07-17 12:56:37 -05:00
|
|
|
span_err!(self.session, span, E0152,
|
|
|
|
"duplicate entry for `{}`", LanguageItems::item_name(item_index));
|
2013-01-07 12:51:53 -06:00
|
|
|
}
|
2014-10-15 01:05:01 -05:00
|
|
|
Some(_) | None => {
|
2013-01-07 12:51:53 -06:00
|
|
|
// OK.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Matched.
|
2014-11-06 11:25:16 -06:00
|
|
|
self.items.items[item_index] = Some(item_def_id);
|
2013-01-07 12:51:53 -06:00
|
|
|
}
|
|
|
|
|
2014-02-05 15:15:24 -06:00
|
|
|
pub fn collect_local_language_items(&mut self, krate: &ast::Crate) {
|
2014-09-12 05:10:30 -05:00
|
|
|
visit::walk_crate(self, krate);
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
|
2013-05-31 17:17:22 -05:00
|
|
|
pub fn collect_external_language_items(&mut self) {
|
2014-03-09 08:20:44 -05:00
|
|
|
let crate_store = &self.session.cstore;
|
2013-12-25 14:08:04 -06:00
|
|
|
crate_store.iter_crate_data(|crate_number, _crate_metadata| {
|
2013-11-21 17:42:55 -06:00
|
|
|
each_lang_item(crate_store, crate_number, |node_id, item_index| {
|
2014-02-05 15:15:24 -06:00
|
|
|
let def_id = ast::DefId { krate: crate_number, node: node_id };
|
2014-07-17 12:56:37 -05:00
|
|
|
self.collect_item(item_index, def_id, DUMMY_SP);
|
2013-08-02 01:17:20 -05:00
|
|
|
true
|
2013-11-21 17:42:55 -06:00
|
|
|
});
|
|
|
|
})
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
|
2014-02-05 15:15:24 -06:00
|
|
|
pub fn collect(&mut self, krate: &ast::Crate) {
|
|
|
|
self.collect_local_language_items(krate);
|
2012-07-25 20:36:18 -05:00
|
|
|
self.collect_external_language_items();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-10 16:02:36 -06:00
|
|
|
pub fn extract(attrs: &[ast::Attribute]) -> Option<InternedString> {
|
2013-10-22 17:13:18 -05:00
|
|
|
for attribute in attrs.iter() {
|
2014-06-08 01:02:48 -05:00
|
|
|
match attribute.value_str() {
|
|
|
|
Some(ref value) if attribute.check_name("lang") => {
|
|
|
|
return Some(value.clone());
|
2013-10-22 17:13:18 -05:00
|
|
|
}
|
2014-06-08 01:02:48 -05:00
|
|
|
_ => {}
|
2013-10-22 17:13:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2014-02-05 15:15:24 -06:00
|
|
|
pub fn collect_language_items(krate: &ast::Crate,
|
2014-04-10 08:58:20 -05:00
|
|
|
session: &Session) -> LanguageItems {
|
2013-10-22 17:13:18 -05:00
|
|
|
let mut collector = LanguageItemCollector::new(session);
|
2014-02-05 15:15:24 -06:00
|
|
|
collector.collect(krate);
|
2014-05-19 11:30:09 -05:00
|
|
|
let LanguageItemCollector { mut items, .. } = collector;
|
|
|
|
weak_lang_items::check_crate(krate, session, &mut items);
|
2013-06-14 19:55:38 -05:00
|
|
|
session.abort_if_errors();
|
2014-04-10 08:58:20 -05:00
|
|
|
items
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
2013-12-05 22:24:25 -06:00
|
|
|
|
|
|
|
// End of the macro
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lets_do_this! {
|
2014-01-07 22:39:15 -06:00
|
|
|
// Variant name, Name, Method name;
|
|
|
|
SendTraitLangItem, "send", send_trait;
|
|
|
|
SizedTraitLangItem, "sized", sized_trait;
|
2014-03-26 18:01:11 -05:00
|
|
|
CopyTraitLangItem, "copy", copy_trait;
|
2014-08-05 18:40:04 -05:00
|
|
|
SyncTraitLangItem, "sync", sync_trait;
|
2014-01-07 22:39:15 -06:00
|
|
|
|
|
|
|
DropTraitLangItem, "drop", drop_trait;
|
|
|
|
|
|
|
|
AddTraitLangItem, "add", add_trait;
|
|
|
|
SubTraitLangItem, "sub", sub_trait;
|
|
|
|
MulTraitLangItem, "mul", mul_trait;
|
|
|
|
DivTraitLangItem, "div", div_trait;
|
|
|
|
RemTraitLangItem, "rem", rem_trait;
|
|
|
|
NegTraitLangItem, "neg", neg_trait;
|
|
|
|
NotTraitLangItem, "not", not_trait;
|
|
|
|
BitXorTraitLangItem, "bitxor", bitxor_trait;
|
|
|
|
BitAndTraitLangItem, "bitand", bitand_trait;
|
|
|
|
BitOrTraitLangItem, "bitor", bitor_trait;
|
|
|
|
ShlTraitLangItem, "shl", shl_trait;
|
|
|
|
ShrTraitLangItem, "shr", shr_trait;
|
|
|
|
IndexTraitLangItem, "index", index_trait;
|
2014-07-03 16:32:41 -05:00
|
|
|
IndexMutTraitLangItem, "index_mut", index_mut_trait;
|
2014-09-15 03:48:58 -05:00
|
|
|
SliceTraitLangItem, "slice", slice_trait;
|
|
|
|
SliceMutTraitLangItem, "slice_mut", slice_mut_trait;
|
2014-01-07 22:39:15 -06:00
|
|
|
|
2014-03-10 16:55:15 -05:00
|
|
|
UnsafeTypeLangItem, "unsafe", unsafe_type;
|
|
|
|
|
2014-02-26 15:02:35 -06:00
|
|
|
DerefTraitLangItem, "deref", deref_trait;
|
|
|
|
DerefMutTraitLangItem, "deref_mut", deref_mut_trait;
|
|
|
|
|
2014-06-01 18:35:01 -05:00
|
|
|
FnTraitLangItem, "fn", fn_trait;
|
|
|
|
FnMutTraitLangItem, "fn_mut", fn_mut_trait;
|
|
|
|
FnOnceTraitLangItem, "fn_once", fn_once_trait;
|
|
|
|
|
2014-01-07 22:39:15 -06:00
|
|
|
EqTraitLangItem, "eq", eq_trait;
|
|
|
|
OrdTraitLangItem, "ord", ord_trait;
|
|
|
|
|
|
|
|
StrEqFnLangItem, "str_eq", str_eq_fn;
|
2014-05-19 11:30:09 -05:00
|
|
|
|
2014-10-09 14:17:22 -05:00
|
|
|
// A number of panic-related lang items. The `panic` item corresponds to
|
|
|
|
// divide-by-zero and various panic cases with `match`. The
|
|
|
|
// `panic_bounds_check` item is for indexing arrays.
|
2014-05-19 11:30:09 -05:00
|
|
|
//
|
|
|
|
// The `begin_unwind` lang item has a predefined symbol name and is sort of
|
|
|
|
// a "weak lang item" in the sense that a crate is not required to have it
|
|
|
|
// defined to use it, but a final product is required to define it
|
|
|
|
// somewhere. Additionally, there are restrictions on crates that use a weak
|
|
|
|
// lang item, but do not have it defined.
|
2014-10-09 14:17:22 -05:00
|
|
|
PanicFnLangItem, "panic", panic_fn;
|
|
|
|
PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn;
|
|
|
|
PanicFmtLangItem, "panic_fmt", panic_fmt;
|
2014-05-19 11:30:09 -05:00
|
|
|
|
2014-01-07 22:39:15 -06:00
|
|
|
ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
|
|
|
|
ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn;
|
|
|
|
StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
|
|
|
|
|
|
|
|
StartFnLangItem, "start", start_fn;
|
|
|
|
|
|
|
|
TyDescStructLangItem, "ty_desc", ty_desc;
|
|
|
|
OpaqueStructLangItem, "opaque", opaque;
|
|
|
|
|
|
|
|
TypeIdLangItem, "type_id", type_id;
|
|
|
|
|
2014-05-19 11:30:09 -05:00
|
|
|
EhPersonalityLangItem, "eh_personality", eh_personality;
|
2014-01-07 22:39:15 -06:00
|
|
|
|
|
|
|
ExchangeHeapLangItem, "exchange_heap", exchange_heap;
|
2014-05-02 16:53:33 -05:00
|
|
|
OwnedBoxLangItem, "owned_box", owned_box;
|
2014-01-07 22:39:15 -06:00
|
|
|
|
|
|
|
CovariantTypeItem, "covariant_type", covariant_type;
|
|
|
|
ContravariantTypeItem, "contravariant_type", contravariant_type;
|
|
|
|
InvariantTypeItem, "invariant_type", invariant_type;
|
|
|
|
|
|
|
|
CovariantLifetimeItem, "covariant_lifetime", covariant_lifetime;
|
|
|
|
ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
|
|
|
|
InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;
|
|
|
|
|
|
|
|
NoSendItem, "no_send_bound", no_send_bound;
|
2014-03-26 18:01:11 -05:00
|
|
|
NoCopyItem, "no_copy_bound", no_copy_bound;
|
2014-09-04 19:01:56 -05:00
|
|
|
NoSyncItem, "no_sync_bound", no_sync_bound;
|
2014-01-07 22:39:15 -06:00
|
|
|
ManagedItem, "managed_bound", managed_bound;
|
2014-05-19 11:30:09 -05:00
|
|
|
|
2014-07-21 22:54:28 -05:00
|
|
|
IteratorItem, "iterator", iterator;
|
|
|
|
|
2014-05-19 11:30:09 -05:00
|
|
|
StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
|
2013-12-05 22:24:25 -06:00
|
|
|
}
|