Skip to content

Commit 88a1b71

Browse files
committed
Make all lang_items optional
Whenever a lang_item is required, some relevant message is displayed, often with a span of what triggered the usage of the lang item
1 parent 9db1903 commit 88a1b71

18 files changed

+294
-179
lines changed

src/librustc/middle/kind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt<Context>)) {
122122
None => cx.tcx.sess.bug("trait ref not in def map!"),
123123
Some(&trait_def) => {
124124
let trait_def_id = ast_util::def_id_of_def(trait_def);
125-
if cx.tcx.lang_items.drop_trait() == trait_def_id {
125+
if cx.tcx.lang_items.drop_trait() == Some(trait_def_id) {
126126
// Yes, it's a destructor.
127127
match self_type.node {
128128
ty_path(_, ref bounds, path_node_id) => {

src/librustc/middle/lang_items.rs

+92-98
Original file line numberDiff line numberDiff line change
@@ -153,135 +153,143 @@ impl LanguageItems {
153153

154154
// FIXME #4621: Method macros sure would be nice here.
155155

156-
pub fn freeze_trait(&self) -> def_id {
157-
self.items[FreezeTraitLangItem as uint].get()
156+
pub fn require(&self, it: LangItem) -> Result<def_id, ~str> {
157+
match self.items[it as uint] {
158+
Some(id) => Ok(id),
159+
None => Err(fmt!("requires `%s` lang_item",
160+
LanguageItems::item_name(it as uint)))
161+
}
162+
}
163+
164+
pub fn freeze_trait(&self) -> Option<def_id> {
165+
self.items[FreezeTraitLangItem as uint]
158166
}
159-
pub fn copy_trait(&self) -> def_id {
160-
self.items[CopyTraitLangItem as uint].get()
167+
pub fn copy_trait(&self) -> Option<def_id> {
168+
self.items[CopyTraitLangItem as uint]
161169
}
162-
pub fn send_trait(&self) -> def_id {
163-
self.items[SendTraitLangItem as uint].get()
170+
pub fn send_trait(&self) -> Option<def_id> {
171+
self.items[SendTraitLangItem as uint]
164172
}
165-
pub fn sized_trait(&self) -> def_id {
166-
self.items[SizedTraitLangItem as uint].get()
173+
pub fn sized_trait(&self) -> Option<def_id> {
174+
self.items[SizedTraitLangItem as uint]
167175
}
168176

169-
pub fn drop_trait(&self) -> def_id {
170-
self.items[DropTraitLangItem as uint].get()
177+
pub fn drop_trait(&self) -> Option<def_id> {
178+
self.items[DropTraitLangItem as uint]
171179
}
172180

173-
pub fn add_trait(&self) -> def_id {
174-
self.items[AddTraitLangItem as uint].get()
181+
pub fn add_trait(&self) -> Option<def_id> {
182+
self.items[AddTraitLangItem as uint]
175183
}
176-
pub fn sub_trait(&self) -> def_id {
177-
self.items[SubTraitLangItem as uint].get()
184+
pub fn sub_trait(&self) -> Option<def_id> {
185+
self.items[SubTraitLangItem as uint]
178186
}
179-
pub fn mul_trait(&self) -> def_id {
180-
self.items[MulTraitLangItem as uint].get()
187+
pub fn mul_trait(&self) -> Option<def_id> {
188+
self.items[MulTraitLangItem as uint]
181189
}
182-
pub fn div_trait(&self) -> def_id {
183-
self.items[DivTraitLangItem as uint].get()
190+
pub fn div_trait(&self) -> Option<def_id> {
191+
self.items[DivTraitLangItem as uint]
184192
}
185-
pub fn rem_trait(&self) -> def_id {
186-
self.items[RemTraitLangItem as uint].get()
193+
pub fn rem_trait(&self) -> Option<def_id> {
194+
self.items[RemTraitLangItem as uint]
187195
}
188-
pub fn neg_trait(&self) -> def_id {
189-
self.items[NegTraitLangItem as uint].get()
196+
pub fn neg_trait(&self) -> Option<def_id> {
197+
self.items[NegTraitLangItem as uint]
190198
}
191-
pub fn not_trait(&self) -> def_id {
192-
self.items[NotTraitLangItem as uint].get()
199+
pub fn not_trait(&self) -> Option<def_id> {
200+
self.items[NotTraitLangItem as uint]
193201
}
194-
pub fn bitxor_trait(&self) -> def_id {
195-
self.items[BitXorTraitLangItem as uint].get()
202+
pub fn bitxor_trait(&self) -> Option<def_id> {
203+
self.items[BitXorTraitLangItem as uint]
196204
}
197-
pub fn bitand_trait(&self) -> def_id {
198-
self.items[BitAndTraitLangItem as uint].get()
205+
pub fn bitand_trait(&self) -> Option<def_id> {
206+
self.items[BitAndTraitLangItem as uint]
199207
}
200-
pub fn bitor_trait(&self) -> def_id {
201-
self.items[BitOrTraitLangItem as uint].get()
208+
pub fn bitor_trait(&self) -> Option<def_id> {
209+
self.items[BitOrTraitLangItem as uint]
202210
}
203-
pub fn shl_trait(&self) -> def_id {
204-
self.items[ShlTraitLangItem as uint].get()
211+
pub fn shl_trait(&self) -> Option<def_id> {
212+
self.items[ShlTraitLangItem as uint]
205213
}
206-
pub fn shr_trait(&self) -> def_id {
207-
self.items[ShrTraitLangItem as uint].get()
214+
pub fn shr_trait(&self) -> Option<def_id> {
215+
self.items[ShrTraitLangItem as uint]
208216
}
209-
pub fn index_trait(&self) -> def_id {
210-
self.items[IndexTraitLangItem as uint].get()
217+
pub fn index_trait(&self) -> Option<def_id> {
218+
self.items[IndexTraitLangItem as uint]
211219
}
212220

213-
pub fn eq_trait(&self) -> def_id {
214-
self.items[EqTraitLangItem as uint].get()
221+
pub fn eq_trait(&self) -> Option<def_id> {
222+
self.items[EqTraitLangItem as uint]
215223
}
216-
pub fn ord_trait(&self) -> def_id {
217-
self.items[OrdTraitLangItem as uint].get()
224+
pub fn ord_trait(&self) -> Option<def_id> {
225+
self.items[OrdTraitLangItem as uint]
218226
}
219227

220-
pub fn str_eq_fn(&self) -> def_id {
221-
self.items[StrEqFnLangItem as uint].get()
228+
pub fn str_eq_fn(&self) -> Option<def_id> {
229+
self.items[StrEqFnLangItem as uint]
222230
}
223-
pub fn uniq_str_eq_fn(&self) -> def_id {
224-
self.items[UniqStrEqFnLangItem as uint].get()
231+
pub fn uniq_str_eq_fn(&self) -> Option<def_id> {
232+
self.items[UniqStrEqFnLangItem as uint]
225233
}
226-
pub fn annihilate_fn(&self) -> def_id {
227-
self.items[AnnihilateFnLangItem as uint].get()
234+
pub fn annihilate_fn(&self) -> Option<def_id> {
235+
self.items[AnnihilateFnLangItem as uint]
228236
}
229-
pub fn log_type_fn(&self) -> def_id {
230-
self.items[LogTypeFnLangItem as uint].get()
237+
pub fn log_type_fn(&self) -> Option<def_id> {
238+
self.items[LogTypeFnLangItem as uint]
231239
}
232-
pub fn fail_fn(&self) -> def_id {
233-
self.items[FailFnLangItem as uint].get()
240+
pub fn fail_fn(&self) -> Option<def_id> {
241+
self.items[FailFnLangItem as uint]
234242
}
235-
pub fn fail_bounds_check_fn(&self) -> def_id {
236-
self.items[FailBoundsCheckFnLangItem as uint].get()
243+
pub fn fail_bounds_check_fn(&self) -> Option<def_id> {
244+
self.items[FailBoundsCheckFnLangItem as uint]
237245
}
238-
pub fn exchange_malloc_fn(&self) -> def_id {
239-
self.items[ExchangeMallocFnLangItem as uint].get()
246+
pub fn exchange_malloc_fn(&self) -> Option<def_id> {
247+
self.items[ExchangeMallocFnLangItem as uint]
240248
}
241-
pub fn closure_exchange_malloc_fn(&self) -> def_id {
242-
self.items[ClosureExchangeMallocFnLangItem as uint].get()
249+
pub fn closure_exchange_malloc_fn(&self) -> Option<def_id> {
250+
self.items[ClosureExchangeMallocFnLangItem as uint]
243251
}
244-
pub fn exchange_free_fn(&self) -> def_id {
245-
self.items[ExchangeFreeFnLangItem as uint].get()
252+
pub fn exchange_free_fn(&self) -> Option<def_id> {
253+
self.items[ExchangeFreeFnLangItem as uint]
246254
}
247-
pub fn malloc_fn(&self) -> def_id {
248-
self.items[MallocFnLangItem as uint].get()
255+
pub fn malloc_fn(&self) -> Option<def_id> {
256+
self.items[MallocFnLangItem as uint]
249257
}
250-
pub fn free_fn(&self) -> def_id {
251-
self.items[FreeFnLangItem as uint].get()
258+
pub fn free_fn(&self) -> Option<def_id> {
259+
self.items[FreeFnLangItem as uint]
252260
}
253-
pub fn borrow_as_imm_fn(&self) -> def_id {
254-
self.items[BorrowAsImmFnLangItem as uint].get()
261+
pub fn borrow_as_imm_fn(&self) -> Option<def_id> {
262+
self.items[BorrowAsImmFnLangItem as uint]
255263
}
256-
pub fn borrow_as_mut_fn(&self) -> def_id {
257-
self.items[BorrowAsMutFnLangItem as uint].get()
264+
pub fn borrow_as_mut_fn(&self) -> Option<def_id> {
265+
self.items[BorrowAsMutFnLangItem as uint]
258266
}
259-
pub fn return_to_mut_fn(&self) -> def_id {
260-
self.items[ReturnToMutFnLangItem as uint].get()
267+
pub fn return_to_mut_fn(&self) -> Option<def_id> {
268+
self.items[ReturnToMutFnLangItem as uint]
261269
}
262-
pub fn check_not_borrowed_fn(&self) -> def_id {
263-
self.items[CheckNotBorrowedFnLangItem as uint].get()
270+
pub fn check_not_borrowed_fn(&self) -> Option<def_id> {
271+
self.items[CheckNotBorrowedFnLangItem as uint]
264272
}
265-
pub fn strdup_uniq_fn(&self) -> def_id {
266-
self.items[StrDupUniqFnLangItem as uint].get()
273+
pub fn strdup_uniq_fn(&self) -> Option<def_id> {
274+
self.items[StrDupUniqFnLangItem as uint]
267275
}
268-
pub fn record_borrow_fn(&self) -> def_id {
269-
self.items[RecordBorrowFnLangItem as uint].get()
276+
pub fn record_borrow_fn(&self) -> Option<def_id> {
277+
self.items[RecordBorrowFnLangItem as uint]
270278
}
271-
pub fn unrecord_borrow_fn(&self) -> def_id {
272-
self.items[UnrecordBorrowFnLangItem as uint].get()
279+
pub fn unrecord_borrow_fn(&self) -> Option<def_id> {
280+
self.items[UnrecordBorrowFnLangItem as uint]
273281
}
274-
pub fn start_fn(&self) -> def_id {
275-
self.items[StartFnLangItem as uint].get()
282+
pub fn start_fn(&self) -> Option<def_id> {
283+
self.items[StartFnLangItem as uint]
276284
}
277-
pub fn ty_desc(&const self) -> def_id {
278-
self.items[TyDescStructLangItem as uint].get()
285+
pub fn ty_desc(&self) -> Option<def_id> {
286+
self.items[TyDescStructLangItem as uint]
279287
}
280-
pub fn ty_visitor(&const self) -> def_id {
281-
self.items[TyVisitorTraitLangItem as uint].get()
288+
pub fn ty_visitor(&self) -> Option<def_id> {
289+
self.items[TyVisitorTraitLangItem as uint]
282290
}
283-
pub fn opaque(&const self) -> def_id {
284-
self.items[OpaqueStructLangItem as uint].get()
291+
pub fn opaque(&self) -> Option<def_id> {
292+
self.items[OpaqueStructLangItem as uint]
285293
}
286294
}
287295

@@ -439,23 +447,9 @@ impl<'self> LanguageItemCollector<'self> {
439447
}
440448
}
441449

442-
pub fn check_completeness(&self) {
443-
for self.item_refs.iter().advance |(&key, &item_ref)| {
444-
match self.items.items[item_ref] {
445-
None => {
446-
self.session.err(fmt!("no item found for `%s`", key));
447-
}
448-
Some(_) => {
449-
// OK.
450-
}
451-
}
452-
}
453-
}
454-
455450
pub fn collect(&mut self) {
456451
self.collect_local_language_items();
457452
self.collect_external_language_items();
458-
self.check_completeness();
459453
}
460454
}
461455

src/librustc/middle/resolve.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -5268,8 +5268,13 @@ impl Resolver {
52685268

52695269
pub fn add_fixed_trait_for_expr(@mut self,
52705270
expr_id: node_id,
5271-
trait_id: def_id) {
5272-
self.trait_map.insert(expr_id, @mut ~[trait_id]);
5271+
trait_id: Option<def_id>) {
5272+
match trait_id {
5273+
Some(trait_id) => {
5274+
self.trait_map.insert(expr_id, @mut ~[trait_id]);
5275+
}
5276+
None => {}
5277+
}
52735278
}
52745279

52755280
pub fn record_def(@mut self, node_id: node_id, def: def) {

src/librustc/middle/trans/_match.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ use back::abi;
152152
use lib::llvm::{llvm, ValueRef, BasicBlockRef};
153153
use middle::const_eval;
154154
use middle::borrowck::root_map_key;
155+
use middle::lang_items::{UniqStrEqFnLangItem, StrEqFnLangItem};
155156
use middle::pat_util::*;
156157
use middle::resolve::DefMap;
157158
use middle::trans::adt;
@@ -1099,15 +1100,19 @@ pub fn compare_values(cx: block,
10991100
Store(cx, lhs, scratch_lhs);
11001101
let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs");
11011102
Store(cx, rhs, scratch_rhs);
1102-
let did = cx.tcx().lang_items.uniq_str_eq_fn();
1103+
let did = langcall(cx, None,
1104+
fmt!("comparison of `%s`", cx.ty_to_str(rhs_t)),
1105+
UniqStrEqFnLangItem);
11031106
let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None);
11041107
Result {
11051108
bcx: result.bcx,
11061109
val: bool_to_i1(result.bcx, result.val)
11071110
}
11081111
}
11091112
ty::ty_estr(_) => {
1110-
let did = cx.tcx().lang_items.str_eq_fn();
1113+
let did = langcall(cx, None,
1114+
fmt!("comparison of `%s`", cx.ty_to_str(rhs_t)),
1115+
StrEqFnLangItem);
11111116
let result = callee::trans_lang_call(cx, did, [lhs, rhs], None);
11121117
Result {
11131118
bcx: result.bcx,

0 commit comments

Comments
 (0)