Skip to content

Instantly share code, notes, and snippets.

@pnkfelix
Created January 14, 2015 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pnkfelix/e734baaa17109dadf427 to your computer and use it in GitHub Desktop.
Save pnkfelix/e734baaa17109dadf427 to your computer and use it in GitHub Desktop.
everybody loops copy of the rustc crate
// Copyright 2012-2013 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.
//! The Rust compiler.
//!
//! # Note
//!
//! This API is completely unstable and subject to change.
#![crate_name = "rustc"]
#![unstable]
#![staged_api]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url =
"http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![allow(unknown_features)]
#![feature(quote)]
#![feature(slicing_syntax, unsafe_destructor)]
#![feature(box_syntax)]
#![allow(unknown_features)]
#![feature(int_uint)]
#![feature(rustc_diagnostic_macros)]
#![allow(unused_variables)]
#![allow(unused_imports)]
#![allow(unused_mut)]
#![allow(unstable)]
#![allow(dead_code)]
extern crate arena;
extern crate flate;
extern crate fmt_macros;
extern crate getopts;
extern crate graphviz;
extern crate libc;
extern crate regex;
extern crate rustc_llvm;
extern crate rustc_back;
extern crate serialize;
extern crate rbml;
extern crate collections;
#[macro_use]
extern crate log;
#[macro_use]
extern crate syntax;
extern crate "serialize" as rustc_serialize;
// used by deriving
#[cfg(test)]
extern crate test;
pub use rustc_llvm as llvm;
mod diagnostics {
// A private module so that macro-expanded idents like
// `::rustc::lint::Lint` will also work in `rustc` itself.
//
// `libstd` uses the same trick.
#![allow(non_snake_case)]
register_diagnostic! (E0001 ,
r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being matched,
one of the preceeding patterns will match.
This means that perhaps some of the preceeding patterns are too general, this
one is too specific or the ordering is incorrect.
"##);
register_diagnostics! (E0002 , E0003 , E0004 , E0005 , E0006 , E0007 ,
E0008 , E0009 , E0010 , E0011 , E0012 , E0013 ,
E0014 , E0015 , E0016 , E0017 , E0018 , E0019 ,
E0020 , E0022 , E0109 , E0110 , E0133 , E0134 ,
E0135 , E0136 , E0137 , E0138 , E0139 , E0140 ,
E0152 , E0153 , E0157 , E0158 , E0161 , E0162 ,
E0165 , E0166 , E0167 , E0168 , E0169 , E0170 ,
E0171 , E0172 , E0173 , E0174 , E0177 , E0178 ,
E0179);
}
pub mod back {
pub use rustc_back::abi;
pub use rustc_back::archive;
pub use rustc_back::arm;
pub use rustc_back::mips;
pub use rustc_back::mipsel;
pub use rustc_back::rpath;
pub use rustc_back::svh;
pub use rustc_back::target_strs;
pub use rustc_back::x86;
pub use rustc_back::x86_64;
}
pub mod middle {
pub mod astconv_util {
/*!
* This module contains a simple utility routine
* used by both `typeck` and `const_eval`.
* Almost certainly this could (and should) be refactored out of existence.
*/
use middle::def;
use middle::ty::{self, Ty};
use syntax::ast;
use util::ppaux::Repr;
pub const NO_REGIONS: uint = 1;
pub const NO_TPS: uint = 2;
pub fn check_path_args(tcx: &ty::ctxt, path: &ast::Path,
flags: uint) {
loop { }
}
pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
-> Option<Ty<'tcx>> {
loop { }
}
}
pub mod astencode {
#![allow(non_camel_case_types)]
#![allow(unused_must_use)]
use metadata::common as c;
use metadata::cstore;
use session::Session;
use metadata::decoder;
use middle::def;
use metadata::encoder as e;
use middle::region;
use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId,
TypeParameter};
use metadata::tydecode::{RegionParameter, UnboxedClosureSource};
use metadata::tyencode;
use middle::mem_categorization::Typer;
use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
use util::ppaux::ty_to_string;
use syntax::{ast, ast_map, ast_util, codemap, fold};
use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span;
use syntax::fold::Folder;
use syntax::parse::token;
use syntax::ptr::P;
use syntax;
use std::io::Seek;
use std::rc::Rc;
use rbml::io::SeekableMemWriter;
use rbml::{reader, writer};
use rbml;
use serialize;
use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
use serialize::{EncoderHelpers};
#[cfg(test)]
use syntax::parse;
#[cfg(test)]
use syntax::print::pprust;
struct DecodeContext<'a, 'b, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
cdata: &'b cstore::crate_metadata,
from_id_range: ast_util::IdRange,
to_id_range: ast_util::IdRange,
}
trait tr {
fn tr(&self, dcx: &DecodeContext) -> Self;
}
trait tr_intern {
fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId;
}
pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
pub fn encode_inlined_item(ecx: &e::EncodeContext,
rbml_w: &mut Encoder,
ii: e::InlinedItemRef) {
loop { }
}
impl <'a, 'b, 'c, 'tcx> ast_map::FoldOps for
&'a DecodeContext<'b, 'c, 'tcx> {
fn new_id(&self, id: ast::NodeId) -> ast::NodeId { loop { } }
fn new_def_id(&self, def_id: ast::DefId) -> ast::DefId {
loop { }
}
fn new_span(&self, span: Span) -> Span { loop { } }
}
pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
tcx: &ty::ctxt<'tcx>,
path: Vec<ast_map::PathElem>,
par_doc: rbml::Doc)
-> Result<&'tcx ast::InlinedItem, Vec<ast_map::PathElem>> {
loop { }
}
fn reserve_id_range(sess: &Session, from_id_range: ast_util::IdRange)
-> ast_util::IdRange {
loop { }
}
impl <'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
/// Translates an internal id, meaning a node id that is known to refer to some part of the
/// item currently being inlined, such as a local variable or argument. All naked node-ids
/// that appear in types have this property, since if something might refer to an external item
/// we would use a def-id to allow for the possibility that the item resides in another crate.
pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId { loop { } }
/// Translates an EXTERNAL def-id, converting the crate number from the one used in the encoded
/// data to the current crate numbers.. By external, I mean that it be translated to a
/// reference to the item in its original crate, as opposed to being translated to a reference
/// to the inlined version of the item. This is typically, but not always, what you want,
/// because most def-ids refer to external things like types or other fns that may or may not
/// be inlined. Note that even when the inlined function is referencing itself recursively, we
/// would want `tr_def_id` for that reference--- conceptually the function calls the original,
/// non-inlined version, and trans deals with linking that recursive call to the inlined copy.
///
/// However, there are a *few* cases where def-ids are used but we know that the thing being
/// referenced is in fact *internal* to the item being inlined. In those cases, you should use
/// `tr_intern_def_id()` below.
pub fn tr_def_id(&self, did: ast::DefId) -> ast::DefId {
loop { }
}
/// Translates an INTERNAL def-id, meaning a def-id that is
/// known to refer to some part of the item currently being
/// inlined. In that case, we want to convert the def-id to
/// refer to the current crate and to the new, inlined node-id.
pub fn tr_intern_def_id(&self, did: ast::DefId) -> ast::DefId {
loop { }
}
pub fn tr_span(&self, _span: Span) -> Span { loop { } }
}
impl tr_intern for ast::DefId {
fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId {
loop { }
}
}
impl tr for ast::DefId {
fn tr(&self, dcx: &DecodeContext) -> ast::DefId { loop { } }
}
impl tr for Option<ast::DefId> {
fn tr(&self, dcx: &DecodeContext) -> Option<ast::DefId> {
loop { }
}
}
impl tr for Span {
fn tr(&self, dcx: &DecodeContext) -> Span { loop { } }
}
trait def_id_encoder_helpers {
fn emit_def_id(&mut self, did: ast::DefId);
}
impl <S: serialize::Encoder> def_id_encoder_helpers for S {
fn emit_def_id(&mut self, did: ast::DefId) { loop { } }
}
trait def_id_decoder_helpers {
fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId;
fn read_def_id_nodcx(&mut self, cdata: &cstore::crate_metadata)
-> ast::DefId;
}
impl <D: serialize::Decoder> def_id_decoder_helpers for D {
fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId {
loop { }
}
fn read_def_id_nodcx(&mut self, cdata: &cstore::crate_metadata)
-> ast::DefId {
loop { }
}
}
fn encode_ast(rbml_w: &mut Encoder, item: &ast::InlinedItem) {
loop { }
}
struct NestedItemsDropper;
impl Folder for NestedItemsDropper {
fn fold_block(&mut self, blk: P<ast::Block>) -> P<ast::Block> {
loop { }
}
}
fn simplify_ast(ii: e::InlinedItemRef) -> ast::InlinedItem {
loop { }
}
fn decode_ast(par_doc: rbml::Doc) -> ast::InlinedItem { loop { } }
fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
loop { }
}
impl tr for def::Def {
fn tr(&self, dcx: &DecodeContext) -> def::Def { loop { } }
}
impl tr for ty::Region {
fn tr(&self, dcx: &DecodeContext) -> ty::Region { loop { } }
}
impl tr for ty::FreeRegion {
fn tr(&self, dcx: &DecodeContext) -> ty::FreeRegion { loop { } }
}
impl tr for region::CodeExtent {
fn tr(&self, dcx: &DecodeContext) -> region::CodeExtent {
loop { }
}
}
impl tr for ty::BoundRegion {
fn tr(&self, dcx: &DecodeContext) -> ty::BoundRegion { loop { } }
}
impl tr for ty::TraitStore {
fn tr(&self, dcx: &DecodeContext) -> ty::TraitStore { loop { } }
}
fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) {
loop { }
}
fn encode_capture_mode(rbml_w: &mut Encoder, cm: ast::CaptureClause) {
loop { }
}
trait rbml_decoder_helper {
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
-> ty::Freevar;
fn read_capture_mode(&mut self) -> ast::CaptureClause;
}
impl <'a> rbml_decoder_helper for reader::Decoder<'a> {
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
-> ty::Freevar {
loop { }
}
fn read_capture_mode(&mut self) -> ast::CaptureClause {
loop { }
}
}
impl tr for ty::Freevar {
fn tr(&self, dcx: &DecodeContext) -> ty::Freevar { loop { } }
}
impl tr for ty::UpvarBorrow {
fn tr(&self, dcx: &DecodeContext) -> ty::UpvarBorrow { loop { } }
}
trait read_method_callee_helper<'tcx> {
fn read_method_callee<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> (ty::ExprAdjustment, MethodCallee<'tcx>);
}
fn encode_method_callee<'a,
'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
adjustment: ty::ExprAdjustment,
method: &MethodCallee<'tcx>) {
loop { }
}
impl <'a, 'tcx> read_method_callee_helper<'tcx> for
reader::Decoder<'a> {
fn read_method_callee<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> (ty::ExprAdjustment, MethodCallee<'tcx>) {
loop { }
}
}
impl <'tcx> tr for MethodOrigin<'tcx> {
fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
loop { }
}
}
pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
kind: ty::UnboxedClosureKind) {
loop { }
}
pub trait vtable_decoder_helpers<'tcx> {
fn read_vec_per_param_space<T, F>(&mut self, f: F)
-> VecPerParamSpace<T> where F: FnMut(&mut Self) -> T;
fn read_vtable_res_with_key
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> (ty::ExprAdjustment, ty::vtable_res<'tcx>);
fn read_vtable_res
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata) -> ty::vtable_res<'tcx>;
fn read_vtable_param_res
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> ty::vtable_param_res<'tcx>;
fn read_vtable_origin
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata) -> ty::vtable_origin<'tcx>;
}
impl <'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
fn read_vec_per_param_space<T, F>(&mut self, mut f: F)
-> VecPerParamSpace<T> where F: FnMut(&mut reader::Decoder<'a>)
-> T {
loop { }
}
fn read_vtable_res_with_key(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> (ty::ExprAdjustment, ty::vtable_res<'tcx>) {
loop { }
}
fn read_vtable_res(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> ty::vtable_res<'tcx> {
loop { }
}
fn read_vtable_param_res(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> ty::vtable_param_res<'tcx> {
loop { }
}
fn read_vtable_origin(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> ty::vtable_origin<'tcx> {
loop { }
}
}
fn encode_vec_per_param_space<T,
F>(rbml_w: &mut Encoder,
v: &subst::VecPerParamSpace<T>,
mut f: F) where
F: FnMut(&mut Encoder, &T) {
loop { }
}
trait get_ty_str_ctxt<'tcx> {
fn ty_str_ctxt<'a>(&'a self) -> tyencode::ctxt<'a, 'tcx>;
}
impl <'a, 'tcx> get_ty_str_ctxt<'tcx> for e::EncodeContext<'a, 'tcx> {
fn ty_str_ctxt<'b>(&'b self) -> tyencode::ctxt<'b, 'tcx> {
loop { }
}
}
trait rbml_writer_helpers<'tcx> {
fn emit_closure_type<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>);
fn emit_method_origin<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
method_origin: &ty::MethodOrigin<'tcx>);
fn emit_ty<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
fn emit_tys<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
tys: &[Ty<'tcx>]);
fn emit_type_param_def<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
type_param_def: &ty::TypeParameterDef<'tcx>);
fn emit_predicate<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
predicate: &ty::Predicate<'tcx>);
fn emit_trait_ref<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
ty: &ty::TraitRef<'tcx>);
fn emit_type_scheme<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
type_scheme: ty::TypeScheme<'tcx>);
fn emit_substs<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
substs: &subst::Substs<'tcx>);
fn emit_existential_bounds<'b>
(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
bounds: &ty::ExistentialBounds<'tcx>);
fn emit_builtin_bounds
(&mut self, ecx: &e::EncodeContext,
bounds: &ty::BuiltinBounds);
fn emit_auto_adjustment<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
adj: &ty::AutoAdjustment<'tcx>);
fn emit_autoref<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
autoref: &ty::AutoRef<'tcx>);
fn emit_auto_deref_ref<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
auto_deref_ref: &ty::AutoDerefRef<'tcx>);
fn emit_unsize_kind<'a>
(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
uk: &ty::UnsizeKind<'tcx>);
}
impl <'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
fn emit_closure_type<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>) {
loop { }
}
fn emit_method_origin<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
method_origin:
&ty::MethodOrigin<'tcx>) {
loop { }
}
fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
ty: Ty<'tcx>) {
loop { }
}
fn emit_tys<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
tys: &[Ty<'tcx>]) {
loop { }
}
fn emit_trait_ref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
trait_ref: &ty::TraitRef<'tcx>) {
loop { }
}
fn emit_type_param_def<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
type_param_def:
&ty::TypeParameterDef<'tcx>) {
loop { }
}
fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
predicate: &ty::Predicate<'tcx>) {
loop { }
}
fn emit_type_scheme<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
type_scheme: ty::TypeScheme<'tcx>) {
loop { }
}
fn emit_existential_bounds<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
bounds:
&ty::ExistentialBounds<'tcx>) {
loop { }
}
fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext,
bounds: &ty::BuiltinBounds) {
loop { }
}
fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
substs: &subst::Substs<'tcx>) {
loop { }
}
fn emit_auto_adjustment<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
adj: &ty::AutoAdjustment<'tcx>) {
loop { }
}
fn emit_autoref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
autoref: &ty::AutoRef<'tcx>) {
loop { }
}
fn emit_auto_deref_ref<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
auto_deref_ref:
&ty::AutoDerefRef<'tcx>) {
loop { }
}
fn emit_unsize_kind<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
uk: &ty::UnsizeKind<'tcx>) {
loop { }
}
}
trait write_tag_and_id {
fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where
F: FnOnce(&mut Self);
fn id(&mut self, id: ast::NodeId);
}
impl <'a> write_tag_and_id for Encoder<'a> {
fn tag<F>(&mut self, tag_id: c::astencode_tag, f: F) where
F: FnOnce(&mut Encoder<'a>) {
loop { }
}
fn id(&mut self, id: ast::NodeId) { loop { } }
}
struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
ecx: &'a e::EncodeContext<'c, 'tcx>,
rbml_w: &'a mut Encoder<'b>,
}
impl <'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for
SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> {
fn visit_id(&mut self, id: ast::NodeId) { loop { } }
}
fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
rbml_w: &mut Encoder,
ii: &ast::InlinedItem) {
loop { }
}
fn encode_side_tables_for_id(ecx: &e::EncodeContext,
rbml_w: &mut Encoder, id: ast::NodeId) {
loop { }
}
trait doc_decoder_helpers {
fn as_int(&self) -> int;
fn opt_child(&self, tag: c::astencode_tag) -> Option<Self>;
}
impl <'a> doc_decoder_helpers for rbml::Doc<'a> {
fn as_int(&self) -> int { loop { } }
fn opt_child(&self, tag: c::astencode_tag)
-> Option<rbml::Doc<'a>> {
loop { }
}
}
trait rbml_decoder_decoder_helpers<'tcx> {
fn read_method_origin<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::MethodOrigin<'tcx>;
fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> Ty<'tcx>;
fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> Vec<Ty<'tcx>>;
fn read_trait_ref<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> Rc<ty::TraitRef<'tcx>>;
fn read_poly_trait_ref<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::PolyTraitRef<'tcx>;
fn read_type_param_def<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::TypeParameterDef<'tcx>;
fn read_predicate<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::Predicate<'tcx>;
fn read_type_scheme<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::TypeScheme<'tcx>;
fn read_existential_bounds<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::ExistentialBounds<'tcx>;
fn read_substs<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> subst::Substs<'tcx>;
fn read_auto_adjustment<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::AutoAdjustment<'tcx>;
fn read_unboxed_closure<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::UnboxedClosure<'tcx>;
fn read_auto_deref_ref<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::AutoDerefRef<'tcx>;
fn read_autoref<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::AutoRef<'tcx>;
fn read_unsize_kind<'a, 'b>
(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::UnsizeKind<'tcx>;
fn convert_def_id
(&mut self, dcx: &DecodeContext, source: DefIdSource,
did: ast::DefId) -> ast::DefId;
fn read_ty_nodcx
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata) -> Ty<'tcx>;
fn read_tys_nodcx
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata) -> Vec<Ty<'tcx>>;
fn read_substs_nodcx
(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata) -> subst::Substs<'tcx>;
}
impl <'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for
reader::Decoder<'a> {
fn read_ty_nodcx(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata) -> Ty<'tcx> {
loop { }
}
fn read_tys_nodcx(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> Vec<Ty<'tcx>> {
loop { }
}
fn read_substs_nodcx(&mut self, tcx: &ty::ctxt<'tcx>,
cdata: &cstore::crate_metadata)
-> subst::Substs<'tcx> {
loop { }
}
fn read_method_origin<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::MethodOrigin<'tcx> {
loop { }
}
fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> Ty<'tcx> {
loop { }
}
fn read_tys<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> Vec<Ty<'tcx>> {
loop { }
}
fn read_trait_ref<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> Rc<ty::TraitRef<'tcx>> {
loop { }
}
fn read_poly_trait_ref<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::PolyTraitRef<'tcx> {
loop { }
}
fn read_type_param_def<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::TypeParameterDef<'tcx> {
loop { }
}
fn read_predicate<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::Predicate<'tcx> {
loop { }
}
fn read_type_scheme<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::TypeScheme<'tcx> {
loop { }
}
fn read_existential_bounds<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::ExistentialBounds<'tcx> {
loop { }
}
fn read_substs<'b,
'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> subst::Substs<'tcx> {
loop { }
}
fn read_auto_adjustment<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::AutoAdjustment<'tcx> {
loop { }
}
fn read_auto_deref_ref<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::AutoDerefRef<'tcx> {
loop { }
}
fn read_autoref<'b,
'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::AutoRef<'tcx> {
loop { }
}
fn read_unsize_kind<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::UnsizeKind<'tcx> {
loop { }
}
fn read_unboxed_closure<'b,
'c>(&mut self,
dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::UnboxedClosure<'tcx> {
loop { }
}
/// Converts a def-id that appears in a type. The correct
/// translation will depend on what kind of def-id this is.
/// This is a subtle point: type definitions are not
/// inlined into the current crate, so if the def-id names
/// a nominal type or type alias, then it should be
/// translated to refer to the source crate.
///
/// However, *type parameters* are cloned along with the function
/// they are attached to. So we should translate those def-ids
/// to refer to the new, cloned copy of the type parameter.
/// We only see references to free type parameters in the body of
/// an inlined function. In such cases, we need the def-id to
/// be a local id so that the TypeContents code is able to lookup
/// the relevant info in the ty_param_defs table.
///
/// *Region parameters*, unfortunately, are another kettle of fish.
/// In such cases, def_id's can appear in types to distinguish
/// shadowed bound regions and so forth. It doesn't actually
/// matter so much what we do to these, since regions are erased
/// at trans time, but it's good to keep them consistent just in
/// case. We translate them with `tr_def_id()` which will map
/// the crate numbers back to the original source crate.
///
/// Unboxed closures are cloned along with the function being
/// inlined, and all side tables use interned node IDs, so we
/// translate their def IDs accordingly.
///
/// It'd be really nice to refactor the type repr to not include
/// def-ids so that all these distinctions were unnecessary.
fn convert_def_id(&mut self, dcx: &DecodeContext,
source: tydecode::DefIdSource, did: ast::DefId)
-> ast::DefId {
loop { }
}
}
fn decode_side_tables(dcx: &DecodeContext, ast_doc: rbml::Doc) {
loop { }
}
#[cfg(test)]
fn encode_item_ast(rbml_w: &mut Encoder, item: &ast::Item) {
loop { }
}
#[cfg(test)]
fn decode_item_ast(par_doc: rbml::Doc) -> ast::Item { loop { } }
#[cfg(test)]
trait fake_ext_ctxt {
fn cfg(&self) -> ast::CrateConfig;
fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess;
fn call_site(&self) -> Span;
fn ident_of(&self, st: &str) -> ast::Ident;
}
#[cfg(test)]
impl fake_ext_ctxt for parse::ParseSess {
fn cfg(&self) -> ast::CrateConfig { loop { } }
fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { loop { } }
fn call_site(&self) -> Span { loop { } }
fn ident_of(&self, st: &str) -> ast::Ident { loop { } }
}
#[cfg(test)]
fn mk_ctxt() -> parse::ParseSess { loop { } }
#[cfg(test)]
fn roundtrip(in_item: Option<P<ast::Item>>) { loop { } }
#[test]
fn test_basic() { loop { } }
#[test]
fn test_more() { loop { } }
#[test]
fn test_simplification() { loop { } }
}
pub mod cfg {
//! Module that constructs a control-flow graph representing an item.
//! Uses `Graph` as the underlying representation.
use middle::graph;
use middle::ty;
use syntax::ast;
use util::nodemap::NodeMap;
mod construct {
use middle::cfg::*;
use middle::def;
use middle::graph;
use middle::region::CodeExtent;
use middle::ty;
use syntax::ast;
use syntax::ast_util;
use syntax::ptr::P;
use util::nodemap::NodeMap;
struct CFGBuilder<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
exit_map: NodeMap<CFGIndex>,
graph: CFGGraph,
fn_exit: CFGIndex,
loop_scopes: Vec<LoopScope>,
}
#[derive(Copy)]
struct LoopScope {
loop_id: ast::NodeId,
continue_index: CFGIndex,
break_index: CFGIndex,
}
pub fn construct(tcx: &ty::ctxt, blk: &ast::Block) -> CFG {
loop { }
}
fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
loop { }
}
impl <'a, 'tcx> CFGBuilder<'a, 'tcx> {
fn block(&mut self, blk: &ast::Block, pred: CFGIndex)
-> CFGIndex {
loop { }
}
fn stmt(&mut self, stmt: &ast::Stmt, pred: CFGIndex)
-> CFGIndex {
loop { }
}
fn decl(&mut self, decl: &ast::Decl, pred: CFGIndex)
-> CFGIndex {
loop { }
}
fn pat(&mut self, pat: &ast::Pat, pred: CFGIndex)
-> CFGIndex {
loop { }
}
fn pats_all<'b, I: Iterator<Item =
&'b P<ast::Pat>>>(&mut self, pats: I,
pred: CFGIndex) -> CFGIndex {
//! Handles case where all of the patterns must match.
loop { }
}
fn pats_any(&mut self, pats: &[P<ast::Pat>], pred: CFGIndex)
-> CFGIndex {
//! Handles case where just one of the patterns must match.
loop { }
}
fn expr(&mut self, expr: &ast::Expr, pred: CFGIndex)
-> CFGIndex {
loop { }
}
fn call<'b, I: Iterator<Item =
&'b ast::Expr>>(&mut self, call_expr: &ast::Expr,
pred: CFGIndex,
func_or_rcvr: &ast::Expr, args: I)
-> CFGIndex {
loop { }
}
fn exprs<'b, I: Iterator<Item =
&'b ast::Expr>>(&mut self, exprs: I, pred: CFGIndex)
-> CFGIndex {
//! Constructs graph for `exprs` evaluated in order
loop { }
}
fn opt_expr(&mut self, opt_expr: &Option<P<ast::Expr>>,
pred: CFGIndex) -> CFGIndex {
//! Constructs graph for `opt_expr` evaluated, if Some
loop { }
}
fn straightline<'b, I: Iterator<Item =
&'b ast::Expr>>(&mut self, expr: &ast::Expr,
pred: CFGIndex, subexprs: I)
-> CFGIndex {
//! Handles case of an expression that evaluates `subexprs` in order
loop { }
}
fn add_dummy_node(&mut self, preds: &[CFGIndex]) -> CFGIndex {
loop { }
}
fn add_node(&mut self, id: ast::NodeId, preds: &[CFGIndex])
-> CFGIndex {
loop { }
}
fn add_contained_edge(&mut self, source: CFGIndex,
target: CFGIndex) {
loop { }
}
fn add_exiting_edge(&mut self, from_expr: &ast::Expr,
from_index: CFGIndex, to_loop: LoopScope,
to_index: CFGIndex) {
loop { }
}
fn add_returning_edge(&mut self, _from_expr: &ast::Expr,
from_index: CFGIndex) {
loop { }
}
fn find_scope(&self, expr: &ast::Expr,
label: Option<ast::Ident>) -> LoopScope {
loop { }
}
fn is_method_call(&self, expr: &ast::Expr) -> bool {
loop { }
}
}
}
pub mod graphviz {
/// This module provides linkage between rustc::middle::graph and
/// libgraphviz traits.
use std::borrow::IntoCow;
use graphviz as dot;
use syntax::ast;
use syntax::ast_map;
use middle::cfg;
pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
pub type Edge<'a> = &'a cfg::CFGEdge;
pub struct LabelledCFG<'a, 'ast:'a> {
pub ast_map: &'a ast_map::Map<'ast>,
pub cfg: &'a cfg::CFG,
pub name: String,
}
fn replace_newline_with_backslash_l(s: String) -> String {
loop { }
}
impl <'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for
LabelledCFG<'a, 'ast> {
fn graph_id(&'a self) -> dot::Id<'a> { loop { } }
fn node_id(&'a self, &(i, _): &Node<'a>) -> dot::Id<'a> {
loop { }
}
fn node_label(&'a self, &(i, n): &Node<'a>)
-> dot::LabelText<'a> {
loop { }
}
fn edge_label(&self, e: &Edge<'a>) -> dot::LabelText<'a> {
loop { }
}
}
impl <'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG
{
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { loop { } }
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { loop { } }
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { loop { } }
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { loop { } }
}
impl <'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for
LabelledCFG<'a, 'ast> {
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { loop { } }
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { loop { } }
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { loop { } }
fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { loop { } }
}
}
pub struct CFG {
pub exit_map: NodeMap<CFGIndex>,
pub graph: CFGGraph,
pub entry: CFGIndex,
pub exit: CFGIndex,
}
#[derive(Copy)]
pub struct CFGNodeData {
pub id: ast::NodeId,
}
pub struct CFGEdgeData {
pub exiting_scopes: Vec<ast::NodeId>,
}
pub type CFGIndex = graph::NodeIndex;
pub type CFGGraph = graph::Graph<CFGNodeData, CFGEdgeData>;
pub type CFGNode = graph::Node<CFGNodeData>;
pub type CFGEdge = graph::Edge<CFGEdgeData>;
impl CFG {
pub fn new(tcx: &ty::ctxt, blk: &ast::Block) -> CFG { loop { } }
pub fn node_is_reachable(&self, id: ast::NodeId) -> bool {
loop { }
}
}
}
pub mod check_const {
use middle::def::*;
use middle::ty;
use util::ppaux;
use syntax::ast;
use syntax::visit::{self, Visitor};
struct CheckCrateVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
in_const: bool,
}
impl <'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
fn with_const<F>(&mut self, in_const: bool, f: F) where
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>) {
loop { }
}
fn inside_const<F>(&mut self, f: F) where
F: FnOnce(&mut CheckCrateVisitor<'a, 'tcx>) {
loop { }
}
}
impl <'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) { loop { } }
fn visit_pat(&mut self, p: &ast::Pat) { loop { } }
fn visit_expr(&mut self, ex: &ast::Expr) { loop { } }
}
pub fn check_crate(tcx: &ty::ctxt) { loop { } }
fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) { loop { } }
}
pub mod check_static_recursion {
use session::Session;
use middle::def::{DefStatic, DefConst, DefMap};
use syntax::ast;
use syntax::{ast_util, ast_map};
use syntax::visit::Visitor;
use syntax::visit;
struct CheckCrateVisitor<'a, 'ast:'a> {
sess: &'a Session,
def_map: &'a DefMap,
ast_map: &'a ast_map::Map<'ast>,
}
impl <'v, 'a, 'ast> Visitor<'v> for CheckCrateVisitor<'a, 'ast> {
fn visit_item(&mut self, i: &ast::Item) { loop { } }
}
pub fn check_crate<'ast>(sess: &Session, krate: &ast::Crate,
def_map: &DefMap,
ast_map: &ast_map::Map<'ast>) {
loop { }
}
fn check_item(v: &mut CheckCrateVisitor, it: &ast::Item) { loop { } }
struct CheckItemRecursionVisitor<'a, 'ast:'a> {
root_it: &'a ast::Item,
sess: &'a Session,
ast_map: &'a ast_map::Map<'ast>,
def_map: &'a DefMap,
idstack: Vec<ast::NodeId>,
}
pub fn check_item_recursion<'a>(sess: &'a Session,
ast_map: &'a ast_map::Map,
def_map: &'a DefMap,
it: &'a ast::Item) {
loop { }
}
impl <'a, 'ast, 'v> Visitor<'v> for
CheckItemRecursionVisitor<'a, 'ast> {
fn visit_item(&mut self, it: &ast::Item) { loop { } }
fn visit_expr(&mut self, e: &ast::Expr) { loop { } }
}
}
pub mod check_loop {
use self::Context::*;
use session::Session;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::Visitor;
use syntax::visit;
#[derive(Clone, Copy, PartialEq)]
enum Context { Normal, Loop, Closure, }
#[derive(Copy)]
struct CheckLoopVisitor<'a> {
sess: &'a Session,
cx: Context,
}
pub fn check_crate(sess: &Session, krate: &ast::Crate) { loop { } }
impl <'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
fn visit_item(&mut self, i: &ast::Item) { loop { } }
fn visit_expr(&mut self, e: &ast::Expr) { loop { } }
}
impl <'a> CheckLoopVisitor<'a> {
fn with_context<F>(&mut self, cx: Context, f: F) where
F: FnOnce(&mut CheckLoopVisitor<'a>) {
loop { }
}
fn require_loop(&self, name: &str, span: Span) { loop { } }
}
}
pub mod check_match {
pub use self::Constructor::*;
use self::Usefulness::*;
use self::WitnessPreference::*;
use middle::const_eval::{compare_const_vals, const_bool, const_float,
const_val};
use middle::const_eval::{const_expr_to_pat, eval_const_expr,
lookup_const_by_id};
use middle::def::*;
use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor,
Init};
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
use middle::expr_use_visitor::{WriteAndRead};
use middle::expr_use_visitor as euv;
use middle::mem_categorization::cmt;
use middle::pat_util::*;
use middle::ty::*;
use middle::ty;
use std::fmt;
use std::iter::{range_inclusive, AdditiveIterator, FromIterator,
repeat};
use std::num::Float;
use std::slice;
use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
use syntax::ast_util::walk_pat;
use syntax::codemap::{Span, Spanned, DUMMY_SP};
use syntax::fold::{Folder, noop_fold_pat};
use syntax::print::pprust::pat_to_string;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::visit::{self, Visitor, FnKind};
use util::ppaux::ty_to_string;
pub const DUMMY_WILD_PAT: &'static Pat =
&Pat{id: DUMMY_NODE_ID,
node: ast::PatWild(ast::PatWildSingle),
span: DUMMY_SP,};
struct Matrix<'a>(Vec<Vec<&'a Pat>>);
/// Pretty-printer for matrices of patterns, example:
/// ++++++++++++++++++++++++++
/// + _ + [] +
/// ++++++++++++++++++++++++++
/// + true + [First] +
/// ++++++++++++++++++++++++++
/// + true + [Second(true)] +
/// ++++++++++++++++++++++++++
/// + false + [_] +
/// ++++++++++++++++++++++++++
/// + _ + [_, _, ..tail] +
/// ++++++++++++++++++++++++++
impl <'a> fmt::Show for Matrix<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl <'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
fn from_iter<T: Iterator<Item = Vec<&'a Pat>>>(iterator: T)
-> Matrix<'a> {
loop { }
}
}
pub struct MatchCheckCtxt<'a, 'tcx:'a> {
pub tcx: &'a ty::ctxt<'tcx>,
pub param_env: ParameterEnvironment<'a, 'tcx>,
}
#[derive(Clone, PartialEq)]
pub enum Constructor {
/// The constructor of all patterns that don't vary by constructor,
/// e.g. struct patterns and fixed-length arrays.
Single,
/// Enum variants.
Variant(ast::DefId),
/// Literal values.
ConstantValue(const_val),
/// Ranges of literal values (2..5).
ConstantRange(const_val, const_val),
/// Array patterns of length n.
Slice(uint),
/// Array patterns with a subslice.
SliceWithSubslice(uint, uint),
}
#[derive(Clone, PartialEq)]
enum Usefulness { Useful, UsefulWithWitness(Vec<P<Pat>>), NotUseful, }
#[derive(Copy)]
enum WitnessPreference { ConstructWitness, LeaveOutWitness, }
impl <'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr) { loop { } }
fn visit_local(&mut self, l: &ast::Local) { loop { } }
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, n: NodeId) {
loop { }
}
}
pub fn check_crate(tcx: &ty::ctxt) { loop { } }
fn check_expr(cx: &mut MatchCheckCtxt, ex: &ast::Expr) { loop { } }
fn is_expr_const_nan(tcx: &ty::ctxt, expr: &ast::Expr) -> bool {
loop { }
}
fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt,
pat: &Pat) {
loop { }
}
fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) { loop { } }
fn check_arms(cx: &MatchCheckCtxt,
arms: &[(Vec<P<Pat>>, Option<&ast::Expr>)],
source: ast::MatchSource) {
loop { }
}
fn raw_pat<'a>(p: &'a Pat) -> &'a Pat { loop { } }
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
loop { }
}
fn const_val_to_expr(value: &const_val) -> P<ast::Expr> { loop { } }
pub struct StaticInliner<'a, 'tcx:'a> {
pub tcx: &'a ty::ctxt<'tcx>,
pub failed: bool,
}
impl <'a, 'tcx> StaticInliner<'a, 'tcx> {
pub fn new<'b>(tcx: &'b ty::ctxt<'tcx>)
-> StaticInliner<'b, 'tcx> {
loop { }
}
}
impl <'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> { loop { } }
}
/// Constructs a partial witness for a pattern given a list of
/// patterns expanded by the specialization step.
///
/// When a pattern P is discovered to be useful, this function is used bottom-up
/// to reconstruct a complete witness, e.g. a pattern P' that covers a subset
/// of values, V, where each value in that set is not covered by any previously
/// used patterns and is covered by the pattern P'. Examples:
///
/// left_ty: tuple of 3 elements
/// pats: [10, 20, _] => (10, 20, _)
///
/// left_ty: struct X { a: (bool, &'static str), b: uint}
/// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 }
fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
pats: Vec<&Pat>, left_ty: Ty) -> P<Pat> {
loop { }
}
fn missing_constructor(cx: &MatchCheckCtxt,
&Matrix(ref rows): &Matrix, left_ty: Ty,
max_slice_length: uint)
-> Option<Constructor> {
loop { }
}
/// This determines the set of all possible constructors of a pattern matching
/// values of type `left_ty`. For vectors, this would normally be an infinite set
/// but is instead bounded by the maximum fixed length of slice patterns in
/// the column of patterns being analyzed.
fn all_constructors(cx: &MatchCheckCtxt, left_ty: Ty,
max_slice_length: uint) -> Vec<Constructor> {
loop { }
}
fn is_useful(cx: &MatchCheckCtxt, matrix: &Matrix, v: &[&Pat],
witness: WitnessPreference) -> Usefulness {
loop { }
}
fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix,
v: &[&Pat], ctor: Constructor, lty: Ty,
witness: WitnessPreference) -> Usefulness {
loop { }
}
/// Determines the constructors that the given pattern can be specialized to.
///
/// In most cases, there's only one constructor that a specific pattern
/// represents, such as a specific enum variant or a specific literal value.
/// Slice patterns, however, can match slices of different lengths. For instance,
/// `[a, b, ..tail]` can match a slice of length 2, 3, 4 and so on.
///
/// On the other hand, a wild pattern and an identifier pattern cannot be
/// specialized in any way.
fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, left_ty: Ty,
max_slice_length: uint) -> Vec<Constructor> {
loop { }
}
/// This computes the arity of a constructor. The arity of a constructor
/// is how many subpattern patterns of that constructor should be expanded to.
///
/// For instance, a tuple pattern (_, 42u, Some([])) has the arity of 3.
/// A struct pattern's arity is the number of fields it contains, etc.
pub fn constructor_arity(cx: &MatchCheckCtxt, ctor: &Constructor,
ty: Ty) -> uint {
loop { }
}
fn range_covered_by_constructor(ctor: &Constructor, from: &const_val,
to: &const_val) -> Option<bool> {
loop { }
}
/// This is the main specialization step. It expands the first pattern in the given row
/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
///
/// OTOH, slice patterns with a subslice pattern (..tail) can be expanded into multiple
/// different patterns.
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
/// fields filled with wild patterns.
pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
constructor: &Constructor, col: uint,
arity: uint) -> Option<Vec<&'a Pat>> {
loop { }
}
fn check_local(cx: &mut MatchCheckCtxt, loc: &ast::Local) {
loop { }
}
fn check_fn(cx: &mut MatchCheckCtxt, kind: FnKind, decl: &ast::FnDecl,
body: &ast::Block, sp: Span, fn_id: NodeId) {
loop { }
}
fn is_refutable<A, F>(cx: &MatchCheckCtxt, pat: &Pat, refutable: F)
-> Option<A> where F: FnOnce(&Pat) -> A {
loop { }
}
fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
has_guard: bool, pats: &[P<Pat>]) {
loop { }
}
/// Ensures that a pattern guard doesn't borrow by mutable reference or
/// assign.
fn check_for_mutation_in_guard<'a,
'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
guard: &ast::Expr) {
loop { }
}
struct MutationChecker<'a, 'tcx:'a> {
cx: &'a MatchCheckCtxt<'a, 'tcx>,
}
impl <'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
fn matched_pat(&mut self, _: &Pat, _: cmt, _: euv::MatchMode) {
loop { }
}
fn consume(&mut self, _: NodeId, _: Span, _: cmt,
_: ConsumeMode) {
loop { }
}
fn consume_pat(&mut self, _: &Pat, _: cmt, _: ConsumeMode) {
loop { }
}
fn borrow(&mut self, _: NodeId, span: Span, _: cmt, _: Region,
kind: BorrowKind, _: LoanCause) {
loop { }
}
fn decl_without_init(&mut self, _: NodeId, _: Span) { loop { } }
fn mutate(&mut self, _: NodeId, span: Span, _: cmt,
mode: MutateMode) {
loop { }
}
}
/// Forbids bindings in `@` patterns. This is necessary for memory safety,
/// because of the way rvalues are handled in the borrow check. (See issue
/// #14587.)
fn check_legality_of_bindings_in_at_patterns(cx: &MatchCheckCtxt,
pat: &Pat) {
loop { }
}
struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> {
cx: &'a MatchCheckCtxt<'b, 'tcx>,
bindings_allowed: bool,
}
impl <'a, 'b, 'tcx, 'v> Visitor<'v> for
AtBindingPatternVisitor<'a, 'b, 'tcx> {
fn visit_pat(&mut self, pat: &Pat) { loop { } }
}
}
pub mod check_rvalues {
use middle::expr_use_visitor as euv;
use middle::mem_categorization as mc;
use middle::ty::ParameterEnvironment;
use middle::ty;
use util::ppaux::ty_to_string;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit;
pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) { loop { } }
struct RvalueContext<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
}
impl <'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, fn_id: ast::NodeId) {
loop { }
}
}
struct RvalueContextDelegate<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
param_env: &'a ty::ParameterEnvironment<'a, 'tcx>,
}
impl <'a, 'tcx> euv::Delegate<'tcx> for
RvalueContextDelegate<'a, 'tcx> {
fn consume(&mut self, _: ast::NodeId, span: Span,
cmt: mc::cmt<'tcx>, _: euv::ConsumeMode) {
loop { }
}
fn matched_pat(&mut self, _matched_pat: &ast::Pat, _cmt: mc::cmt,
_mode: euv::MatchMode) {
loop { }
}
fn consume_pat(&mut self, _consume_pat: &ast::Pat, _cmt: mc::cmt,
_mode: euv::ConsumeMode) {
loop { }
}
fn borrow(&mut self, _borrow_id: ast::NodeId, _borrow_span: Span,
_cmt: mc::cmt, _loan_region: ty::Region,
_bk: ty::BorrowKind, _loan_cause: euv::LoanCause) {
loop { }
}
fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {
loop { }
}
fn mutate(&mut self, _assignment_id: ast::NodeId,
_assignment_span: Span, _assignee_cmt: mc::cmt,
_mode: euv::MutateMode) {
loop { }
}
}
}
pub mod check_static {
use self::Mode::*;
use middle::ty;
use middle::def;
use middle::infer;
use middle::traits;
use middle::mem_categorization as mc;
use middle::expr_use_visitor as euv;
use util::nodemap::NodeSet;
use syntax::ast;
use syntax::print::pprust;
use syntax::visit::Visitor;
use syntax::codemap::Span;
use syntax::visit;
#[derive(Copy, Eq, PartialEq)]
enum Mode { InConstant, InStatic, InStaticMut, InNothing, }
struct CheckStaticVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
mode: Mode,
checker: &'a mut GlobalChecker,
}
struct GlobalVisitor<'a, 'b,
'tcx:'a+'b>(euv::ExprUseVisitor<'a, 'b, 'tcx,
ty::ParameterEnvironment<'b, 'tcx>>);
struct GlobalChecker {
static_consumptions: NodeSet,
const_borrows: NodeSet,
static_interior_borrows: NodeSet,
static_local_borrows: NodeSet,
}
pub fn check_crate(tcx: &ty::ctxt) { loop { } }
impl <'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
fn with_mode<F>(&mut self, mode: Mode, f: F) where
F: FnOnce(&mut CheckStaticVisitor<'a, 'tcx>) {
loop { }
}
fn msg(&self) -> &'static str { loop { } }
fn check_static_mut_type(&self, e: &ast::Expr) { loop { } }
fn check_static_type(&self, e: &ast::Expr) { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) { loop { } }
/// This method is used to enforce the constraints on
/// immutable static items. It walks through the *value*
/// of the item walking down the expression and evaluating
/// every nested expression. if the expression is not part
/// of a static item, this method does nothing but walking
/// down through it.
fn visit_expr(&mut self, e: &ast::Expr) { loop { } }
}
impl <'a, 'b, 't, 'v> Visitor<'v> for GlobalVisitor<'a, 'b, 't> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
}
impl <'tcx> euv::Delegate<'tcx> for GlobalChecker {
fn consume(&mut self, consume_id: ast::NodeId,
_consume_span: Span, cmt: mc::cmt,
_mode: euv::ConsumeMode) {
loop { }
}
fn borrow(&mut self, borrow_id: ast::NodeId, _borrow_span: Span,
cmt: mc::cmt, _loan_region: ty::Region,
_bk: ty::BorrowKind, _loan_cause: euv::LoanCause) {
loop { }
}
fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {
loop { }
}
fn mutate(&mut self, _assignment_id: ast::NodeId,
_assignment_span: Span, _assignee_cmt: mc::cmt,
_mode: euv::MutateMode) {
loop { }
}
fn matched_pat(&mut self, _: &ast::Pat, _: mc::cmt,
_: euv::MatchMode) {
loop { }
}
fn consume_pat(&mut self, _consume_pat: &ast::Pat, _cmt: mc::cmt,
_mode: euv::ConsumeMode) {
loop { }
}
}
}
pub mod const_eval {
#![allow(non_camel_case_types)]
#![allow(unsigned_negation)]
pub use self::const_val::*;
pub use self::constness::*;
use metadata::csearch;
use middle::{astencode, def};
use middle::pat_util::def_to_path;
use middle::ty::{self};
use middle::astconv_util::{ast_ty_to_prim_ty};
use util::nodemap::DefIdMap;
use syntax::ast::{self, Expr};
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::visit::{self, Visitor};
use syntax::{ast_map, ast_util, codemap};
use std::collections::hash_map::Entry::Vacant;
use std::rc::Rc;
#[derive(Copy)]
pub enum constness { integral_const, general_const, non_const, }
type constness_cache = DefIdMap<constness>;
pub fn join(a: constness, b: constness) -> constness { loop { } }
pub fn join_all<It: Iterator<Item = constness>>(cs: It) -> constness {
loop { }
}
fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
loop { }
}
fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, enum_def: ast::DefId,
variant_def: ast::DefId)
-> Option<&'a Expr> {
loop { }
}
pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
-> Option<&'a Expr> {
loop { }
}
struct ConstEvalVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
ccache: constness_cache,
}
impl <'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
fn classify(&mut self, e: &Expr) -> constness { loop { } }
fn lookup_constness(&self, e: &Expr) -> constness { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
fn visit_expr_post(&mut self, e: &Expr) { loop { } }
}
pub fn process_crate(tcx: &ty::ctxt) { loop { } }
#[derive(Clone, PartialEq)]
pub enum const_val {
const_float(f64),
const_int(i64),
const_uint(u64),
const_str(InternedString),
const_binary(Rc<Vec<u8>>),
const_bool(bool),
}
pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<ast::Pat> {
loop { }
}
pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
loop { }
}
pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr)
-> Result<const_val, String> {
loop { }
}
pub fn lit_to_const(lit: &ast::Lit) -> const_val { loop { } }
fn compare_vals<T: PartialOrd>(a: T, b: T) -> Option<int> {
loop { }
}
pub fn compare_const_vals(a: &const_val, b: &const_val)
-> Option<int> {
loop { }
}
pub fn compare_lit_exprs(tcx: &ty::ctxt, a: &Expr, b: &Expr)
-> Option<int> {
loop { }
}
}
pub mod dataflow {
//! A module for propagating forward dataflow information. The analysis
//! assumes that the items to be propagated can be represented as bits
//! and thus uses bitvectors. Your job is simply to specify the so-called
//! GEN and KILL bits for each expression.
pub use self::EntryOrExit::*;
use middle::cfg;
use middle::cfg::CFGIndex;
use middle::ty;
use std::io;
use std::uint;
use std::iter::repeat;
use syntax::ast;
use syntax::ast_util::IdRange;
use syntax::visit;
use syntax::print::{pp, pprust};
use util::nodemap::NodeMap;
#[derive(Copy, Show)]
pub enum EntryOrExit { Entry, Exit, }
#[derive(Clone)]
pub struct DataFlowContext<'a, 'tcx:'a, O> {
tcx: &'a ty::ctxt<'tcx>,
/// a name for the analysis using this dataflow instance
analysis_name: &'static str,
/// the data flow operator
oper: O,
/// number of bits to propagate per id
bits_per_id: uint,
/// number of words we will use to store bits_per_id.
/// equal to bits_per_id/uint::BITS rounded up.
words_per_id: uint,
nodeid_to_index: NodeMap<CFGIndex>,
/// bits generated as we exit the cfg node. Updated by `add_gen()`.
gens: Vec<uint>,
/// bits killed as we exit the cfg node. Updated by `add_kill()`.
kills: Vec<uint>,
/// bits that are valid on entry to the cfg node. Updated by
/// `propagate()`.
on_entry: Vec<uint>,
}
pub trait BitwiseOperator {
/// Joins two predecessor bits together, typically either `|` or `&`
fn join(&self, succ: uint, pred: uint) -> uint;
}
/// Parameterization for the precise form of data flow that is used.
pub trait DataFlowOperator: BitwiseOperator {
/// Specifies the initial value for each bit in the `on_entry` set
fn initial_value(&self) -> bool;
}
struct PropagationContext<'a, 'b:'a, 'tcx:'b, O: 'a> {
dfcx: &'a mut DataFlowContext<'b, 'tcx, O>,
changed: bool,
}
fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>)
-> CFGIndex {
loop { }
}
impl <'a, 'tcx, O: DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
fn has_bitset_for_nodeid(&self, n: ast::NodeId) -> bool {
loop { }
}
}
impl <'a, 'tcx, O: DataFlowOperator> pprust::PpAnn for
DataFlowContext<'a, 'tcx, O> {
fn pre(&self, ps: &mut pprust::State, node: pprust::AnnNode)
-> io::IoResult<()> {
loop { }
}
}
fn build_nodeid_to_index(decl: Option<&ast::FnDecl>, cfg: &cfg::CFG)
-> NodeMap<CFGIndex> {
loop { }
}
impl <'a, 'tcx, O: DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
pub fn new(tcx: &'a ty::ctxt<'tcx>, analysis_name: &'static str,
decl: Option<&ast::FnDecl>, cfg: &cfg::CFG, oper: O,
id_range: IdRange, bits_per_id: uint)
-> DataFlowContext<'a, 'tcx, O> {
loop { }
}
pub fn add_gen(&mut self, id: ast::NodeId, bit: uint) {
//! Indicates that `id` generates `bit`
loop { }
}
pub fn add_kill(&mut self, id: ast::NodeId, bit: uint) {
//! Indicates that `id` kills `bit`
loop { }
}
fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
//! Applies the gen and kill sets for `cfgidx` to `bits`
loop { }
}
fn compute_id_range(&self, cfgidx: CFGIndex) -> (uint, uint) {
loop { }
}
pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool
where F: FnMut(uint) -> bool {
//! Iterates through each bit that is set on entry to `id`.
//! Only useful after `propagate()` has been called.
loop { }
}
pub fn each_bit_for_node<F>(&self, e: EntryOrExit,
cfgidx: CFGIndex, f: F) -> bool where
F: FnMut(uint) -> bool {
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
//! Only useful after `propagate()` has been called.
loop { }
}
pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where
F: FnMut(uint) -> bool {
//! Iterates through each bit in the gen set for `id`.
loop { }
}
fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where
F: FnMut(uint) -> bool {
//! Helper for iterating over the bits in a bit set.
//! Returns false on the first call to `f` that returns false;
//! if all calls to `f` return true, then returns true.
loop { }
}
pub fn add_kills_from_flow_exits(&mut self, cfg: &cfg::CFG) {
//! Whenever you have a `break` or `continue` statement, flow
//! exits through any number of enclosing scopes on its way to
//! the new destination. This function infers the kill bits of
//! those control operators based on the kill bits associated
//! with those scopes.
//!
//! This is usually called (if it is called at all), after
//! all add_gen and add_kill calls, but before propagate.
loop { }
}
}
impl <'a, 'tcx, O: DataFlowOperator + Clone + 'static>
DataFlowContext<'a, 'tcx, O> {
pub fn propagate(&mut self, cfg: &cfg::CFG, blk: &ast::Block) {
//! Performs the data flow analysis.
loop { }
}
fn pretty_print_to(&self, wr: Box<io::Writer+ 'static>,
blk: &ast::Block) -> io::IoResult<()> {
loop { }
}
}
impl <'a, 'b, 'tcx, O: DataFlowOperator>
PropagationContext<'a, 'b, 'tcx, O> {
fn walk_cfg(&mut self, cfg: &cfg::CFG, in_out: &mut [uint]) {
loop { }
}
fn reset(&mut self, bits: &mut [uint]) { loop { } }
fn propagate_bits_into_graph_successors_of(&mut self,
pred_bits: &[uint],
cfg: &cfg::CFG,
cfgidx: CFGIndex) {
loop { }
}
fn propagate_bits_into_entry_set_for(&mut self,
pred_bits: &[uint],
edge: &cfg::CFGEdge) {
loop { }
}
}
fn mut_bits_to_string(words: &mut [uint]) -> String { loop { } }
fn bits_to_string(words: &[uint]) -> String { loop { } }
#[inline]
fn bitwise<Op: BitwiseOperator>(out_vec: &mut [uint], in_vec: &[uint],
op: &Op) -> bool {
loop { }
}
fn set_bit(words: &mut [uint], bit: uint) -> bool { loop { } }
fn bit_str(bit: uint) -> String { loop { } }
struct Union;
impl BitwiseOperator for Union {
fn join(&self, a: uint, b: uint) -> uint { loop { } }
}
struct Subtract;
impl BitwiseOperator for Subtract {
fn join(&self, a: uint, b: uint) -> uint { loop { } }
}
}
pub mod dead {
use middle::{def, pat_util, privacy, ty};
use lint;
use util::nodemap::NodeSet;
use std::collections::HashSet;
use syntax::{ast, ast_map, codemap};
use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
use syntax::attr::{self, AttrMetaMethods};
use syntax::visit::{self, Visitor};
fn should_explore(tcx: &ty::ctxt, def_id: ast::DefId) -> bool {
loop { }
}
struct MarkSymbolVisitor<'a, 'tcx:'a> {
worklist: Vec<ast::NodeId>,
tcx: &'a ty::ctxt<'tcx>,
live_symbols: Box<HashSet<ast::NodeId>>,
struct_has_extern_repr: bool,
ignore_non_const_paths: bool,
inherited_pub_visibility: bool,
}
impl <'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>, worklist: Vec<ast::NodeId>)
-> MarkSymbolVisitor<'a, 'tcx> {
loop { }
}
fn check_def_id(&mut self, def_id: ast::DefId) { loop { } }
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
loop { }
}
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
span: codemap::Span) {
loop { }
}
fn handle_field_access(&mut self, lhs: &ast::Expr,
name: &ast::Ident) {
loop { }
}
fn handle_tup_field_access(&mut self, lhs: &ast::Expr,
idx: uint) {
loop { }
}
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
pats:
&[codemap::Spanned<ast::FieldPat>]) {
loop { }
}
fn mark_live_symbols(&mut self) { loop { } }
fn visit_node(&mut self, node: &ast_map::Node) { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
fn visit_struct_def(&mut self, def: &ast::StructDef,
_: ast::Ident, _: &ast::Generics,
_: ast::NodeId) {
loop { }
}
fn visit_expr(&mut self, expr: &ast::Expr) { loop { } }
fn visit_pat(&mut self, pat: &ast::Pat) { loop { } }
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
loop { }
}
fn visit_item(&mut self, _: &ast::Item) { loop { } }
}
fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute])
-> bool {
loop { }
}
struct LifeSeeder {
worklist: Vec<ast::NodeId>,
}
impl <'v> Visitor<'v> for LifeSeeder {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_fn(&mut self, fk: visit::FnKind<'v>, _: &'v ast::FnDecl,
block: &'v ast::Block, _: codemap::Span,
id: ast::NodeId) {
loop { }
}
}
fn create_and_seed_worklist(tcx: &ty::ctxt,
exported_items: &privacy::ExportedItems,
reachable_symbols: &NodeSet,
krate: &ast::Crate) -> Vec<ast::NodeId> {
loop { }
}
fn find_live(tcx: &ty::ctxt, exported_items: &privacy::ExportedItems,
reachable_symbols: &NodeSet, krate: &ast::Crate)
-> Box<HashSet<ast::NodeId>> {
loop { }
}
fn get_struct_ctor_id(item: &ast::Item) -> Option<ast::NodeId> {
loop { }
}
struct DeadVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
live_symbols: Box<HashSet<ast::NodeId>>,
}
impl <'a, 'tcx> DeadVisitor<'a, 'tcx> {
fn should_warn_about_item(&mut self, item: &ast::Item) -> bool {
loop { }
}
fn should_warn_about_field(&mut self, node: &ast::StructField_)
-> bool {
loop { }
}
fn should_warn_about_variant(&mut self, variant: &ast::Variant_)
-> bool {
loop { }
}
fn symbol_is_live(&mut self, id: ast::NodeId,
ctor_id: Option<ast::NodeId>) -> bool {
loop { }
}
fn warn_dead_code(&mut self, id: ast::NodeId, span: codemap::Span,
ident: ast::Ident, node_type: &str) {
loop { }
}
}
impl <'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
loop { }
}
fn visit_fn(&mut self, fk: visit::FnKind<'v>, _: &'v ast::FnDecl,
block: &'v ast::Block, span: codemap::Span,
id: ast::NodeId) {
loop { }
}
fn visit_struct_field(&mut self, field: &ast::StructField) {
loop { }
}
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
loop { }
}
}
pub fn check_crate(tcx: &ty::ctxt,
exported_items: &privacy::ExportedItems,
reachable_symbols: &NodeSet) {
loop { }
}
}
pub mod def {
pub use self::Def::*;
pub use self::MethodProvenance::*;
pub use self::TraitItemKind::*;
use middle::subst::ParamSpace;
use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
use util::nodemap::NodeMap;
use syntax::ast;
use syntax::ast_util::local_def;
use std::cell::RefCell;
#[derive(Clone,
Copy,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Show)]
pub enum Def {
DefFn(ast::DefId, bool),
DefStaticMethod(ast::DefId, MethodProvenance),
DefSelfTy(ast::NodeId),
DefMod(ast::DefId),
DefForeignMod(ast::DefId),
DefStatic(ast::DefId, bool),
DefConst(ast::DefId),
DefLocal(ast::NodeId),
DefVariant(ast::DefId, ast::DefId, bool),
DefTy(ast::DefId, bool),
DefAssociatedTy(ast::DefId),
DefAssociatedPath(TyParamProvenance, ast::Ident),
DefTrait(ast::DefId),
DefPrimTy(ast::PrimTy),
DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
DefUse(ast::DefId),
DefUpvar(ast::NodeId, ast::NodeId, ast::NodeId),
/// Note that if it's a tuple struct's definition, the node id of the ast::DefId
/// may either refer to the item definition's id or the StructDef.ctor_id.
///
/// The cases that I have encountered so far are (this is not exhaustive):
/// - If it's a ty_path referring to some tuple struct, then DefMap maps
/// it to a def whose id is the item definition's id.
/// - If it's an ExprPath referring to some tuple struct, then DefMap maps
/// it to a def whose id is the StructDef.ctor_id.
DefStruct(ast::DefId),
DefTyParamBinder(ast::NodeId),
DefRegion(ast::NodeId),
DefLabel(ast::NodeId),
DefMethod(ast::DefId, Option<ast::DefId>, MethodProvenance),
}
pub type DefMap = RefCell<NodeMap<Def>>;
pub type ExportMap = NodeMap<Vec<Export>>;
#[derive(Copy)]
pub struct Export {
pub name: ast::Name,
pub def_id: ast::DefId,
}
#[derive(Clone,
Copy,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Show)]
pub enum MethodProvenance {
FromTrait(ast::DefId),
FromImpl(ast::DefId),
}
#[derive(Clone,
Copy,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Show)]
pub enum TyParamProvenance {
FromSelf(ast::DefId),
FromParam(ast::DefId),
}
impl MethodProvenance {
pub fn map<F>(self, f: F) -> MethodProvenance where
F: FnOnce(ast::DefId) -> ast::DefId {
loop { }
}
}
impl TyParamProvenance {
pub fn def_id(&self) -> ast::DefId { loop { } }
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum TraitItemKind {
NonstaticMethodTraitItemKind,
StaticMethodTraitItemKind,
TypeTraitItemKind,
}
impl TraitItemKind {
pub fn from_explicit_self_category(explicit_self_category:
ExplicitSelfCategory)
-> TraitItemKind {
loop { }
}
}
impl Def {
pub fn local_node_id(&self) -> ast::NodeId { loop { } }
pub fn def_id(&self) -> ast::DefId { loop { } }
pub fn variant_def_ids(&self)
-> Option<(ast::DefId, ast::DefId)> {
loop { }
}
}
}
pub mod dependency_format {
//! Resolution of mixing rlibs and dylibs
//!
//! When producing a final artifact, such as a dynamic library, the compiler has
//! a choice between linking an rlib or linking a dylib of all upstream
//! dependencies. The linking phase must guarantee, however, that a library only
//! show up once in the object file. For example, it is illegal for library A to
//! be statically linked to B and C in separate dylibs, and then link B and C
//! into a crate D (because library A appears twice).
//!
//! The job of this module is to calculate what format each upstream crate
//! should be used when linking each output type requested in this session. This
//! generally follows this set of rules:
//!
//! 1. Each library must appear exactly once in the output.
//! 2. Each rlib contains only one library (it's just an object file)
//! 3. Each dylib can contain more than one library (due to static linking),
//! and can also bring in many dynamic dependencies.
//!
//! With these constraints in mind, it's generally a very difficult problem to
//! find a solution that's not "all rlibs" or "all dylibs". I have suspicions
//! that NP-ness may come into the picture here...
//!
//! The current selection algorithm below looks mostly similar to:
//!
//! 1. If static linking is required, then require all upstream dependencies
//! to be available as rlibs. If not, generate an error.
//! 2. If static linking is requested (generating an executable), then
//! attempt to use all upstream dependencies as rlibs. If any are not
//! found, bail out and continue to step 3.
//! 3. Static linking has failed, at least one library must be dynamically
//! linked. Apply a heuristic by greedily maximizing the number of
//! dynamically linked libraries.
//! 4. Each upstream dependency available as a dynamic library is
//! registered. The dependencies all propagate, adding to a map. It is
//! possible for a dylib to add a static library as a dependency, but it
//! is illegal for two dylibs to add the same static library as a
//! dependency. The same dylib can be added twice. Additionally, it is
//! illegal to add a static dependency when it was previously found as a
//! dylib (and vice versa)
//! 5. After all dynamic dependencies have been traversed, re-traverse the
//! remaining dependencies and add them statically (if they haven't been
//! added already).
//!
//! While not perfect, this algorithm should help support use-cases such as leaf
//! dependencies being static while the larger tree of inner dependencies are
//! all dynamic. This isn't currently very well battle tested, so it will likely
//! fall short in some use cases.
//!
//! Currently, there is no way to specify the preference of linkage with a
//! particular library (other than a global dynamic/static switch).
//! Additionally, the algorithm is geared towards finding *any* solution rather
//! than finding a number of solutions (there are normally quite a few).
use syntax::ast;
use session;
use session::config;
use metadata::cstore;
use metadata::csearch;
use middle::ty;
use util::nodemap::FnvHashMap;
/// A list of dependencies for a certain crate type.
///
/// The length of this vector is the same as the number of external crates used.
/// The value is None if the crate does not need to be linked (it was found
/// statically in another dylib), or Some(kind) if it needs to be linked as
/// `kind` (either static or dynamic).
pub type DependencyList = Vec<Option<cstore::LinkagePreference>>;
/// A mapping of all required dependencies for a particular flavor of output.
///
/// This is local to the tcx, and is generally relevant to one session.
pub type Dependencies = FnvHashMap<config::CrateType, DependencyList>;
pub fn calculate(tcx: &ty::ctxt) { loop { } }
fn calculate_type(sess: &session::Session, ty: config::CrateType)
-> DependencyList {
loop { }
}
fn add_library(sess: &session::Session, cnum: ast::CrateNum,
link: cstore::LinkagePreference,
m:
&mut FnvHashMap<ast::CrateNum,
cstore::LinkagePreference>) {
loop { }
}
fn attempt_static(sess: &session::Session) -> Option<DependencyList> {
loop { }
}
}
pub mod effect {
//! Enforces the Rust effect system. Currently there is just one effect,
/// `unsafe`.
use self::UnsafeContext::*;
use middle::def;
use middle::ty::{self, Ty};
use middle::ty::MethodCall;
use util::ppaux;
use syntax::ast;
use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::Visitor;
#[derive(Copy, PartialEq)]
enum UnsafeContext {
SafeContext,
UnsafeFn,
UnsafeBlock(ast::NodeId),
}
fn type_is_unsafe_function(ty: Ty) -> bool { loop { } }
struct EffectCheckVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
/// Whether we're in an unsafe context.
unsafe_context: UnsafeContext,
}
impl <'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
fn require_unsafe(&mut self, span: Span, description: &str) {
loop { }
}
fn check_str_index(&mut self, e: &ast::Expr) { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: visit::FnKind<'v>,
fn_decl: &'v ast::FnDecl, block: &'v ast::Block,
span: Span, _: ast::NodeId) {
loop { }
}
fn visit_block(&mut self, block: &ast::Block) { loop { } }
fn visit_expr(&mut self, expr: &ast::Expr) { loop { } }
}
pub fn check_crate(tcx: &ty::ctxt) { loop { } }
}
pub mod entry {
use session::{config, Session};
use syntax::ast::{Name, NodeId, Item, ItemFn};
use syntax::ast_map;
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::visit;
use syntax::visit::Visitor;
struct EntryContext<'a, 'ast:'a> {
session: &'a Session,
ast_map: &'a ast_map::Map<'ast>,
main_name: Name,
main_fn: Option<(NodeId, Span)>,
attr_main_fn: Option<(NodeId, Span)>,
start_fn: Option<(NodeId, Span)>,
non_main_fns: Vec<(NodeId, Span)>,
}
impl <'a, 'ast, 'v> Visitor<'v> for EntryContext<'a, 'ast> {
fn visit_item(&mut self, item: &Item) { loop { } }
}
pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
loop { }
}
fn find_item(item: &Item, ctxt: &mut EntryContext) { loop { } }
fn configure_main(this: &mut EntryContext) { loop { } }
}
pub mod expr_use_visitor {
//! A different sort of visitor for walking fn bodies. Unlike the
//! normal visitor, which just walks the entire body in one shot, the
//! `ExprUseVisitor` determines how expressions are being used.
pub use self::MutateMode::*;
pub use self::LoanCause::*;
pub use self::ConsumeMode::*;
pub use self::MoveReason::*;
pub use self::MatchMode::*;
use self::TrackMatchMode::*;
use self::OverloadedCallType::*;
use middle::{def, region, pat_util};
use middle::mem_categorization as mc;
use middle::mem_categorization::Typer;
use middle::ty::{self};
use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
use util::ppaux::Repr;
use std::marker;
use syntax::{ast, ast_util};
use syntax::ptr::P;
use syntax::codemap::Span;
/// This trait defines the callbacks you can expect to receive when
/// employing the ExprUseVisitor.
pub trait Delegate<'tcx> {
fn consume
(&mut self, consume_id: ast::NodeId, consume_span: Span,
cmt: mc::cmt<'tcx>, mode: ConsumeMode);
fn matched_pat
(&mut self, matched_pat: &ast::Pat, cmt: mc::cmt<'tcx>,
mode: MatchMode);
fn consume_pat
(&mut self, consume_pat: &ast::Pat, cmt: mc::cmt<'tcx>,
mode: ConsumeMode);
fn borrow
(&mut self, borrow_id: ast::NodeId, borrow_span: Span,
cmt: mc::cmt<'tcx>, loan_region: ty::Region,
bk: ty::BorrowKind, loan_cause: LoanCause);
fn decl_without_init(&mut self, id: ast::NodeId, span: Span);
fn mutate
(&mut self, assignment_id: ast::NodeId, assignment_span: Span,
assignee_cmt: mc::cmt<'tcx>, mode: MutateMode);
}
#[derive(Copy, PartialEq, Show)]
pub enum LoanCause {
ClosureCapture(Span),
AddrOf,
AutoRef,
RefBinding,
OverloadedOperator,
ClosureInvocation,
ForLoop,
MatchDiscriminant,
}
#[derive(Copy, PartialEq, Show)]
pub enum ConsumeMode { Copy, Move(MoveReason), }
#[derive(Copy, PartialEq, Show)]
pub enum MoveReason { DirectRefMove, PatBindingMove, CaptureMove, }
#[derive(Copy, PartialEq, Show)]
pub enum MatchMode {
NonBindingMatch,
BorrowingMatch,
CopyingMatch,
MovingMatch,
}
#[derive(PartialEq, Show)]
enum TrackMatchMode<T> { Unknown, Definite(MatchMode), Conflicting, }
impl <T> marker::Copy for TrackMatchMode<T> { }
impl <T> TrackMatchMode<T> {
fn lub(&mut self, mode: MatchMode) { loop { } }
fn match_mode(&self) -> MatchMode { loop { } }
}
#[derive(Copy, PartialEq, Show)]
pub enum MutateMode { Init, JustWrite, WriteAndRead, }
#[derive(Copy)]
enum OverloadedCallType {
FnOverloadedCall,
FnMutOverloadedCall,
FnOnceOverloadedCall,
}
impl OverloadedCallType {
fn from_trait_id(tcx: &ty::ctxt, trait_id: ast::DefId)
-> OverloadedCallType {
loop { }
}
fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
-> OverloadedCallType {
loop { }
}
fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
-> OverloadedCallType {
loop { }
}
fn from_method_origin(tcx: &ty::ctxt, origin: &MethodOrigin)
-> OverloadedCallType {
loop { }
}
}
pub struct ExprUseVisitor<'d, 't, 'tcx:'t, TYPER: 't> {
typer: &'t TYPER,
mc: mc::MemCategorizationContext<'t, TYPER>,
delegate: &'d mut (Delegate<'tcx>+ 'd),
}
macro_rules! return_if_err(( $ inp : expr ) => (
match $ inp {
Ok ( v ) => v , Err ( ( ) ) => return }
));
/// Whether the elements of an overloaded operation are passed by value or by reference
enum PassArgs { ByValue, ByRef, }
impl <'d, 't, 'tcx, TYPER: mc::Typer<'tcx>>
ExprUseVisitor<'d, 't, 'tcx, TYPER> {
pub fn new(delegate: &'d mut Delegate<'tcx>, typer: &'t TYPER)
-> ExprUseVisitor<'d, 't, 'tcx, TYPER> {
loop { }
}
pub fn walk_fn(&mut self, decl: &ast::FnDecl, body: &ast::Block) {
loop { }
}
fn walk_arg_patterns(&mut self, decl: &ast::FnDecl,
body: &ast::Block) {
loop { }
}
fn tcx(&self) -> &'t ty::ctxt<'tcx> { loop { } }
fn delegate_consume(&mut self, consume_id: ast::NodeId,
consume_span: Span, cmt: mc::cmt<'tcx>) {
loop { }
}
fn consume_exprs(&mut self, exprs: &Vec<P<ast::Expr>>) {
loop { }
}
pub fn consume_expr(&mut self, expr: &ast::Expr) { loop { } }
fn mutate_expr(&mut self, assignment_expr: &ast::Expr,
expr: &ast::Expr, mode: MutateMode) {
loop { }
}
fn borrow_expr(&mut self, expr: &ast::Expr, r: ty::Region,
bk: ty::BorrowKind, cause: LoanCause) {
loop { }
}
fn select_from_expr(&mut self, expr: &ast::Expr) { loop { } }
pub fn walk_expr(&mut self, expr: &ast::Expr) { loop { } }
fn walk_callee(&mut self, call: &ast::Expr, callee: &ast::Expr) {
loop { }
}
fn walk_stmt(&mut self, stmt: &ast::Stmt) { loop { } }
fn walk_local(&mut self, local: &ast::Local) { loop { } }
/// Indicates that the value of `blk` will be consumed, meaning either copied or moved
/// depending on its type.
fn walk_block(&mut self, blk: &ast::Block) { loop { } }
fn walk_struct_expr(&mut self, _expr: &ast::Expr,
fields: &Vec<ast::Field>,
opt_with: &Option<P<ast::Expr>>) {
loop { }
}
fn walk_adjustment(&mut self, expr: &ast::Expr) { loop { } }
/// Autoderefs for overloaded Deref calls in fact reference their receiver. That is, if we have
/// `(*x)` where `x` is of type `Rc<T>`, then this in fact is equivalent to `x.deref()`. Since
/// `deref()` is declared with `&self`, this is an autoref of `x`.
fn walk_autoderefs(&mut self, expr: &ast::Expr,
autoderefs: uint) {
loop { }
}
fn walk_autoref(&mut self, expr: &ast::Expr,
autoref: &ty::AutoRef, n: uint) {
loop { }
}
fn walk_overloaded_operator(&mut self, expr: &ast::Expr,
receiver: &ast::Expr,
rhs: Vec<&ast::Expr>,
pass_args: PassArgs) -> bool {
loop { }
}
fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>,
arm: &ast::Arm) -> TrackMatchMode<Span> {
loop { }
}
fn walk_arm(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm,
mode: MatchMode) {
loop { }
}
/// Walks an pat that occurs in isolation (i.e. top-level of fn
/// arg or let binding. *Not* a match arm or nested pat.)
fn walk_irrefutable_pat(&mut self, cmt_discr: mc::cmt<'tcx>,
pat: &ast::Pat) {
loop { }
}
/// Identifies any bindings within `pat` and accumulates within
/// `mode` whether the overall pattern/match structure is a move,
/// copy, or borrow.
fn determine_pat_move_mode(&mut self, cmt_discr: mc::cmt<'tcx>,
pat: &ast::Pat,
mode: &mut TrackMatchMode<Span>) {
loop { }
}
/// The core driver for walking a pattern; `match_mode` must be
/// established up front, e.g. via `determine_pat_move_mode` (see
/// also `walk_irrefutable_pat` for patterns that stand alone).
fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &ast::Pat,
match_mode: MatchMode) {
loop { }
}
fn walk_captures(&mut self, closure_expr: &ast::Expr) {
loop { }
}
fn walk_by_ref_captures(&mut self, closure_expr: &ast::Expr,
freevars: &[ty::Freevar]) {
loop { }
}
fn walk_by_value_captures(&mut self, closure_expr: &ast::Expr,
freevars: &[ty::Freevar]) {
loop { }
}
fn cat_captured_var(&mut self, closure_id: ast::NodeId,
closure_span: Span, upvar_def: def::Def)
-> mc::McResult<mc::cmt<'tcx>> {
loop { }
}
}
fn copy_or_move<'tcx>(typer: &mc::Typer<'tcx>, cmt: &mc::cmt<'tcx>,
move_reason: MoveReason) -> ConsumeMode {
loop { }
}
}
pub mod fast_reject {
use middle::ty::{self, Ty};
use syntax::ast;
use self::SimplifiedType::*;
/// See `simplify_type
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum SimplifiedType {
BoolSimplifiedType,
CharSimplifiedType,
IntSimplifiedType(ast::IntTy),
UintSimplifiedType(ast::UintTy),
FloatSimplifiedType(ast::FloatTy),
EnumSimplifiedType(ast::DefId),
StrSimplifiedType,
VecSimplifiedType,
PtrSimplifiedType,
TupleSimplifiedType(uint),
TraitSimplifiedType(ast::DefId),
StructSimplifiedType(ast::DefId),
UnboxedClosureSimplifiedType(ast::DefId),
FunctionSimplifiedType(uint),
ParameterSimplifiedType,
}
/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
/// The idea is to get something simple that we can use to quickly decide if two types could unify
/// during method lookup.
///
/// If `can_simplify_params` is false, then we will fail to simplify type parameters entirely. This
/// is useful when those type parameters would be instantiated with fresh type variables, since
/// then we can't say much about whether two types would unify. Put another way,
/// `can_simplify_params` should be true if type parameters appear free in `ty` and `false` if they
/// are to be considered bound.
pub fn simplify_type(tcx: &ty::ctxt, ty: Ty,
can_simplify_params: bool)
-> Option<SimplifiedType> {
loop { }
}
}
pub mod graph {
//! A graph module for use in dataflow, region resolution, and elsewhere.
//!
//! # Interface details
//!
//! You customize the graph by specifying a "node data" type `N` and an
//! "edge data" type `E`. You can then later gain access (mutable or
//! immutable) to these "user-data" bits. Currently, you can only add
//! nodes or edges to the graph. You cannot remove or modify them once
//! added. This could be changed if we have a need.
//!
//! # Implementation details
//!
//! The main tricky thing about this code is the way that edges are
//! stored. The edges are stored in a central array, but they are also
//! threaded onto two linked lists for each node, one for incoming edges
//! and one for outgoing edges. Note that every edge is a member of some
//! incoming list and some outgoing list. Basically you can load the
//! first index of the linked list from the node data structures (the
//! field `first_edge`) and then, for each edge, load the next index from
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).
#![allow(dead_code)]
use std::fmt::{Formatter, Error, Show};
use std::uint;
use std::collections::BitvSet;
pub struct Graph<N, E> {
nodes: Vec<Node<N>>,
edges: Vec<Edge<E>>,
}
pub struct Node<N> {
first_edge: [EdgeIndex; 2],
pub data: N,
}
pub struct Edge<E> {
next_edge: [EdgeIndex; 2],
source: NodeIndex,
target: NodeIndex,
pub data: E,
}
impl <E: Show> Show for Edge<E> {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
loop { }
}
}
#[derive(Clone, Copy, PartialEq, Show)]
pub struct NodeIndex(pub uint);
#[allow(non_upper_case_globals)]
pub const InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
#[derive(Copy, PartialEq, Show)]
pub struct EdgeIndex(pub uint);
#[allow(non_upper_case_globals)]
pub const InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
#[derive(Copy, Show)]
pub struct Direction {
repr: uint,
}
#[allow(non_upper_case_globals)]
pub const Outgoing: Direction = Direction{repr: 0,};
#[allow(non_upper_case_globals)]
pub const Incoming: Direction = Direction{repr: 1,};
impl NodeIndex {
fn get(&self) -> uint { loop { } }
/// Returns unique id (unique with respect to the graph holding associated node).
pub fn node_id(&self) -> uint { loop { } }
}
impl EdgeIndex {
fn get(&self) -> uint { loop { } }
/// Returns unique id (unique with respect to the graph holding associated edge).
pub fn edge_id(&self) -> uint { loop { } }
}
impl <N, E> Graph<N, E> {
pub fn new() -> Graph<N, E> { loop { } }
pub fn with_capacity(num_nodes: uint, num_edges: uint)
-> Graph<N, E> {
loop { }
}
#[inline]
pub fn all_nodes<'a>(&'a self) -> &'a [Node<N>] { loop { } }
#[inline]
pub fn all_edges<'a>(&'a self) -> &'a [Edge<E>] { loop { } }
pub fn next_node_index(&self) -> NodeIndex { loop { } }
pub fn add_node(&mut self, data: N) -> NodeIndex { loop { } }
pub fn mut_node_data<'a>(&'a mut self, idx: NodeIndex)
-> &'a mut N {
loop { }
}
pub fn node_data<'a>(&'a self, idx: NodeIndex) -> &'a N {
loop { }
}
pub fn node<'a>(&'a self, idx: NodeIndex) -> &'a Node<N> {
loop { }
}
pub fn next_edge_index(&self) -> EdgeIndex { loop { } }
pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex,
data: E) -> EdgeIndex {
loop { }
}
pub fn mut_edge_data<'a>(&'a mut self, idx: EdgeIndex)
-> &'a mut E {
loop { }
}
pub fn edge_data<'a>(&'a self, idx: EdgeIndex) -> &'a E {
loop { }
}
pub fn edge<'a>(&'a self, idx: EdgeIndex) -> &'a Edge<E> {
loop { }
}
pub fn first_adjacent(&self, node: NodeIndex, dir: Direction)
-> EdgeIndex {
//! Accesses the index of the first edge adjacent to `node`.
//! This is useful if you wish to modify the graph while walking
//! the linked list of edges.
loop { }
}
pub fn next_adjacent(&self, edge: EdgeIndex, dir: Direction)
-> EdgeIndex {
//! Accesses the next edge in a given direction.
//! This is useful if you wish to modify the graph while walking
//! the linked list of edges.
loop { }
}
pub fn each_node<'a, F>(&'a self, mut f: F) -> bool where
F: FnMut(NodeIndex, &'a Node<N>) -> bool {
//! Iterates over all edges defined in the graph.
loop { }
}
pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool where
F: FnMut(EdgeIndex, &'a Edge<E>) -> bool {
//! Iterates over all edges defined in the graph
loop { }
}
pub fn each_outgoing_edge<'a,
F>(&'a self, source: NodeIndex, f: F)
-> bool where F: FnMut(EdgeIndex, &'a Edge<E>) -> bool {
//! Iterates over all outgoing edges from the node `from`
loop { }
}
pub fn each_incoming_edge<'a,
F>(&'a self, target: NodeIndex, f: F)
-> bool where F: FnMut(EdgeIndex, &'a Edge<E>) -> bool {
//! Iterates over all incoming edges to the node `target`
loop { }
}
pub fn each_adjacent_edge<'a,
F>(&'a self, node: NodeIndex,
dir: Direction, mut f: F) -> bool
where F: FnMut(EdgeIndex, &'a Edge<E>) -> bool {
//! Iterates over all edges adjacent to the node `node`
//! in the direction `dir` (either `Outgoing` or `Incoming)
loop { }
}
pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F) where
F: FnMut(uint, EdgeIndex, &'a Edge<E>) -> bool {
loop { }
}
pub fn depth_traverse<'a>(&'a self, start: NodeIndex)
-> DepthFirstTraversal<'a, N, E> {
loop { }
}
}
pub struct DepthFirstTraversal<'g, N: 'g, E: 'g> {
graph: &'g Graph<N, E>,
stack: Vec<NodeIndex>,
visited: BitvSet,
}
impl <'g, N, E> Iterator for DepthFirstTraversal<'g, N, E> {type
Item
=
&'g N;
fn next(&mut self) -> Option<&'g N> { loop { } }
}
pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F) where
F: FnMut(EdgeIndex) -> bool {
loop { }
}
impl <E> Edge<E> {
pub fn source(&self) -> NodeIndex { loop { } }
pub fn target(&self) -> NodeIndex { loop { } }
}
#[cfg(test)]
mod test {
use middle::graph::*;
use std::fmt::Show;
type TestNode = Node<&'static str>;
type TestEdge = Edge<&'static str>;
type TestGraph = Graph<&'static str, &'static str>;
fn create_graph() -> TestGraph { loop { } }
#[test]
fn each_node() { loop { } }
#[test]
fn each_edge() { loop { } }
fn test_adjacent_edges<N: PartialEq + Show, E: PartialEq +
Show>(graph: &Graph<N, E>,
start_index: NodeIndex,
start_data: N,
expected_incoming: &[(E, N)],
expected_outgoing: &[(E, N)]) {
loop { }
}
#[test]
fn each_adjacent_from_a() { loop { } }
#[test]
fn each_adjacent_from_b() { loop { } }
#[test]
fn each_adjacent_from_c() { loop { } }
#[test]
fn each_adjacent_from_d() { loop { } }
}
}
pub mod intrinsicck {
use metadata::csearch;
use middle::def::DefFn;
use middle::subst::{Subst, Substs, EnumeratedItems};
use middle::ty::{TransmuteRestriction, ctxt, ty_bare_fn};
use middle::ty::{self, Ty};
use util::ppaux::Repr;
use syntax::abi::RustIntrinsic;
use syntax::ast::DefId;
use syntax::ast;
use syntax::ast_map::NodeForeignItem;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::visit::Visitor;
use syntax::visit;
pub fn check_crate(tcx: &ctxt) { loop { } }
struct IntrinsicCheckingVisitor<'a, 'tcx:'a> {
tcx: &'a ctxt<'tcx>,
param_envs: Vec<ty::ParameterEnvironment<'a, 'tcx>>,
dummy_sized_ty: Ty<'tcx>,
dummy_unsized_ty: Ty<'tcx>,
}
impl <'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool { loop { } }
fn check_transmute(&self, span: Span, from: Ty<'tcx>,
to: Ty<'tcx>, id: ast::NodeId) {
loop { }
}
fn with_each_combination(&self, span: Span,
param_env:
&ty::ParameterEnvironment<'a, 'tcx>,
mut types_in_scope:
EnumeratedItems<Ty<'tcx>>,
substs: &mut Substs<'tcx>,
callback: &mut FnMut(&Substs<'tcx>)) {
loop { }
}
fn push_transmute_restriction(&self,
restriction:
TransmuteRestriction<'tcx>) {
loop { }
}
}
impl <'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx>
{
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, id: ast::NodeId) {
loop { }
}
fn visit_expr(&mut self, expr: &ast::Expr) { loop { } }
}
impl <'tcx> Repr<'tcx> for TransmuteRestriction<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
}
pub mod infer {
//! See doc.rs for documentation
#![allow(non_camel_case_types)]
pub use self::LateBoundRegionConversionTime::*;
pub use self::RegionVariableOrigin::*;
pub use self::SubregionOrigin::*;
pub use self::TypeOrigin::*;
pub use self::ValuePairs::*;
pub use self::fixup_err::*;
pub use middle::ty::IntVarValue;
pub use self::freshen::TypeFreshener;
pub use self::region_inference::GenericKind;
use middle::subst;
use middle::subst::Substs;
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid,
UnconstrainedNumeric};
use middle::ty::replace_late_bound_regions;
use middle::ty::{self, Ty};
use middle::ty_fold::{TypeFolder, TypeFoldable};
use std::cell::{RefCell};
use std::rc::Rc;
use syntax::ast;
use syntax::codemap;
use syntax::codemap::Span;
use util::common::indent;
use util::nodemap::FnvHashMap;
use util::ppaux::{ty_to_string};
use util::ppaux::{Repr, UserString};
use self::coercion::Coerce;
use self::combine::{Combine, Combineable, CombineFields};
use self::region_inference::{RegionVarBindings, RegionSnapshot};
use self::equate::Equate;
use self::sub::Sub;
use self::lub::Lub;
use self::unify::{UnificationTable,
InferCtxtMethodsForSimplyUnifiableTypes};
use self::error_reporting::ErrorReporting;
pub mod coercion {
//! # Type Coercion
//!
//! Under certain circumstances we will coerce from one type to another,
//! for example by auto-borrowing. This occurs in situations where the
//! compiler has a firm 'expected type' that was supplied from the user,
//! and where the actual type is similar to that expected type in purpose
//! but not in representation (so actual subtyping is inappropriate).
//!
//! ## Reborrowing
//!
//! Note that if we are expecting a reference, we will *reborrow*
//! even if the argument provided was already a reference. This is
//! useful for freezing mut/const things (that is, when the expected is &T
//! but you have &const T or &mut T) and also for avoiding the linearity
//! of mut things (when the expected is &mut T and you have &mut T). See
//! the various `src/test/run-pass/coerce-reborrow-*.rs` tests for
//! examples of where this is useful.
//!
//! ## Subtle note
//!
//! When deciding what type coercions to consider, we do not attempt to
//! resolve any type variables we may encounter. This is because `b`
//! represents the expected type "as the user wrote it", meaning that if
//! the user defined a generic function like
//!
//! fn foo<A>(a: A, b: A) { ... }
//!
//! and then we wrote `foo(&1, @2)`, we will not auto-borrow
//! either argument. In older code we went to some lengths to
//! resolve the `b` variable, which could mean that we'd
//! auto-borrow later arguments but not earlier ones, which
//! seems very confusing.
//!
//! ## Subtler note
//!
//! However, right now, if the user manually specifies the
//! values for the type variables, as so:
//!
//! foo::<&int>(@1, @2)
//!
//! then we *will* auto-borrow, because we can't distinguish this from a
//! function that declared `&int`. This is inconsistent but it's easiest
//! at the moment. The right thing to do, I think, is to consider the
//! *unsubstituted* type when deciding whether to auto-borrow, but the
//! *substituted* type when considering the bounds and so forth. But most
//! of our methods don't give access to the unsubstituted type, and
//! rightly so because they'd be error-prone. So maybe the thing to do is
//! to actually determine the kind of coercions that should occur
//! separately and pass them in. Or maybe it's ok as is. Anyway, it's
//! sort of a minor point so I've opted to leave it for later---after all
//! we may want to adjust precisely when coercions occur.
use super::{CoerceResult, Coercion};
use super::combine::{CombineFields, Combine};
use super::sub::Sub;
use middle::subst;
use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef,
AutoUnsize, AutoUnsafe};
use middle::ty::{mt};
use middle::ty::{self, Ty};
use util::ppaux;
use util::ppaux::Repr;
use syntax::ast;
pub struct Coerce<'f, 'tcx:'f>(pub CombineFields<'f, 'tcx>);
impl <'f, 'tcx> Coerce<'f, 'tcx> {
pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f, 'tcx> {
loop { }
}
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
pub fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> CoerceResult<'tcx> {
loop { }
}
pub fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> CoerceResult<'tcx> {
loop { }
}
pub fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F)
-> T where F: FnOnce(Ty<'tcx>) -> T {
loop { }
}
pub fn coerce_borrowed_pointer(&self, a: Ty<'tcx>,
b: Ty<'tcx>,
mutbl_b: ast::Mutability)
-> CoerceResult<'tcx> {
loop { }
}
fn coerce_unsized(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> CoerceResult<'tcx> {
loop { }
}
fn unsize_ty(&self, ty_a: Ty<'tcx>, a: Ty<'tcx>,
ty_b: Ty<'tcx>)
-> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> {
loop { }
}
fn coerce_borrowed_object(&self, a: Ty<'tcx>, b: Ty<'tcx>,
b_mutbl: ast::Mutability)
-> CoerceResult<'tcx> {
loop { }
}
fn coerce_unsafe_object(&self, a: Ty<'tcx>, b: Ty<'tcx>,
b_mutbl: ast::Mutability)
-> CoerceResult<'tcx> {
loop { }
}
fn coerce_object<F,
G>(&self, a: Ty<'tcx>, b: Ty<'tcx>,
b_mutbl: ast::Mutability, mk_ty: F,
mk_adjust: G) -> CoerceResult<'tcx> where
F: FnOnce(Ty<'tcx>) -> Ty<'tcx>, G: FnOnce() ->
ty::AutoRef<'tcx> {
loop { }
}
pub fn coerce_borrowed_fn(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> CoerceResult<'tcx> {
loop { }
}
fn coerce_from_fn_item(&self, a: Ty<'tcx>,
fn_def_id_a: ast::DefId,
fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
b: Ty<'tcx>) -> CoerceResult<'tcx> {
/*!
* Attempts to coerce from the type of a Rust function item
* into a closure or a `proc`.
*/
loop { }
}
pub fn coerce_unsafe_ptr(&self, a: Ty<'tcx>, b: Ty<'tcx>,
mutbl_b: ast::Mutability)
-> CoerceResult<'tcx> {
loop { }
}
}
fn can_coerce_mutbls(from_mutbl: ast::Mutability,
to_mutbl: ast::Mutability) -> bool {
loop { }
}
}
pub mod combine {
use super::equate::Equate;
use super::glb::Glb;
use super::lub::Lub;
use super::sub::Sub;
use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
use super::{InferCtxt, cres};
use super::{MiscVariable, TypeTrace};
use super::type_variable::{RelationDir, EqTo, SubtypeOf,
SupertypeOf};
use middle::subst;
use middle::subst::{ErasedRegions, NonerasedRegions, Substs};
use middle::ty::{FloatVar, FnSig, IntVar, TyVar};
use middle::ty::{IntType, UintType};
use middle::ty::{BuiltinBounds};
use middle::ty::{self, Ty};
use middle::ty_fold;
use middle::ty_fold::{TypeFoldable};
use util::ppaux::Repr;
use std::rc::Rc;
use syntax::ast::{Onceness, Unsafety};
use syntax::ast;
use syntax::abi;
use syntax::codemap::Span;
pub trait Combine<'tcx>: Sized {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>;
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { loop { } }
fn tag(&self) -> String;
fn a_is_expected(&self) -> bool;
fn trace(&self) -> TypeTrace<'tcx>;
fn equate<'a>(&'a self) -> Equate<'a, 'tcx>;
fn sub<'a>(&'a self) -> Sub<'a, 'tcx>;
fn lub<'a>(&'a self) -> Lub<'a, 'tcx>;
fn glb<'a>(&'a self) -> Glb<'a, 'tcx>;
fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>)
-> cres<'tcx, ty::mt<'tcx>>;
fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>>;
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>>;
fn tps(&self, _: subst::ParamSpace, as_: &[Ty<'tcx>],
bs: &[Ty<'tcx>]) -> cres<'tcx, Vec<Ty<'tcx>>> {
loop { }
}
fn substs(&self, item_def_id: ast::DefId,
a_subst: &subst::Substs<'tcx>,
b_subst: &subst::Substs<'tcx>)
-> cres<'tcx, subst::Substs<'tcx>> {
loop { }
}
fn substs_variances(&self,
variances: Option<&ty::ItemVariances>,
a_subst: &subst::Substs<'tcx>,
b_subst: &subst::Substs<'tcx>)
-> cres<'tcx, subst::Substs<'tcx>> {
loop { }
}
fn bare_fn_tys(&self, a: &ty::BareFnTy<'tcx>,
b: &ty::BareFnTy<'tcx>)
-> cres<'tcx, ty::BareFnTy<'tcx>> {
loop { }
}
fn closure_tys(&self, a: &ty::ClosureTy<'tcx>,
b: &ty::ClosureTy<'tcx>)
-> cres<'tcx, ty::ClosureTy<'tcx>> {
loop { }
}
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
-> cres<'tcx, ty::FnSig<'tcx>> {
loop { }
}
fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn unsafeties(&self, a: Unsafety, b: Unsafety)
-> cres<'tcx, Unsafety>;
fn abi(&self, a: abi::Abi, b: abi::Abi)
-> cres<'tcx, abi::Abi> {
loop { }
}
fn oncenesses(&self, a: Onceness, b: Onceness)
-> cres<'tcx, Onceness>;
fn projection_tys(&self, a: &ty::ProjectionTy<'tcx>,
b: &ty::ProjectionTy<'tcx>)
-> cres<'tcx, ty::ProjectionTy<'tcx>> {
loop { }
}
fn projection_predicates(&self,
a: &ty::ProjectionPredicate<'tcx>,
b: &ty::ProjectionPredicate<'tcx>)
-> cres<'tcx, ty::ProjectionPredicate<'tcx>> {
loop { }
}
fn projection_bounds(&self,
a:
&Vec<ty::PolyProjectionPredicate<'tcx>>,
b:
&Vec<ty::PolyProjectionPredicate<'tcx>>)
-> cres<'tcx, Vec<ty::PolyProjectionPredicate<'tcx>>> {
loop { }
}
fn existential_bounds(&self, a: &ty::ExistentialBounds<'tcx>,
b: &ty::ExistentialBounds<'tcx>)
-> cres<'tcx, ty::ExistentialBounds<'tcx>> {
loop { }
}
fn builtin_bounds
(&self, a: ty::BuiltinBounds, b: ty::BuiltinBounds)
-> cres<'tcx, ty::BuiltinBounds>;
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region>;
fn regions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region>;
fn trait_stores(&self, vk: ty::terr_vstore_kind,
a: ty::TraitStore, b: ty::TraitStore)
-> cres<'tcx, ty::TraitStore> {
loop { }
}
fn trait_refs(&self, a: &ty::TraitRef<'tcx>,
b: &ty::TraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> {
loop { }
}
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> cres<'tcx, ty::Binder<T>> where T: Combineable<'tcx>;
}
pub trait Combineable<'tcx>: Repr<'tcx> + TypeFoldable<'tcx> {
fn combine<C: Combine<'tcx>>(combiner: &C, a: &Self, b: &Self)
-> cres<'tcx, Self>;
}
impl <'tcx, T> Combineable<'tcx> for Rc<T> where
T: Combineable<'tcx> {
fn combine<C: Combine<'tcx>>(combiner: &C, a: &Rc<T>,
b: &Rc<T>) -> cres<'tcx, Rc<T>> {
loop { }
}
}
impl <'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> {
fn combine<C: Combine<'tcx>>(combiner: &C,
a: &ty::TraitRef<'tcx>,
b: &ty::TraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>> {
loop { }
}
}
impl <'tcx> Combineable<'tcx> for Ty<'tcx> {
fn combine<C: Combine<'tcx>>(combiner: &C, a: &Ty<'tcx>,
b: &Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
}
impl <'tcx> Combineable<'tcx> for ty::ProjectionPredicate<'tcx> {
fn combine<C: Combine<'tcx>>(combiner: &C,
a:
&ty::ProjectionPredicate<'tcx>,
b:
&ty::ProjectionPredicate<'tcx>)
-> cres<'tcx, ty::ProjectionPredicate<'tcx>> {
loop { }
}
}
impl <'tcx> Combineable<'tcx> for ty::FnSig<'tcx> {
fn combine<C: Combine<'tcx>>(combiner: &C,
a: &ty::FnSig<'tcx>,
b: &ty::FnSig<'tcx>)
-> cres<'tcx, ty::FnSig<'tcx>> {
loop { }
}
}
#[derive(Clone)]
pub struct CombineFields<'a, 'tcx:'a> {
pub infcx: &'a InferCtxt<'a, 'tcx>,
pub a_is_expected: bool,
pub trace: TypeTrace<'tcx>,
}
pub fn expected_found<'tcx, C: Combine<'tcx>,
T>(this: &C, a: T, b: T)
-> ty::expected_found<T> {
loop { }
}
pub fn super_tys<'tcx,
C: Combine<'tcx>>(this: &C, a: Ty<'tcx>,
b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
impl <'f, 'tcx> CombineFields<'f, 'tcx> {
pub fn switch_expected(&self) -> CombineFields<'f, 'tcx> {
loop { }
}
fn equate(&self) -> Equate<'f, 'tcx> { loop { } }
fn sub(&self) -> Sub<'f, 'tcx> { loop { } }
pub fn instantiate(&self, a_ty: Ty<'tcx>, dir: RelationDir,
b_vid: ty::TyVid) -> cres<'tcx, ()> {
loop { }
}
/// Attempts to generalize `ty` for the type variable `for_vid`. This checks for cycle -- that
/// is, whether the type `ty` references `for_vid`. If `make_region_vars` is true, it will also
/// replace all regions with fresh variables. Returns `ty_err` in the case of a cycle, `Ok`
/// otherwise.
fn generalize(&self, ty: Ty<'tcx>, for_vid: ty::TyVid,
make_region_vars: bool)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
}
struct Generalizer<'cx, 'tcx:'cx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
span: Span,
for_vid: ty::TyVid,
make_region_vars: bool,
cycle_detected: bool,
}
impl <'cx, 'tcx> ty_fold::TypeFolder<'tcx> for
Generalizer<'cx, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { loop { } }
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
}
}
pub mod doc {
//! # Type inference engine
//!
//! This is loosely based on standard HM-type inference, but with an
//! extension to try and accommodate subtyping. There is nothing
//! principled about this extension; it's sound---I hope!---but it's a
//! heuristic, ultimately, and does not guarantee that it finds a valid
//! typing even if one exists (in fact, there are known scenarios where it
//! fails, some of which may eventually become problematic).
//!
//! ## Key idea
//!
//! The main change is that each type variable T is associated with a
//! lower-bound L and an upper-bound U. L and U begin as bottom and top,
//! respectively, but gradually narrow in response to new constraints
//! being introduced. When a variable is finally resolved to a concrete
//! type, it can (theoretically) select any type that is a supertype of L
//! and a subtype of U.
//!
//! There are several critical invariants which we maintain:
//!
//! - the upper-bound of a variable only becomes lower and the lower-bound
//! only becomes higher over time;
//! - the lower-bound L is always a subtype of the upper bound U;
//! - the lower-bound L and upper-bound U never refer to other type variables,
//! but only to types (though those types may contain type variables).
//!
//! > An aside: if the terms upper- and lower-bound confuse you, think of
//! > "supertype" and "subtype". The upper-bound is a "supertype"
//! > (super=upper in Latin, or something like that anyway) and the lower-bound
//! > is a "subtype" (sub=lower in Latin). I find it helps to visualize
//! > a simple class hierarchy, like Java minus interfaces and
//! > primitive types. The class Object is at the root (top) and other
//! > types lie in between. The bottom type is then the Null type.
//! > So the tree looks like:
//! >
//! > ```text
//! > Object
//! > / \
//! > String Other
//! > \ /
//! > (null)
//! > ```
//! >
//! > So the upper bound type is the "supertype" and the lower bound is the
//! > "subtype" (also, super and sub mean upper and lower in Latin, or something
//! > like that anyway).
//!
//! ## Satisfying constraints
//!
//! At a primitive level, there is only one form of constraint that the
//! inference understands: a subtype relation. So the outside world can
//! say "make type A a subtype of type B". If there are variables
//! involved, the inferencer will adjust their upper- and lower-bounds as
//! needed to ensure that this relation is satisfied. (We also allow "make
//! type A equal to type B", but this is translated into "A <: B" and "B
//! <: A")
//!
//! As stated above, we always maintain the invariant that type bounds
//! never refer to other variables. This keeps the inference relatively
//! simple, avoiding the scenario of having a kind of graph where we have
//! to pump constraints along and reach a fixed point, but it does impose
//! some heuristics in the case where the user is relating two type
//! variables A <: B.
//!
//! Combining two variables such that variable A will forever be a subtype
//! of variable B is the trickiest part of the algorithm because there is
//! often no right choice---that is, the right choice will depend on
//! future constraints which we do not yet know. The problem comes about
//! because both A and B have bounds that can be adjusted in the future.
//! Let's look at some of the cases that can come up.
//!
//! Imagine, to start, the best case, where both A and B have an upper and
//! lower bound (that is, the bounds are not top nor bot respectively). In
//! that case, if we're lucky, A.ub <: B.lb, and so we know that whatever
//! A and B should become, they will forever have the desired subtyping
//! relation. We can just leave things as they are.
//!
//! ### Option 1: Unify
//!
//! However, suppose that A.ub is *not* a subtype of B.lb. In
//! that case, we must make a decision. One option is to unify A
//! and B so that they are one variable whose bounds are:
//!
//! UB = GLB(A.ub, B.ub)
//! LB = LUB(A.lb, B.lb)
//!
//! (Note that we will have to verify that LB <: UB; if it does not, the
//! types are not intersecting and there is an error) In that case, A <: B
//! holds trivially because A==B. However, we have now lost some
//! flexibility, because perhaps the user intended for A and B to end up
//! as different types and not the same type.
//!
//! Pictorally, what this does is to take two distinct variables with
//! (hopefully not completely) distinct type ranges and produce one with
//! the intersection.
//!
//! ```text
//! B.ub B.ub
//! /\ /
//! A.ub / \ A.ub /
//! / \ / \ \ /
//! / X \ UB
//! / / \ \ / \
//! / / / \ / /
//! \ \ / / \ /
//! \ X / LB
//! \ / \ / / \
//! \ / \ / / \
//! A.lb B.lb A.lb B.lb
//! ```
//!
//!
//! ### Option 2: Relate UB/LB
//!
//! Another option is to keep A and B as distinct variables but set their
//! bounds in such a way that, whatever happens, we know that A <: B will hold.
//! This can be achieved by ensuring that A.ub <: B.lb. In practice there
//! are two ways to do that, depicted pictorially here:
//!
//! ```text
//! Before Option #1 Option #2
//!
//! B.ub B.ub B.ub
//! /\ / \ / \
//! A.ub / \ A.ub /(B')\ A.ub /(B')\
//! / \ / \ \ / / \ / /
//! / X \ __UB____/ UB /
//! / / \ \ / | | /
//! / / / \ / | | /
//! \ \ / / /(A')| | /
//! \ X / / LB ______LB/
//! \ / \ / / / \ / (A')/ \
//! \ / \ / \ / \ \ / \
//! A.lb B.lb A.lb B.lb A.lb B.lb
//! ```
//!
//! In these diagrams, UB and LB are defined as before. As you can see,
//! the new ranges `A'` and `B'` are quite different from the range that
//! would be produced by unifying the variables.
//!
//! ### What we do now
//!
//! Our current technique is to *try* (transactionally) to relate the
//! existing bounds of A and B, if there are any (i.e., if `UB(A) != top
//! && LB(B) != bot`). If that succeeds, we're done. If it fails, then
//! we merge A and B into same variable.
//!
//! This is not clearly the correct course. For example, if `UB(A) !=
//! top` but `LB(B) == bot`, we could conceivably set `LB(B)` to `UB(A)`
//! and leave the variables unmerged. This is sometimes the better
//! course, it depends on the program.
//!
//! The main case which fails today that I would like to support is:
//!
//! ```text
//! fn foo<T>(x: T, y: T) { ... }
//!
//! fn bar() {
//! let x: @mut int = @mut 3;
//! let y: @int = @3;
//! foo(x, y);
//! }
//! ```
//!
//! In principle, the inferencer ought to find that the parameter `T` to
//! `foo(x, y)` is `@const int`. Today, however, it does not; this is
//! because the type variable `T` is merged with the type variable for
//! `X`, and thus inherits its UB/LB of `@mut int`. This leaves no
//! flexibility for `T` to later adjust to accommodate `@int`.
//!
//! ### What to do when not all bounds are present
//!
//! In the prior discussion we assumed that A.ub was not top and B.lb was
//! not bot. Unfortunately this is rarely the case. Often type variables
//! have "lopsided" bounds. For example, if a variable in the program has
//! been initialized but has not been used, then its corresponding type
//! variable will have a lower bound but no upper bound. When that
//! variable is then used, we would like to know its upper bound---but we
//! don't have one! In this case we'll do different things depending on
//! how the variable is being used.
//!
//! ## Transactional support
//!
//! Whenever we adjust merge variables or adjust their bounds, we always
//! keep a record of the old value. This allows the changes to be undone.
//!
//! ## Regions
//!
//! I've only talked about type variables here, but region variables
//! follow the same principle. They have upper- and lower-bounds. A
//! region A is a subregion of a region B if A being valid implies that B
//! is valid. This basically corresponds to the block nesting structure:
//! the regions for outer block scopes are superregions of those for inner
//! block scopes.
//!
//! ## Integral and floating-point type variables
//!
//! There is a third variety of type variable that we use only for
//! inferring the types of unsuffixed integer literals. Integral type
//! variables differ from general-purpose type variables in that there's
//! no subtyping relationship among the various integral types, so instead
//! of associating each variable with an upper and lower bound, we just
//! use simple unification. Each integer variable is associated with at
//! most one integer type. Floating point types are handled similarly to
//! integral types.
//!
//! ## GLB/LUB
//!
//! Computing the greatest-lower-bound and least-upper-bound of two
//! types/regions is generally straightforward except when type variables
//! are involved. In that case, we follow a similar "try to use the bounds
//! when possible but otherwise merge the variables" strategy. In other
//! words, `GLB(A, B)` where `A` and `B` are variables will often result
//! in `A` and `B` being merged and the result being `A`.
//!
//! ## Type coercion
//!
//! We have a notion of assignability which differs somewhat from
//! subtyping; in particular it may cause region borrowing to occur. See
//! the big comment later in this file on Type Coercion for specifics.
//!
//! ### In conclusion
//!
//! I showed you three ways to relate `A` and `B`. There are also more,
//! of course, though I'm not sure if there are any more sensible options.
//! The main point is that there are various options, each of which
//! produce a distinct range of types for `A` and `B`. Depending on what
//! the correct values for A and B are, one of these options will be the
//! right choice: but of course we don't know the right values for A and B
//! yet, that's what we're trying to find! In our code, we opt to unify
//! (Option #1).
//!
//! # Implementation details
//!
//! We make use of a trait-like implementation strategy to consolidate
//! duplicated code between subtypes, GLB, and LUB computations. See the
//! section on "Type Combining" below for details.
}
pub mod equate {
use middle::ty::{BuiltinBounds};
use middle::ty::{self, Ty};
use middle::ty::TyVar;
use middle::infer::combine::*;
use middle::infer::{cres};
use middle::infer::glb::Glb;
use middle::infer::InferCtxt;
use middle::infer::lub::Lub;
use middle::infer::sub::Sub;
use middle::infer::{TypeTrace, Subtype};
use middle::infer::type_variable::{EqTo};
use util::ppaux::{Repr};
use syntax::ast::{Onceness, Unsafety};
pub struct Equate<'f, 'tcx:'f> {
fields: CombineFields<'f, 'tcx>,
}
#[allow(non_snake_case)]
pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>)
-> Equate<'f, 'tcx> {
loop { }
}
impl <'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> {
loop { }
}
fn tag(&self) -> String { loop { } }
fn a_is_expected(&self) -> bool { loop { } }
fn trace(&self) -> TypeTrace<'tcx> { loop { } }
fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { loop { } }
fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { loop { } }
fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { loop { } }
fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { loop { } }
fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn regions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>)
-> cres<'tcx, ty::mt<'tcx>> {
loop { }
}
fn unsafeties(&self, a: Unsafety, b: Unsafety)
-> cres<'tcx, Unsafety> {
loop { }
}
fn oncenesses(&self, a: Onceness, b: Onceness)
-> cres<'tcx, Onceness> {
loop { }
}
fn builtin_bounds(&self, a: BuiltinBounds, b: BuiltinBounds)
-> cres<'tcx, BuiltinBounds> {
loop { }
}
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> cres<'tcx, ty::Binder<T>> where T: Combineable<'tcx> {
loop { }
}
}
}
pub mod error_reporting {
//! Error Reporting Code for the inference engine
//!
//! Because of the way inference, and in particular region inference,
//! works, it often happens that errors are not detected until far after
//! the relevant line of code has been type-checked. Therefore, there is
//! an elaborate system to track why a particular constraint in the
//! inference graph arose so that we can explain to the user what gave
//! rise to a particular error.
//!
//! The basis of the system are the "origin" types. An "origin" is the
//! reason that a constraint or inference variable arose. There are
//! different "origin" enums for different kinds of constraints/variables
//! (e.g., `TypeOrigin`, `RegionVariableOrigin`). An origin always has
//! a span, but also more information so that we can generate a meaningful
//! error message.
//!
//! Having a catalogue of all the different reasons an error can arise is
//! also useful for other reasons, like cross-referencing FAQs etc, though
//! we are not really taking advantage of this yet.
//!
//! # Region Inference
//!
//! Region inference is particularly tricky because it always succeeds "in
//! the moment" and simply registers a constraint. Then, at the end, we
//! can compute the full graph and report errors, so we need to be able to
//! store and later report what gave rise to the conflicting constraints.
//!
//! # Subtype Trace
//!
//! Determining whether `T1 <: T2` often involves a number of subtypes and
//! subconstraints along the way. A "TypeTrace" is an extended version
//! of an origin that traces the types and other values that were being
//! compared. It is not necessarily comprehensive (in fact, at the time of
//! this writing it only tracks the root values being compared) but I'd
//! like to extend it to include significant "waypoints". For example, if
//! you are comparing `(T1, T2) <: (T3, T4)`, and the problem is that `T2
//! <: T4` fails, I'd like the trace to include enough information to say
//! "in the 2nd element of the tuple". Similarly, failures when comparing
//! arguments or return types in fn types should be able to cite the
//! specific position, etc.
//!
//! # Reality vs plan
//!
//! Of course, there is still a LOT of code in typeck that has yet to be
//! ported to this system, and which relies on string concatenation at the
//! time of error detection.
use self::FreshOrKept::*;
use super::InferCtxt;
use super::TypeTrace;
use super::SubregionOrigin;
use super::RegionVariableOrigin;
use super::ValuePairs;
use super::region_inference::RegionResolutionError;
use super::region_inference::ConcreteFailure;
use super::region_inference::SubSupConflict;
use super::region_inference::SupSupConflict;
use super::region_inference::GenericBoundFailure;
use super::region_inference::GenericKind;
use super::region_inference::ProcessedErrors;
use super::region_inference::SameRegions;
use std::collections::HashSet;
use middle::def;
use middle::infer;
use middle::subst;
use middle::ty::{self, Ty};
use middle::ty::{Region, ReFree};
use std::cell::{Cell, RefCell};
use std::char::from_u32;
use std::rc::Rc;
use std::string::String;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::{name_to_dummy_lifetime,
PostExpansionMethod};
use syntax::owned_slice::OwnedSlice;
use syntax::codemap;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use util::ppaux::bound_region_to_string;
use util::ppaux::note_and_explain_region;
use util::ppaux::UserString;
pub trait ErrorReporting<'tcx> {
fn report_region_errors
(&self, errors: &Vec<RegionResolutionError<'tcx>>);
fn process_errors
(&self, errors: &Vec<RegionResolutionError<'tcx>>)
-> Vec<RegionResolutionError<'tcx>>;
fn report_type_error
(&self, trace: TypeTrace<'tcx>,
terr: &ty::type_err<'tcx>);
fn report_and_explain_type_error
(&self, trace: TypeTrace<'tcx>,
terr: &ty::type_err<'tcx>);
fn values_str(&self, values: &ValuePairs<'tcx>)
-> Option<String>;
fn expected_found_str<T: UserString<'tcx> + Resolvable<'tcx>>
(&self, exp_found: &ty::expected_found<T>)
-> Option<String>;
fn report_concrete_failure
(&self, origin: SubregionOrigin<'tcx>, sub: Region,
sup: Region);
fn report_generic_bound_failure
(&self, origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>, sub: Region, sups: Vec<Region>);
fn report_sub_sup_conflict
(&self, var_origin: RegionVariableOrigin,
sub_origin: SubregionOrigin<'tcx>, sub_region: Region,
sup_origin: SubregionOrigin<'tcx>, sup_region: Region);
fn report_sup_sup_conflict
(&self, var_origin: RegionVariableOrigin,
origin1: SubregionOrigin<'tcx>, region1: Region,
origin2: SubregionOrigin<'tcx>, region2: Region);
fn report_processed_errors
(&self, var_origin: &[RegionVariableOrigin],
trace_origin: &[(TypeTrace<'tcx>, ty::type_err<'tcx>)],
same_regions: &[SameRegions]);
fn give_suggestion(&self, same_regions: &[SameRegions]);
}
trait ErrorReportingHelpers<'tcx> {
fn report_inference_failure
(&self, var_origin: RegionVariableOrigin);
fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>);
fn give_expl_lifetime_param
(&self, decl: &ast::FnDecl, unsafety: ast::Unsafety,
ident: ast::Ident,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
generics: &ast::Generics, span: codemap::Span);
}
impl <'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
fn report_region_errors(&self,
errors:
&Vec<RegionResolutionError<'tcx>>) {
loop { }
}
fn process_errors(&self,
errors: &Vec<RegionResolutionError<'tcx>>)
-> Vec<RegionResolutionError<'tcx>> {
loop { }
}
fn report_type_error(&self, trace: TypeTrace<'tcx>,
terr: &ty::type_err<'tcx>) {
loop { }
}
fn report_and_explain_type_error(&self,
trace: TypeTrace<'tcx>,
terr: &ty::type_err<'tcx>) {
loop { }
}
/// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
/// error.
fn values_str(&self, values: &ValuePairs<'tcx>)
-> Option<String> {
loop { }
}
fn expected_found_str<T: UserString<'tcx> +
Resolvable<'tcx>>(&self,
exp_found:
&ty::expected_found<T>)
-> Option<String> {
loop { }
}
fn report_generic_bound_failure(&self,
origin: SubregionOrigin<'tcx>,
bound_kind: GenericKind<'tcx>,
sub: Region,
_sups: Vec<Region>) {
loop { }
}
fn report_concrete_failure(&self,
origin: SubregionOrigin<'tcx>,
sub: Region, sup: Region) {
loop { }
}
fn report_sub_sup_conflict(&self,
var_origin: RegionVariableOrigin,
sub_origin: SubregionOrigin<'tcx>,
sub_region: Region,
sup_origin: SubregionOrigin<'tcx>,
sup_region: Region) {
loop { }
}
fn report_sup_sup_conflict(&self,
var_origin: RegionVariableOrigin,
origin1: SubregionOrigin<'tcx>,
region1: Region,
origin2: SubregionOrigin<'tcx>,
region2: Region) {
loop { }
}
fn report_processed_errors(&self,
var_origins:
&[RegionVariableOrigin],
trace_origins:
&[(TypeTrace<'tcx>,
ty::type_err<'tcx>)],
same_regions: &[SameRegions]) {
loop { }
}
fn give_suggestion(&self, same_regions: &[SameRegions]) {
let scope_id = same_regions[0].scope_id;
let parent = self.tcx.map.get_parent(scope_id);
let parent_node = self.tcx.map.find(parent);
let node_inner = match parent_node {
Some(ref node) => match *node {
ast_map::NodeItem(ref item) => {
match item.node {
ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => {
Some((&**fn_decl, gen, pur, item.ident, None, item.span))
},
_ => None
}
}
ast_map::NodeImplItem(ref item) => {
match **item {
ast::MethodImplItem(ref m) => {
Some((m.pe_fn_decl(),
m.pe_generics(),
m.pe_unsafety(),
m.pe_ident(),
Some(&m.pe_explicit_self().node),
m.span))
}
ast::TypeImplItem(_) => None,
}
},
ast_map::NodeTraitItem(ref item) => {
match **item {
ast::ProvidedMethod(ref m) => {
Some((m.pe_fn_decl(),
m.pe_generics(),
m.pe_unsafety(),
m.pe_ident(),
Some(&m.pe_explicit_self().node),
m.span))
}
_ => None
}
}
_ => None
},
None => None
};
let (fn_decl, generics, unsafety, ident, expl_self, span)
= node_inner.expect("expect item fn");
let taken = lifetimes_in_scope(self.tcx, scope_id);
let life_giver = LifeGiver::with_taken(&taken[]);
let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
generics, same_regions, &life_giver);
let (fn_decl, expl_self, generics) = rebuilder.rebuild();
self.give_expl_lifetime_param(&fn_decl, unsafety, ident,
expl_self.as_ref(), &generics, span);
}
}
struct RebuildPathInfo<'a> {
path: &'a ast::Path,
indexes: Vec<u32>,
expected: u32,
anon_nums: &'a HashSet<u32>,
region_names: &'a HashSet<ast::Name>,
}
struct Rebuilder<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
fn_decl: &'a ast::FnDecl,
expl_self_opt: Option<&'a ast::ExplicitSelf_>,
generics: &'a ast::Generics,
same_regions: &'a [SameRegions],
life_giver: &'a LifeGiver,
cur_anon: Cell<u32>,
inserted_anons: RefCell<HashSet<u32>>,
}
enum FreshOrKept { Fresh, Kept, }
impl <'a, 'tcx> Rebuilder<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>, fn_decl: &'a ast::FnDecl,
expl_self_opt: Option<&'a ast::ExplicitSelf_>,
generics: &'a ast::Generics,
same_regions: &'a [SameRegions],
life_giver: &'a LifeGiver) -> Rebuilder<'a, 'tcx> {
loop { }
}
fn rebuild(&self)
-> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
loop { }
}
fn pick_lifetime(&self, region_names: &HashSet<ast::Name>)
-> (ast::Lifetime, FreshOrKept) {
loop { }
}
fn extract_anon_nums_and_names(&self,
same_regions: &SameRegions)
-> (HashSet<u32>, HashSet<ast::Name>) {
loop { }
}
fn extract_all_region_names(&self) -> HashSet<ast::Name> {
loop { }
}
fn inc_cur_anon(&self, n: u32) { loop { } }
fn offset_cur_anon(&self) { loop { } }
fn inc_and_offset_cur_anon(&self, n: u32) { loop { } }
fn track_anon(&self, anon: u32) { loop { } }
fn rebuild_ty_params(&self,
ty_params: OwnedSlice<ast::TyParam>,
lifetime: ast::Lifetime,
region_names: &HashSet<ast::Name>)
-> OwnedSlice<ast::TyParam> {
loop { }
}
fn rebuild_ty_param_bounds(&self,
ty_param_bounds:
OwnedSlice<ast::TyParamBound>,
lifetime: ast::Lifetime,
region_names: &HashSet<ast::Name>)
-> OwnedSlice<ast::TyParamBound> {
loop { }
}
fn rebuild_expl_self(&self,
expl_self_opt:
Option<ast::ExplicitSelf_>,
lifetime: ast::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> Option<ast::ExplicitSelf_> {
loop { }
}
fn rebuild_generics(&self, generics: &ast::Generics,
add: &Vec<ast::Lifetime>,
keep: &HashSet<ast::Name>,
remove: &HashSet<ast::Name>,
ty_params: OwnedSlice<ast::TyParam>,
where_clause: ast::WhereClause)
-> ast::Generics {
loop { }
}
fn rebuild_args_ty(&self, inputs: &[ast::Arg],
lifetime: ast::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> Vec<ast::Arg> {
loop { }
}
fn rebuild_output(&self, ty: &ast::FunctionRetTy,
lifetime: ast::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> ast::FunctionRetTy {
loop { }
}
fn rebuild_arg_ty_or_output(&self, ty: &ast::Ty,
lifetime: ast::Lifetime,
anon_nums: &HashSet<u32>,
region_names: &HashSet<ast::Name>)
-> P<ast::Ty> {
loop { }
}
fn rebuild_ty(&self, from: P<ast::Ty>, to: P<ast::Ty>)
-> P<ast::Ty> {
loop { }
}
fn rebuild_path(&self, rebuild_info: RebuildPathInfo,
lifetime: ast::Lifetime) -> ast::Path {
loop { }
}
}
impl <'a, 'tcx> ErrorReportingHelpers<'tcx> for
InferCtxt<'a, 'tcx> {
fn give_expl_lifetime_param(&self, decl: &ast::FnDecl,
unsafety: ast::Unsafety,
ident: ast::Ident,
opt_explicit_self:
Option<&ast::ExplicitSelf_>,
generics: &ast::Generics,
span: codemap::Span) {
loop { }
}
fn report_inference_failure(&self,
var_origin:
RegionVariableOrigin) {
loop { }
}
fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
loop { }
}
}
pub trait Resolvable<'tcx> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>) -> Self;
fn contains_error(&self) -> bool;
}
impl <'tcx> Resolvable<'tcx> for Ty<'tcx> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>)
-> Ty<'tcx> {
loop { }
}
fn contains_error(&self) -> bool { loop { } }
}
impl <'tcx> Resolvable<'tcx> for Rc<ty::TraitRef<'tcx>> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>)
-> Rc<ty::TraitRef<'tcx>> {
loop { }
}
fn contains_error(&self) -> bool { loop { } }
}
impl <'tcx> Resolvable<'tcx> for ty::PolyTraitRef<'tcx> {
fn resolve<'a>(&self, infcx: &InferCtxt<'a, 'tcx>)
-> ty::PolyTraitRef<'tcx> {
loop { }
}
fn contains_error(&self) -> bool { loop { } }
}
fn lifetimes_in_scope(tcx: &ty::ctxt, scope_id: ast::NodeId)
-> Vec<ast::LifetimeDef> {
loop { }
}
struct LifeGiver {
taken: HashSet<String>,
counter: Cell<uint>,
generated: RefCell<Vec<ast::Lifetime>>,
}
impl LifeGiver {
fn with_taken(taken: &[ast::LifetimeDef]) -> LifeGiver {
loop { }
}
fn inc_counter(&self) { loop { } }
fn give_lifetime(&self) -> ast::Lifetime { loop { } }
fn get_generated_lifetimes(&self) -> Vec<ast::Lifetime> {
loop { }
}
}
}
pub mod glb {
use super::combine::*;
use super::lattice::*;
use super::equate::Equate;
use super::higher_ranked::HigherRankedRelations;
use super::lub::Lub;
use super::sub::Sub;
use super::{cres, InferCtxt};
use super::{TypeTrace, Subtype};
use middle::ty::{BuiltinBounds};
use middle::ty::{self, Ty};
use syntax::ast::{Many, Once, MutImmutable, MutMutable};
use syntax::ast::{Onceness, Unsafety};
use util::ppaux::mt_to_string;
use util::ppaux::Repr;
/// "Greatest lower bound" (common subtype)
pub struct Glb<'f, 'tcx:'f> {
fields: CombineFields<'f, 'tcx>,
}
#[allow(non_snake_case)]
pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>)
-> Glb<'f, 'tcx> {
loop { }
}
impl <'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> {
loop { }
}
fn tag(&self) -> String { loop { } }
fn a_is_expected(&self) -> bool { loop { } }
fn trace(&self) -> TypeTrace<'tcx> { loop { } }
fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { loop { } }
fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { loop { } }
fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { loop { } }
fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { loop { } }
fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>)
-> cres<'tcx, ty::mt<'tcx>> {
loop { }
}
fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn unsafeties(&self, a: Unsafety, b: Unsafety)
-> cres<'tcx, Unsafety> {
loop { }
}
fn oncenesses(&self, a: Onceness, b: Onceness)
-> cres<'tcx, Onceness> {
loop { }
}
fn builtin_bounds(&self, a: ty::BuiltinBounds,
b: ty::BuiltinBounds)
-> cres<'tcx, ty::BuiltinBounds> {
loop { }
}
fn regions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> cres<'tcx, ty::Binder<T>> where T: Combineable<'tcx> {
loop { }
}
}
}
mod higher_ranked {
//! Helper routines for higher-ranked things. See the `doc` module at
//! the end of the file for details.
use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType,
SkolemizationMap};
use super::combine::{Combine, Combineable};
use middle::ty::{self, Binder};
use middle::ty_fold::{self, TypeFoldable};
use syntax::codemap::Span;
use util::nodemap::{FnvHashMap, FnvHashSet};
use util::ppaux::Repr;
pub trait HigherRankedRelations<'tcx> {
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
-> cres<'tcx, Binder<T>> where T: Combineable<'tcx>;
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>)
-> cres<'tcx, Binder<T>> where T: Combineable<'tcx>;
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>)
-> cres<'tcx, Binder<T>> where T: Combineable<'tcx>;
}
trait InferCtxtExt<'tcx> {
fn tainted_regions
(&self, snapshot: &CombinedSnapshot, r: ty::Region)
-> Vec<ty::Region>;
fn region_vars_confined_to_snapshot
(&self, snapshot: &CombinedSnapshot)
-> Vec<ty::RegionVid>;
}
impl <'tcx, C> HigherRankedRelations<'tcx> for C where
C: Combine<'tcx> {
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
-> cres<'tcx, Binder<T>> where T: Combineable<'tcx> {
loop { }
}
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>)
-> cres<'tcx, Binder<T>> where T: Combineable<'tcx> {
loop { }
}
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>)
-> cres<'tcx, Binder<T>> where T: Combineable<'tcx> {
loop { }
}
}
fn var_ids<'tcx,
T: Combine<'tcx>>(combiner: &T,
map:
&FnvHashMap<ty::BoundRegion,
ty::Region>)
-> Vec<ty::RegionVid> {
loop { }
}
fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region)
-> bool {
loop { }
}
fn fold_regions_in<'tcx, T,
F>(tcx: &ty::ctxt<'tcx>, unbound_value: &T,
mut fldr: F) -> T where
T: Combineable<'tcx>, F: FnMut(ty::Region, ty::DebruijnIndex) ->
ty::Region {
loop { }
}
impl <'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
fn tainted_regions(&self, snapshot: &CombinedSnapshot,
r: ty::Region) -> Vec<ty::Region> {
loop { }
}
fn region_vars_confined_to_snapshot(&self,
snapshot:
&CombinedSnapshot)
-> Vec<ty::RegionVid> {
/*!
* Returns the set of region variables that do not affect any
* types/regions which existed before `snapshot` was
* started. This is used in the sub/lub/glb computations. The
* idea here is that when we are computing lub/glb of two
* regions, we sometimes create intermediate region variables.
* Those region variables may touch some of the skolemized or
* other "forbidden" regions we created to replace bound
* regions, but they don't really represent an "external"
* constraint.
*
* However, sometimes fresh variables are created for other
* purposes too, and those *may* represent an external
* constraint. In particular, when a type variable is
* instantiated, we create region variables for all the
* regions that appear within, and if that type variable
* pre-existed the snapshot, then those region variables
* represent external constraints.
*
* An example appears in the unit test
* `sub_free_bound_false_infer`. In this test, we want to
* know whether
*
* ```rust
* fn(_#0t) <: for<'a> fn(&'a int)
* ```
*
* Note that the subtype has a type variable. Because the type
* variable can't be instantiated with a region that is bound
* in the fn signature, this comparison ought to fail. But if
* we're not careful, it will succeed.
*
* The reason is that when we walk through the subtyping
* algorith, we begin by replacing `'a` with a skolemized
* variable `'1`. We then have `fn(_#0t) <: fn(&'1 int)`. This
* can be made true by unifying `_#0t` with `&'1 int`. In the
* process, we create a fresh variable for the skolemized
* region, `'$2`, and hence we have that `_#0t == &'$2
* int`. However, because `'$2` was created during the sub
* computation, if we're not careful we will erroneously
* assume it is one of the transient region variables
* representing a lub/glb internally. Not good.
*
* To prevent this, we check for type variables which were
* unified during the snapshot, and say that any region
* variable created during the snapshot but which finds its
* way into a type variable is considered to "escape" the
* snapshot.
*/
loop { }
}
}
pub fn skolemize_late_bound_regions<'a, 'tcx,
T>(infcx:
&InferCtxt<'a, 'tcx>,
binder: &ty::Binder<T>,
snapshot:
&CombinedSnapshot)
-> (T, SkolemizationMap) where T: TypeFoldable<'tcx> +
Repr<'tcx> {
/*!
* Replace all regions bound by `binder` with skolemized regions and
* return a map indicating which bound-region was replaced with what
* skolemized region. This is the first step of checking subtyping
* when higher-ranked things are involved. See `doc.rs` for more details.
*/
loop { }
}
pub fn leak_check<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
skol_map: &SkolemizationMap,
snapshot: &CombinedSnapshot)
-> Result<(), (ty::BoundRegion, ty::Region)> {
/*!
* Searches the region constriants created since `snapshot` was started
* and checks to determine whether any of the skolemized regions created
* in `skol_map` would "escape" -- meaning that they are related to
* other regions in some way. If so, the higher-ranked subtyping doesn't
* hold. See `doc.rs` for more details.
*/
loop { }
}
/// This code converts from skolemized regions back to late-bound
/// regions. It works by replacing each region in the taint set of a
/// skolemized region with a bound-region. The bound region will be bound
/// by the outer-most binder in `value`; the caller must ensure that there is
/// such a binder and it is the right place.
///
/// This routine is only intended to be used when the leak-check has
/// passed; currently, it's used in the trait matching code to create
/// a set of nested obligations frmo an impl that matches against
/// something higher-ranked. More details can be found in
/// `middle::traits::doc.rs`.
///
/// As a brief example, consider the obligation `for<'a> Fn(&'a int)
/// -> &'a int`, and the impl:
///
/// impl<A,R> Fn<A,R> for SomethingOrOther
/// where A : Clone
/// { ... }
///
/// Here we will have replaced `'a` with a skolemized region
/// `'0`. This means that our substitution will be `{A=>&'0
/// int, R=>&'0 int}`.
///
/// When we apply the substitution to the bounds, we will wind up with
/// `&'0 int : Clone` as a predicate. As a last step, we then go and
/// replace `'0` with a late-bound region `'a`. The depth is matched
/// to the depth of the predicate, in this case 1, so that the final
/// predicate is `for<'a> &'a int : Clone`.
pub fn plug_leaks<'a, 'tcx,
T>(infcx: &InferCtxt<'a, 'tcx>,
skol_map: SkolemizationMap,
snapshot: &CombinedSnapshot, value: &T) -> T
where T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
}
pub mod lattice {
//! # Lattice Variables
//!
//! This file contains generic code for operating on inference variables
//! that are characterized by an upper- and lower-bound. The logic and
//! reasoning is explained in detail in the large comment in `infer.rs`.
//!
//! The code in here is defined quite generically so that it can be
//! applied both to type variables, which represent types being inferred,
//! and fn variables, which represent function types being inferred.
//! It may eventually be applied to their types as well, who knows.
//! In some cases, the functions are also generic with respect to the
//! operation on the lattice (GLB vs LUB).
//!
//! Although all the functions are generic, we generally write the
//! comments in a way that is specific to type variables and the LUB
//! operation. It's just easier that way.
//!
//! In general all of the functions are defined parametrically
//! over a `LatticeValue`, which is a value defined with respect to
//! a lattice.
use super::*;
use super::combine::*;
use super::glb::Glb;
use super::lub::Lub;
use middle::ty::{TyVar};
use middle::ty::{self, Ty};
use util::ppaux::Repr;
pub trait LatticeDir<'tcx> {
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, ()>;
}
impl <'a, 'tcx> LatticeDir<'tcx> for Lub<'a, 'tcx> {
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, ()> {
loop { }
}
}
impl <'a, 'tcx> LatticeDir<'tcx> for Glb<'a, 'tcx> {
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, ()> {
loop { }
}
}
pub fn super_lattice_tys<'tcx, L: LatticeDir<'tcx> +
Combine<'tcx>>(this: &L, a: Ty<'tcx>,
b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
}
pub mod lub {
use super::combine::*;
use super::equate::Equate;
use super::glb::Glb;
use super::higher_ranked::HigherRankedRelations;
use super::lattice::*;
use super::sub::Sub;
use super::{cres, InferCtxt};
use super::{TypeTrace, Subtype};
use middle::ty::{BuiltinBounds};
use middle::ty::{self, Ty};
use syntax::ast::{Many, Once};
use syntax::ast::{Onceness, Unsafety};
use syntax::ast::{MutMutable, MutImmutable};
use util::ppaux::mt_to_string;
use util::ppaux::Repr;
/// "Least upper bound" (common supertype)
pub struct Lub<'f, 'tcx:'f> {
fields: CombineFields<'f, 'tcx>,
}
#[allow(non_snake_case)]
pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>)
-> Lub<'f, 'tcx> {
loop { }
}
impl <'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> {
loop { }
}
fn tag(&self) -> String { loop { } }
fn a_is_expected(&self) -> bool { loop { } }
fn trace(&self) -> TypeTrace<'tcx> { loop { } }
fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { loop { } }
fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { loop { } }
fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { loop { } }
fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { loop { } }
fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>)
-> cres<'tcx, ty::mt<'tcx>> {
loop { }
}
fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn unsafeties(&self, a: Unsafety, b: Unsafety)
-> cres<'tcx, Unsafety> {
loop { }
}
fn oncenesses(&self, a: Onceness, b: Onceness)
-> cres<'tcx, Onceness> {
loop { }
}
fn builtin_bounds(&self, a: ty::BuiltinBounds,
b: ty::BuiltinBounds)
-> cres<'tcx, ty::BuiltinBounds> {
loop { }
}
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn regions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> cres<'tcx, ty::Binder<T>> where T: Combineable<'tcx> {
loop { }
}
}
}
pub mod region_inference {
//! See doc.rs
pub use self::Constraint::*;
pub use self::Verify::*;
pub use self::UndoLogEntry::*;
pub use self::CombineMapType::*;
pub use self::RegionResolutionError::*;
pub use self::VarValue::*;
use self::Classification::*;
use super::cres;
use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace,
MiscVariable};
use middle::region;
use middle::ty::{self, Ty};
use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree,
ReEarlyBound};
use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized,
BrFresh};
use middle::graph;
use middle::graph::{Direction, NodeIndex};
use util::common::indenter;
use util::nodemap::{FnvHashMap, FnvHashSet};
use util::ppaux::{Repr, UserString};
use std::cell::{Cell, RefCell};
use std::cmp::Ordering::{self, Less, Greater, Equal};
use std::iter::repeat;
use std::u32;
use syntax::ast;
mod doc {
//! Region inference module.
//!
//! # Terminology
//!
//! Note that we use the terms region and lifetime interchangeably,
//! though the term `lifetime` is preferred.
//!
//! # Introduction
//!
//! Region inference uses a somewhat more involved algorithm than type
//! inference. It is not the most efficient thing ever written though it
//! seems to work well enough in practice (famous last words). The reason
//! that we use a different algorithm is because, unlike with types, it is
//! impractical to hand-annotate with regions (in some cases, there aren't
//! even the requisite syntactic forms). So we have to get it right, and
//! it's worth spending more time on a more involved analysis. Moreover,
//! regions are a simpler case than types: they don't have aggregate
//! structure, for example.
//!
//! Unlike normal type inference, which is similar in spirit to H-M and thus
//! works progressively, the region type inference works by accumulating
//! constraints over the course of a function. Finally, at the end of
//! processing a function, we process and solve the constraints all at
//! once.
//!
//! The constraints are always of one of three possible forms:
//!
//! - ConstrainVarSubVar(R_i, R_j) states that region variable R_i
//! must be a subregion of R_j
//! - ConstrainRegSubVar(R, R_i) states that the concrete region R
//! (which must not be a variable) must be a subregion of the variable R_i
//! - ConstrainVarSubReg(R_i, R) is the inverse
//!
//! # Building up the constraints
//!
//! Variables and constraints are created using the following methods:
//!
//! - `new_region_var()` creates a new, unconstrained region variable;
//! - `make_subregion(R_i, R_j)` states that R_i is a subregion of R_j
//! - `lub_regions(R_i, R_j) -> R_k` returns a region R_k which is
//! the smallest region that is greater than both R_i and R_j
//! - `glb_regions(R_i, R_j) -> R_k` returns a region R_k which is
//! the greatest region that is smaller than both R_i and R_j
//!
//! The actual region resolution algorithm is not entirely
//! obvious, though it is also not overly complex.
//!
//! ## Snapshotting
//!
//! It is also permitted to try (and rollback) changes to the graph. This
//! is done by invoking `start_snapshot()`, which returns a value. Then
//! later you can call `rollback_to()` which undoes the work.
//! Alternatively, you can call `commit()` which ends all snapshots.
//! Snapshots can be recursive---so you can start a snapshot when another
//! is in progress, but only the root snapshot can "commit".
//!
//! # Resolving constraints
//!
//! The constraint resolution algorithm is not super complex but also not
//! entirely obvious. Here I describe the problem somewhat abstractly,
//! then describe how the current code works. There may be other, smarter
//! ways of doing this with which I am unfamiliar and can't be bothered to
//! research at the moment. - NDM
//!
//! ## The problem
//!
//! Basically our input is a directed graph where nodes can be divided
//! into two categories: region variables and concrete regions. Each edge
//! `R -> S` in the graph represents a constraint that the region `R` is a
//! subregion of the region `S`.
//!
//! Region variable nodes can have arbitrary degree. There is one region
//! variable node per region variable.
//!
//! Each concrete region node is associated with some, well, concrete
//! region: e.g., a free lifetime, or the region for a particular scope.
//! Note that there may be more than one concrete region node for a
//! particular region value. Moreover, because of how the graph is built,
//! we know that all concrete region nodes have either in-degree 1 or
//! out-degree 1.
//!
//! Before resolution begins, we build up the constraints in a hashmap
//! that maps `Constraint` keys to spans. During resolution, we construct
//! the actual `Graph` structure that we describe here.
//!
//! ## Our current algorithm
//!
//! We divide region variables into two groups: Expanding and Contracting.
//! Expanding region variables are those that have a concrete region
//! predecessor (direct or indirect). Contracting region variables are
//! all others.
//!
//! We first resolve the values of Expanding region variables and then
//! process Contracting ones. We currently use an iterative, fixed-point
//! procedure (but read on, I believe this could be replaced with a linear
//! walk). Basically we iterate over the edges in the graph, ensuring
//! that, if the source of the edge has a value, then this value is a
//! subregion of the target value. If the target does not yet have a
//! value, it takes the value from the source. If the target already had
//! a value, then the resulting value is Least Upper Bound of the old and
//! new values. When we are done, each Expanding node will have the
//! smallest region that it could possibly have and still satisfy the
//! constraints.
//!
//! We next process the Contracting nodes. Here we again iterate over the
//! edges, only this time we move values from target to source (if the
//! source is a Contracting node). For each contracting node, we compute
//! its value as the GLB of all its successors. Basically contracting
//! nodes ensure that there is overlap between their successors; we will
//! ultimately infer the largest overlap possible.
//!
//! # The Region Hierarchy
//!
//! ## Without closures
//!
//! Let's first consider the region hierarchy without thinking about
//! closures, because they add a lot of complications. The region
//! hierarchy *basically* mirrors the lexical structure of the code.
//! There is a region for every piece of 'evaluation' that occurs, meaning
//! every expression, block, and pattern (patterns are considered to
//! "execute" by testing the value they are applied to and creating any
//! relevant bindings). So, for example:
//!
//! fn foo(x: int, y: int) { // -+
//! // +------------+ // |
//! // | +-----+ // |
//! // | +-+ +-+ +-+ // |
//! // | | | | | | | // |
//! // v v v v v v v // |
//! let z = x + y; // |
//! ... // |
//! } // -+
//!
//! fn bar() { ... }
//!
//! In this example, there is a region for the fn body block as a whole,
//! and then a subregion for the declaration of the local variable.
//! Within that, there are sublifetimes for the assignment pattern and
//! also the expression `x + y`. The expression itself has sublifetimes
//! for evaluating `x` and `y`.
//!
//! ## Function calls
//!
//! Function calls are a bit tricky. I will describe how we handle them
//! *now* and then a bit about how we can improve them (Issue #6268).
//!
//! Consider a function call like `func(expr1, expr2)`, where `func`,
//! `arg1`, and `arg2` are all arbitrary expressions. Currently,
//! we construct a region hierarchy like:
//!
//! +----------------+
//! | |
//! +--+ +---+ +---+|
//! v v v v v vv
//! func(expr1, expr2)
//!
//! Here you can see that the call as a whole has a region and the
//! function plus arguments are subregions of that. As a side-effect of
//! this, we get a lot of spurious errors around nested calls, in
//! particular when combined with `&mut` functions. For example, a call
//! like this one
//!
//! self.foo(self.bar())
//!
//! where both `foo` and `bar` are `&mut self` functions will always yield
//! an error.
//!
//! Here is a more involved example (which is safe) so we can see what's
//! going on:
//!
//! struct Foo { f: uint, g: uint }
//! ...
//! fn add(p: &mut uint, v: uint) {
//! *p += v;
//! }
//! ...
//! fn inc(p: &mut uint) -> uint {
//! *p += 1; *p
//! }
//! fn weird() {
//! let mut x: Box<Foo> = box Foo { ... };
//! 'a: add(&mut (*x).f,
//! 'b: inc(&mut (*x).f)) // (..)
//! }
//!
//! The important part is the line marked `(..)` which contains a call to
//! `add()`. The first argument is a mutable borrow of the field `f`. The
//! second argument also borrows the field `f`. Now, in the current borrow
//! checker, the first borrow is given the lifetime of the call to
//! `add()`, `'a`. The second borrow is given the lifetime of `'b` of the
//! call to `inc()`. Because `'b` is considered to be a sublifetime of
//! `'a`, an error is reported since there are two co-existing mutable
//! borrows of the same data.
//!
//! However, if we were to examine the lifetimes a bit more carefully, we
//! can see that this error is unnecessary. Let's examine the lifetimes
//! involved with `'a` in detail. We'll break apart all the steps involved
//! in a call expression:
//!
//! 'a: {
//! 'a_arg1: let a_temp1: ... = add;
//! 'a_arg2: let a_temp2: &'a mut uint = &'a mut (*x).f;
//! 'a_arg3: let a_temp3: uint = {
//! let b_temp1: ... = inc;
//! let b_temp2: &'b = &'b mut (*x).f;
//! 'b_call: b_temp1(b_temp2)
//! };
//! 'a_call: a_temp1(a_temp2, a_temp3) // (**)
//! }
//!
//! Here we see that the lifetime `'a` includes a number of substatements.
//! In particular, there is this lifetime I've called `'a_call` that
//! corresponds to the *actual execution of the function `add()`*, after
//! all arguments have been evaluated. There is a corresponding lifetime
//! `'b_call` for the execution of `inc()`. If we wanted to be precise
//! about it, the lifetime of the two borrows should be `'a_call` and
//! `'b_call` respectively, since the references that were created
//! will not be dereferenced except during the execution itself.
//!
//! However, this model by itself is not sound. The reason is that
//! while the two references that are created will never be used
//! simultaneously, it is still true that the first reference is
//! *created* before the second argument is evaluated, and so even though
//! it will not be *dereferenced* during the evaluation of the second
//! argument, it can still be *invalidated* by that evaluation. Consider
//! this similar but unsound example:
//!
//! struct Foo { f: uint, g: uint }
//! ...
//! fn add(p: &mut uint, v: uint) {
//! *p += v;
//! }
//! ...
//! fn consume(x: Box<Foo>) -> uint {
//! x.f + x.g
//! }
//! fn weird() {
//! let mut x: Box<Foo> = box Foo { ... };
//! 'a: add(&mut (*x).f, consume(x)) // (..)
//! }
//!
//! In this case, the second argument to `add` actually consumes `x`, thus
//! invalidating the first argument.
//!
//! So, for now, we exclude the `call` lifetimes from our model.
//! Eventually I would like to include them, but we will have to make the
//! borrow checker handle this situation correctly. In particular, if
//! there is a reference created whose lifetime does not enclose
//! the borrow expression, we must issue sufficient restrictions to ensure
//! that the pointee remains valid.
//!
//! ## Adding closures
//!
//! The other significant complication to the region hierarchy is
//! closures. I will describe here how closures should work, though some
//! of the work to implement this model is ongoing at the time of this
//! writing.
//!
//! The body of closures are type-checked along with the function that
//! creates them. However, unlike other expressions that appear within the
//! function body, it is not entirely obvious when a closure body executes
//! with respect to the other expressions. This is because the closure
//! body will execute whenever the closure is called; however, we can
//! never know precisely when the closure will be called, especially
//! without some sort of alias analysis.
//!
//! However, we can place some sort of limits on when the closure
//! executes. In particular, the type of every closure `fn:'r K` includes
//! a region bound `'r`. This bound indicates the maximum lifetime of that
//! closure; once we exit that region, the closure cannot be called
//! anymore. Therefore, we say that the lifetime of the closure body is a
//! sublifetime of the closure bound, but the closure body itself is unordered
//! with respect to other parts of the code.
//!
//! For example, consider the following fragment of code:
//!
//! 'a: {
//! let closure: fn:'a() = || 'b: {
//! 'c: ...
//! };
//! 'd: ...
//! }
//!
//! Here we have four lifetimes, `'a`, `'b`, `'c`, and `'d`. The closure
//! `closure` is bounded by the lifetime `'a`. The lifetime `'b` is the
//! lifetime of the closure body, and `'c` is some statement within the
//! closure body. Finally, `'d` is a statement within the outer block that
//! created the closure.
//!
//! We can say that the closure body `'b` is a sublifetime of `'a` due to
//! the closure bound. By the usual lexical scoping conventions, the
//! statement `'c` is clearly a sublifetime of `'b`, and `'d` is a
//! sublifetime of `'d`. However, there is no ordering between `'c` and
//! `'d` per se (this kind of ordering between statements is actually only
//! an issue for dataflow; passes like the borrow checker must assume that
//! closures could execute at any time from the moment they are created
//! until they go out of scope).
//!
//! ### Complications due to closure bound inference
//!
//! There is only one problem with the above model: in general, we do not
//! actually *know* the closure bounds during region inference! In fact,
//! closure bounds are almost always region variables! This is very tricky
//! because the inference system implicitly assumes that we can do things
//! like compute the LUB of two scoped lifetimes without needing to know
//! the values of any variables.
//!
//! Here is an example to illustrate the problem:
//!
//! fn identify<T>(x: T) -> T { x }
//!
//! fn foo() { // 'foo is the function body
//! 'a: {
//! let closure = identity(|| 'b: {
//! 'c: ...
//! });
//! 'd: closure();
//! }
//! 'e: ...;
//! }
//!
//! In this example, the closure bound is not explicit. At compile time,
//! we will create a region variable (let's call it `V0`) to represent the
//! closure bound.
//!
//! The primary difficulty arises during the constraint propagation phase.
//! Imagine there is some variable with incoming edges from `'c` and `'d`.
//! This means that the value of the variable must be `LUB('c,
//! 'd)`. However, without knowing what the closure bound `V0` is, we
//! can't compute the LUB of `'c` and `'d`! Any we don't know the closure
//! bound until inference is done.
//!
//! The solution is to rely on the fixed point nature of inference.
//! Basically, when we must compute `LUB('c, 'd)`, we just use the current
//! value for `V0` as the closure's bound. If `V0`'s binding should
//! change, then we will do another round of inference, and the result of
//! `LUB('c, 'd)` will change.
//!
//! One minor implication of this is that the graph does not in fact track
//! the full set of dependencies between edges. We cannot easily know
//! whether the result of a LUB computation will change, since there may
//! be indirect dependencies on other variables that are not reflected on
//! the graph. Therefore, we must *always* iterate over all edges when
//! doing the fixed point calculation, not just those adjacent to nodes
//! whose values have changed.
//!
//! Were it not for this requirement, we could in fact avoid fixed-point
//! iteration altogether. In that universe, we could instead first
//! identify and remove strongly connected components (SCC) in the graph.
//! Note that such components must consist solely of region variables; all
//! of these variables can effectively be unified into a single variable.
//! Once SCCs are removed, we are left with a DAG. At this point, we
//! could walk the DAG in topological order once to compute the expanding
//! nodes, and again in reverse topological order to compute the
//! contracting nodes. However, as I said, this does not work given the
//! current treatment of closure bounds, but perhaps in the future we can
//! address this problem somehow and make region inference somewhat more
//! efficient. Note that this is solely a matter of performance, not
//! expressiveness.
//!
//! ### Skolemization
//!
//! For a discussion on skolemization and higher-ranked subtyping, please
//! see the module `middle::infer::higher_ranked::doc`.
}
mod graphviz {
//! This module provides linkage between libgraphviz traits and
//! `rustc::middle::typeck::infer::region_inference`, generating a
//! rendering of the graph represented by the list of `Constraint`
//! instances (which make up the edges of the graph), as well as the
//! origin for each constraint (which are attached to the labels on
//! each edge).
/// For clarity, rename the graphviz crate locally to dot.
use graphviz as dot;
use middle::ty;
use super::Constraint;
use middle::infer::SubregionOrigin;
use middle::infer::region_inference::RegionVarBindings;
use util::nodemap::{FnvHashMap, FnvHashSet};
use util::ppaux::Repr;
use std::collections::hash_map::Entry::Vacant;
use std::io::{self, File};
use std::os;
use std::sync::atomic::{AtomicBool, Ordering,
ATOMIC_BOOL_INIT};
use syntax::ast;
fn print_help_message() { loop { } }
pub fn maybe_print_constraints_for<'a,
'tcx>(region_vars:
&RegionVarBindings<'a,
'tcx>,
subject_node:
ast::NodeId) {
loop { }
}
struct ConstraintGraph<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
graph_name: String,
map: &'a FnvHashMap<Constraint, SubregionOrigin<'tcx>>,
node_ids: FnvHashMap<Node, uint>,
}
#[derive(Clone, Hash, PartialEq, Eq, Show)]
enum Node { RegionVid(ty::RegionVid), Region(ty::Region), }
type Edge = Constraint;
impl <'a, 'tcx> ConstraintGraph<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>, name: String,
map: &'a ConstraintMap<'tcx>)
-> ConstraintGraph<'a, 'tcx> {
loop { }
}
}
impl <'a, 'tcx> dot::Labeller<'a, Node, Edge> for
ConstraintGraph<'a, 'tcx> {
fn graph_id(&self) -> dot::Id { loop { } }
fn node_id(&self, n: &Node) -> dot::Id { loop { } }
fn node_label(&self, n: &Node) -> dot::LabelText {
loop { }
}
fn edge_label(&self, e: &Edge) -> dot::LabelText {
loop { }
}
}
fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
loop { }
}
impl <'a, 'tcx> dot::GraphWalk<'a, Node, Edge> for
ConstraintGraph<'a, 'tcx> {
fn nodes(&self) -> dot::Nodes<Node> { loop { } }
fn edges(&self) -> dot::Edges<Edge> { loop { } }
fn source(&self, edge: &Edge) -> Node { loop { } }
fn target(&self, edge: &Edge) -> Node { loop { } }
}
pub type ConstraintMap<'tcx> =
FnvHashMap<Constraint, SubregionOrigin<'tcx>>;
fn dump_region_constraints_to<'a,
'tcx:'a>(tcx:
&'a ty::ctxt<'tcx>,
map:
&ConstraintMap<'tcx>,
path: &str)
-> io::IoResult<()> {
loop { }
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum Constraint {
ConstrainVarSubVar(RegionVid, RegionVid),
ConstrainRegSubVar(Region, RegionVid),
ConstrainVarSubReg(RegionVid, Region),
}
pub enum Verify<'tcx> {
VerifyRegSubReg(SubregionOrigin<'tcx>, Region, Region),
VerifyGenericBound(GenericKind<'tcx>,
SubregionOrigin<'tcx>,
Region,
Vec<Region>),
}
#[derive(Clone, Show, PartialEq, Eq)]
pub enum GenericKind<'tcx> {
Param(ty::ParamTy),
Projection(ty::ProjectionTy<'tcx>),
}
#[derive(Copy, PartialEq, Eq, Hash)]
pub struct TwoRegions {
a: Region,
b: Region,
}
#[derive(Copy, PartialEq)]
pub enum UndoLogEntry {
OpenSnapshot,
CommitedSnapshot,
AddVar(RegionVid),
AddConstraint(Constraint),
AddVerify(uint),
AddGiven(ty::FreeRegion, ty::RegionVid),
AddCombination(CombineMapType, TwoRegions),
}
#[derive(Copy, PartialEq)]
pub enum CombineMapType { Lub, Glb, }
#[derive(Clone, Show)]
pub enum RegionResolutionError<'tcx> {
/// `ConcreteFailure(o, a, b)`:
///
/// `o` requires that `a <= b`, but this does not hold
ConcreteFailure(SubregionOrigin<'tcx>, Region, Region),
/// `GenericBoundFailure(p, s, a, bs)
///
/// The parameter/associated-type `p` must be known to outlive the lifetime
/// `a`, but it is only known to outlive `bs` (and none of the
/// regions in `bs` outlive `a`).
GenericBoundFailure(SubregionOrigin<'tcx>,
GenericKind<'tcx>,
Region,
Vec<Region>),
/// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
///
/// Could not infer a value for `v` because `sub_r <= v` (due to
/// `sub_origin`) but `v <= sup_r` (due to `sup_origin`) and
/// `sub_r <= sup_r` does not hold.
SubSupConflict(RegionVariableOrigin<'tcx>,
SubregionOrigin<'tcx>,
Region,
SubregionOrigin<'tcx>,
Region),
/// `SupSupConflict(v, origin1, r1, origin2, r2)`:
///
/// Could not infer a value for `v` because `v <= r1` (due to
/// `origin1`) and `v <= r2` (due to `origin2`) and
/// `r1` and `r2` have no intersection.
SupSupConflict(RegionVariableOrigin<'tcx>,
SubregionOrigin<'tcx>,
Region,
SubregionOrigin<'tcx>,
Region),
/// For subsets of `ConcreteFailure` and `SubSupConflict`, we can derive
/// more specific errors message by suggesting to the user where they
/// should put a lifetime. In those cases we process and put those errors
/// into `ProcessedErrors` before we do any reporting.
ProcessedErrors(Vec<RegionVariableOrigin<'tcx>>,
Vec<(TypeTrace<'tcx>, ty::type_err<'tcx>)>,
Vec<SameRegions>),
}
/// SameRegions is used to group regions that we think are the same and would
/// like to indicate so to the user.
/// For example, the following function
/// ```
/// struct Foo { bar: int }
/// fn foo2<'a, 'b>(x: &'a Foo) -> &'b int {
/// &x.bar
/// }
/// ```
/// would report an error because we expect 'a and 'b to match, and so we group
/// 'a and 'b together inside a SameRegions struct
#[derive(Clone, Show)]
pub struct SameRegions {
pub scope_id: ast::NodeId,
pub regions: Vec<BoundRegion>,
}
impl SameRegions {
pub fn contains(&self, other: &BoundRegion) -> bool {
loop { }
}
pub fn push(&mut self, other: BoundRegion) { loop { } }
}
pub type CombineMap = FnvHashMap<TwoRegions, RegionVid>;
pub struct RegionVarBindings<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
var_origins: RefCell<Vec<RegionVariableOrigin<'tcx>>>,
constraints: RefCell<FnvHashMap<Constraint,
SubregionOrigin<'tcx>>>,
verifys: RefCell<Vec<Verify<'tcx>>>,
givens: RefCell<FnvHashSet<(ty::FreeRegion, ty::RegionVid)>>,
lubs: RefCell<CombineMap>,
glbs: RefCell<CombineMap>,
skolemization_count: Cell<u32>,
bound_count: Cell<u32>,
undo_log: RefCell<Vec<UndoLogEntry>>,
values: RefCell<Option<Vec<VarValue>>>,
}
#[derive(Show)]
#[allow(missing_copy_implementations)]
pub struct RegionSnapshot {
length: uint,
skolemization_count: u32,
}
impl <'a, 'tcx> RegionVarBindings<'a, 'tcx> {
pub fn new(tcx: &'a ty::ctxt<'tcx>)
-> RegionVarBindings<'a, 'tcx> {
loop { }
}
fn in_snapshot(&self) -> bool { loop { } }
pub fn start_snapshot(&self) -> RegionSnapshot { loop { } }
pub fn commit(&self, snapshot: RegionSnapshot) { loop { } }
pub fn rollback_to(&self, snapshot: RegionSnapshot) {
loop { }
}
pub fn num_vars(&self) -> u32 { loop { } }
pub fn new_region_var(&self,
origin: RegionVariableOrigin<'tcx>)
-> RegionVid {
loop { }
}
/// Creates a new skolemized region. Skolemized regions are fresh
/// regions used when performing higher-ranked computations. They
/// must be used in a very particular way and are never supposed
/// to "escape" out into error messages or the code at large.
///
/// The idea is to always create a snapshot. Skolemized regions
/// can be created in the context of this snapshot, but once the
/// snapshot is committed or rolled back, their numbers will be
/// recycled, so you must be finished with them. See the extensive
/// comments in `higher_ranked.rs` to see how it works (in
/// particular, the subtyping comparison).
///
/// The `snapshot` argument to this function is not really used;
/// it's just there to make it explicit which snapshot bounds the
/// skolemized region that results.
pub fn new_skolemized(&self, br: ty::BoundRegion,
snapshot: &RegionSnapshot) -> Region {
loop { }
}
pub fn new_bound(&self, debruijn: ty::DebruijnIndex)
-> Region {
loop { }
}
fn values_are_none(&self) -> bool { loop { } }
fn add_constraint(&self, constraint: Constraint,
origin: SubregionOrigin<'tcx>) {
loop { }
}
fn add_verify(&self, verify: Verify<'tcx>) { loop { } }
pub fn add_given(&self, sub: ty::FreeRegion,
sup: ty::RegionVid) {
loop { }
}
pub fn make_eqregion(&self, origin: SubregionOrigin<'tcx>,
sub: Region, sup: Region) {
loop { }
}
pub fn make_subregion(&self, origin: SubregionOrigin<'tcx>,
sub: Region, sup: Region) {
loop { }
}
/// See `Verify::VerifyGenericBound`
pub fn verify_generic_bound(&self,
origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
sub: Region, sups: Vec<Region>) {
loop { }
}
pub fn lub_regions(&self, origin: SubregionOrigin<'tcx>,
a: Region, b: Region) -> Region {
loop { }
}
pub fn glb_regions(&self, origin: SubregionOrigin<'tcx>,
a: Region, b: Region) -> Region {
loop { }
}
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region {
loop { }
}
fn combine_map(&self, t: CombineMapType)
-> &RefCell<CombineMap> {
loop { }
}
pub fn combine_vars<F>(&self, t: CombineMapType, a: Region,
b: Region,
origin: SubregionOrigin<'tcx>,
mut relate: F) -> Region where
F: FnMut(&RegionVarBindings<'a, 'tcx>, Region, Region) {
loop { }
}
pub fn vars_created_since_snapshot(&self,
mark: &RegionSnapshot)
-> Vec<RegionVid> {
loop { }
}
/// Computes all regions that have been related to `r0` in any way since the mark `mark` was
/// made---`r0` itself will be the first entry. This is used when checking whether skolemized
/// regions are being improperly related to other regions.
pub fn tainted(&self, mark: &RegionSnapshot, r0: Region)
-> Vec<Region> {
loop { }
}
/// This function performs the actual region resolution. It must be
/// called after all constraints have been added. It performs a
/// fixed-point iteration to find region values which satisfy all
/// constraints, assuming such values can be found; if they cannot,
/// errors are reported.
pub fn resolve_regions(&self, subject_node: ast::NodeId)
-> Vec<RegionResolutionError<'tcx>> {
loop { }
}
fn is_subregion_of(&self, sub: Region, sup: Region) -> bool {
loop { }
}
fn lub_concrete_regions(&self, a: Region, b: Region)
-> Region {
loop { }
}
/// Computes a region that encloses both free region arguments. Guarantee that if the same two
/// regions are given as argument, in any order, a consistent result is returned.
fn lub_free_regions(&self, a: &FreeRegion, b: &FreeRegion)
-> ty::Region {
loop { }
}
fn glb_concrete_regions(&self, a: Region, b: Region)
-> cres<'tcx, Region> {
loop { }
}
/// Computes a region that is enclosed by both free region arguments, if any. Guarantees that
/// if the same two regions are given as argument, in any order, a consistent result is
/// returned.
fn glb_free_regions(&self, a: &FreeRegion, b: &FreeRegion)
-> cres<'tcx, ty::Region> {
loop { }
}
fn intersect_scopes(&self, region_a: ty::Region,
region_b: ty::Region,
scope_a: region::CodeExtent,
scope_b: region::CodeExtent)
-> cres<'tcx, Region> {
loop { }
}
}
#[derive(Copy, PartialEq, Show)]
enum Classification { Expanding, Contracting, }
#[derive(Copy)]
pub enum VarValue { NoValue, Value(Region), ErrorValue, }
struct VarData {
classification: Classification,
value: VarValue,
}
struct RegionAndOrigin<'tcx> {
region: Region,
origin: SubregionOrigin<'tcx>,
}
type RegionGraph = graph::Graph<(), Constraint>;
impl <'a, 'tcx> RegionVarBindings<'a, 'tcx> {
fn infer_variable_values(&self,
errors:
&mut Vec<RegionResolutionError<'tcx>>,
subject: ast::NodeId)
-> Vec<VarValue> {
loop { }
}
fn construct_var_data(&self) -> Vec<VarData> { loop { } }
fn dump_constraints(&self) { loop { } }
fn expansion(&self, var_data: &mut [VarData]) { loop { } }
fn expand_node(&self, a_region: Region, b_vid: RegionVid,
b_data: &mut VarData) -> bool {
loop { }
}
fn contraction(&self, var_data: &mut [VarData]) { loop { } }
fn contract_node(&self, a_vid: RegionVid,
a_data: &mut VarData, b_region: Region)
-> bool {
loop { }
}
fn collect_concrete_region_errors(&self,
values: &Vec<VarValue>,
errors:
&mut Vec<RegionResolutionError<'tcx>>) {
loop { }
}
fn extract_values_and_collect_conflicts(&self,
var_data: &[VarData],
errors:
&mut Vec<RegionResolutionError<'tcx>>)
-> Vec<VarValue> {
loop { }
}
fn construct_graph(&self) -> RegionGraph { loop { } }
fn collect_error_for_expanding_node(&self,
graph: &RegionGraph,
var_data: &[VarData],
dup_vec: &mut [u32],
node_idx: RegionVid,
errors:
&mut Vec<RegionResolutionError<'tcx>>) {
loop { }
}
fn collect_error_for_contracting_node(&self,
graph: &RegionGraph,
var_data: &[VarData],
dup_vec: &mut [u32],
node_idx: RegionVid,
errors:
&mut Vec<RegionResolutionError<'tcx>>) {
loop { }
}
fn collect_concrete_regions(&self, graph: &RegionGraph,
var_data: &[VarData],
orig_node_idx: RegionVid,
dir: Direction,
dup_vec: &mut [u32])
-> (Vec<RegionAndOrigin<'tcx>>, bool) {
loop { }
}
fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
where F: FnMut(&Constraint) -> bool {
loop { }
}
}
impl <'tcx> Repr<'tcx> for Constraint {
fn repr(&self, tcx: &ty::ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for Verify<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
fn normalize(values: &Vec<VarValue>, r: ty::Region)
-> ty::Region {
loop { }
}
fn lookup(values: &Vec<VarValue>, rid: ty::RegionVid)
-> ty::Region {
loop { }
}
impl <'tcx> Repr<'tcx> for VarValue {
fn repr(&self, tcx: &ty::ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for RegionAndOrigin<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for GenericKind<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for GenericKind<'tcx> {
fn user_string(&self, tcx: &ty::ctxt<'tcx>) -> String {
loop { }
}
}
impl <'tcx> GenericKind<'tcx> {
pub fn to_ty(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
loop { }
}
}
}
pub mod resolve {
use super::{InferCtxt, fixup_err, fres, unresolved_ty,
unresolved_int_ty, unresolved_float_ty};
use middle::ty::{self, Ty};
use middle::ty_fold::{self, TypeFoldable};
use util::ppaux::Repr;
/// The opportunistic type resolver can be used at any time. It simply replaces
/// type variables that have been unified with the things they have
/// been unified with (similar to `shallow_resolve`, but deep). This is
/// useful for printing messages etc but also required at various
/// points for correctness.
pub struct OpportunisticTypeResolver<'a, 'tcx:'a> {
infcx: &'a InferCtxt<'a, 'tcx>,
}
impl <'a, 'tcx> OpportunisticTypeResolver<'a, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>)
-> OpportunisticTypeResolver<'a, 'tcx> {
loop { }
}
}
impl <'a, 'tcx> ty_fold::TypeFolder<'tcx> for
OpportunisticTypeResolver<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { loop { } }
}
/// Full type resolution replaces all type and region variables with
/// their concrete results. If any variable cannot be replaced (never unified, etc)
/// then an `Err` result is returned.
pub fn fully_resolve<'a, 'tcx,
T>(infcx: &InferCtxt<'a, 'tcx>, value: &T)
-> fres<T> where T: TypeFoldable<'tcx> {
loop { }
}
struct FullTypeResolver<'a, 'tcx:'a> {
infcx: &'a InferCtxt<'a, 'tcx>,
err: Option<fixup_err>,
}
impl <'a, 'tcx> ty_fold::TypeFolder<'tcx> for
FullTypeResolver<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { loop { } }
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
}
}
mod freshen {
//! Freshening is the process of replacing unknown variables with fresh types. The idea is that
//! the type, after freshening, contains no inference variables but instead contains either a
//! value for each variable or fresh "arbitrary" types wherever a variable would have been.
//!
//! Freshening is used primarily to get a good type for inserting into a cache. The result
//! summarizes what the type inferencer knows "so far". The primary place it is used right now is
//! in the trait matching algorithm, which needs to be able to cache whether an `impl` self type
//! matches some other type X -- *without* affecting `X`. That means if that if the type `X` is in
//! fact an unbound type variable, we want the match to be regarded as ambiguous, because depending
//! on what type that type variable is ultimately assigned, the match may or may not succeed.
//!
//! Note that you should be careful not to allow the output of freshening to leak to the user in
//! error messages or in any other form. Freshening is only really useful as an internal detail.
//!
//! __An important detail concerning regions.__ The freshener also replaces *all* regions with
//! 'static. The reason behind this is that, in general, we do not take region relationships into
//! account when making type-overloaded decisions. This is important because of the design of the
//! region inferencer, which is not based on unification but rather on accumulating and then
//! solving a set of constraints. In contrast, the type inferencer assigns a value to each type
//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
//! inferencer knows "so far".
use middle::ty::{self, Ty};
use middle::ty_fold;
use middle::ty_fold::TypeFoldable;
use middle::ty_fold::TypeFolder;
use std::collections::hash_map::{self, Entry};
use super::InferCtxt;
use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
pub struct TypeFreshener<'a, 'tcx:'a> {
infcx: &'a InferCtxt<'a, 'tcx>,
freshen_count: u32,
freshen_map: hash_map::HashMap<ty::InferTy, Ty<'tcx>>,
}
impl <'a, 'tcx> TypeFreshener<'a, 'tcx> {
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>)
-> TypeFreshener<'a, 'tcx> {
loop { }
}
fn freshen<F>(&mut self, opt_ty: Option<Ty<'tcx>>,
key: ty::InferTy, freshener: F) -> Ty<'tcx>
where F: FnOnce(u32) -> ty::InferTy {
loop { }
}
}
impl <'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
fn tcx<'b>(&'b self) -> &'b ty::ctxt<'tcx> { loop { } }
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { loop { } }
}
}
pub mod sub {
use super::combine::*;
use super::{cres, CresCompare};
use super::equate::Equate;
use super::glb::Glb;
use super::higher_ranked::HigherRankedRelations;
use super::InferCtxt;
use super::lub::Lub;
use super::{TypeTrace, Subtype};
use super::type_variable::{SubtypeOf, SupertypeOf};
use middle::ty::{BuiltinBounds};
use middle::ty::{self, Ty};
use middle::ty::TyVar;
use util::ppaux::{Repr};
use syntax::ast::{Onceness, MutImmutable, MutMutable, Unsafety};
/// "Greatest lower bound" (common subtype)
pub struct Sub<'f, 'tcx:'f> {
fields: CombineFields<'f, 'tcx>,
}
#[allow(non_snake_case)]
pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>)
-> Sub<'f, 'tcx> {
loop { }
}
impl <'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> {
loop { }
}
fn tag(&self) -> String { loop { } }
fn a_is_expected(&self) -> bool { loop { } }
fn trace(&self) -> TypeTrace<'tcx> { loop { } }
fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { loop { } }
fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { loop { } }
fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { loop { } }
fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { loop { } }
fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn regions(&self, a: ty::Region, b: ty::Region)
-> cres<'tcx, ty::Region> {
loop { }
}
fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>)
-> cres<'tcx, ty::mt<'tcx>> {
loop { }
}
fn unsafeties(&self, a: Unsafety, b: Unsafety)
-> cres<'tcx, Unsafety> {
loop { }
}
fn oncenesses(&self, a: Onceness, b: Onceness)
-> cres<'tcx, Onceness> {
loop { }
}
fn builtin_bounds(&self, a: BuiltinBounds, b: BuiltinBounds)
-> cres<'tcx, BuiltinBounds> {
loop { }
}
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>> {
loop { }
}
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>)
-> cres<'tcx, ty::Binder<T>> where T: Combineable<'tcx> {
loop { }
}
}
}
pub mod type_variable {
pub use self::RelationDir::*;
use self::TypeVariableValue::*;
use self::UndoEntry::*;
use middle::ty::{self, Ty};
use std::cmp::min;
use std::mem;
use std::u32;
use util::snapshot_vec as sv;
pub struct TypeVariableTable<'tcx> {
values: sv::SnapshotVec<TypeVariableData<'tcx>, UndoEntry,
Delegate>,
}
struct TypeVariableData<'tcx> {
value: TypeVariableValue<'tcx>,
diverging: bool,
}
enum TypeVariableValue<'tcx> {
Known(Ty<'tcx>),
Bounded(Vec<Relation>),
}
pub struct Snapshot {
snapshot: sv::Snapshot,
}
enum UndoEntry {
SpecifyVar(ty::TyVid, Vec<Relation>),
Relate(ty::TyVid, ty::TyVid),
}
struct Delegate;
type Relation = (RelationDir, ty::TyVid);
#[derive(Copy, PartialEq, Show)]
pub enum RelationDir { SubtypeOf, SupertypeOf, EqTo, }
impl RelationDir {
fn opposite(self) -> RelationDir { loop { } }
}
impl <'tcx> TypeVariableTable<'tcx> {
pub fn new() -> TypeVariableTable<'tcx> { loop { } }
fn relations<'a>(&'a mut self, a: ty::TyVid)
-> &'a mut Vec<Relation> {
loop { }
}
pub fn var_diverges<'a>(&'a self, vid: ty::TyVid) -> bool {
loop { }
}
/// Records that `a <: b`, `a :> b`, or `a == b`, depending on `dir`.
///
/// Precondition: neither `a` nor `b` are known.
pub fn relate_vars(&mut self, a: ty::TyVid, dir: RelationDir,
b: ty::TyVid) {
loop { }
}
/// Instantiates `vid` with the type `ty` and then pushes an entry onto `stack` for each of the
/// relations of `vid` to other variables. The relations will have the form `(ty, dir, vid1)`
/// where `vid1` is some other variable id.
pub fn instantiate_and_push(&mut self, vid: ty::TyVid,
ty: Ty<'tcx>,
stack:
&mut Vec<(Ty<'tcx>,
RelationDir,
ty::TyVid)>) {
loop { }
}
pub fn new_var(&mut self, diverging: bool) -> ty::TyVid {
loop { }
}
pub fn probe(&self, vid: ty::TyVid) -> Option<Ty<'tcx>> {
loop { }
}
pub fn replace_if_possible(&self, t: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn snapshot(&mut self) -> Snapshot { loop { } }
pub fn rollback_to(&mut self, s: Snapshot) { loop { } }
pub fn commit(&mut self, s: Snapshot) { loop { } }
pub fn types_escaping_snapshot(&self, s: &Snapshot)
-> Vec<Ty<'tcx>> {
/*!
* Find the set of type variables that existed *before* `s`
* but which have only been unified since `s` started, and
* return the types with which they were unified. So if we had
* a type variable `V0`, then we started the snapshot, then we
* created a type variable `V1`, unifed `V0` with `T0`, and
* unified `V1` with `T1`, this function would return `{T0}`.
*/
loop { }
}
}
impl <'tcx>
sv::SnapshotVecDelegate<TypeVariableData<'tcx>, UndoEntry> for
Delegate {
fn reverse(&mut self, values: &mut Vec<TypeVariableData>,
action: UndoEntry) {
loop { }
}
}
fn relations<'a>(v: &'a mut TypeVariableData)
-> &'a mut Vec<Relation> {
loop { }
}
}
pub mod unify {
pub use self::VarValue::*;
use std::marker;
use middle::ty::{expected_found, IntVarValue};
use middle::ty::{self, Ty};
use middle::infer::{uok, ures};
use middle::infer::InferCtxt;
use std::cell::RefCell;
use std::fmt::Show;
use syntax::ast;
use util::ppaux::Repr;
use util::snapshot_vec as sv;
/// This trait is implemented by any type that can serve as a type
/// variable. We call such variables *unification keys*. For example,
/// this trait is implemented by `IntVid`, which represents integral
/// variables.
///
/// Each key type has an associated value type `V`. For example, for
/// `IntVid`, this is `Option<IntVarValue>`, representing some
/// (possibly not yet known) sort of integer.
///
/// Implementations of this trait are at the end of this file.
pub trait UnifyKey<'tcx, V>: Clone + Show + PartialEq +
Repr<'tcx> {
fn index(&self) -> uint;
fn from_index(u: uint) -> Self;
fn unification_table<'v>(infcx: &'v InferCtxt)
-> &'v RefCell<UnificationTable<Self, V>>;
fn tag(k: Option<Self>) -> &'static str;
}
/// Trait for valid types that a type variable can be set to. Note that
/// this is typically not the end type that the value will take on, but
/// rather an `Option` wrapper (where `None` represents a variable
/// whose value is not yet set).
///
/// Implementations of this trait are at the end of this file.
pub trait UnifyValue<'tcx>: Clone + Repr<'tcx> + PartialEq { }
/// Value of a unification key. We implement Tarjan's union-find
/// algorithm: when two keys are unified, one of them is converted
/// into a "redirect" pointing at the other. These redirects form a
/// DAG: the roots of the DAG (nodes that are not redirected) are each
/// associated with a value of type `V` and a rank. The rank is used
/// to keep the DAG relatively balanced, which helps keep the running
/// time of the algorithm under control. For more information, see
/// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
#[derive(PartialEq, Clone)]
pub enum VarValue<K, V> { Redirect(K), Root(V, uint), }
/// Table of unification keys and their values.
pub struct UnificationTable<K, V> {
/// Indicates the current value of each key.
values: sv::SnapshotVec<VarValue<K, V>, (), Delegate>,
}
/// At any time, users may snapshot a unification table. The changes
/// made during the snapshot may either be *committed* or *rolled back*.
pub struct Snapshot<K> {
marker: marker::CovariantType<K>,
snapshot: sv::Snapshot,
}
/// Internal type used to represent the result of a `get()` operation.
/// Conveys the current root and value of the key.
pub struct Node<K, V> {
pub key: K,
pub value: V,
pub rank: uint,
}
#[derive(Copy)]
pub struct Delegate;
impl <'tcx, V: PartialEq + Clone + Repr<'tcx>, K: UnifyKey<'tcx,
V>> UnificationTable<K, V> {
pub fn new() -> UnificationTable<K, V> { loop { } }
/// Starts a new snapshot. Each snapshot must be either
/// rolled back or committed in a "LIFO" (stack) order.
pub fn snapshot(&mut self) -> Snapshot<K> { loop { } }
/// Reverses all changes since the last snapshot. Also
/// removes any keys that have been created since then.
pub fn rollback_to(&mut self, snapshot: Snapshot<K>) {
loop { }
}
/// Commits all changes since the last snapshot. Of course, they
/// can still be undone if there is a snapshot further out.
pub fn commit(&mut self, snapshot: Snapshot<K>) { loop { } }
pub fn new_key(&mut self, value: V) -> K { loop { } }
/// Find the root node for `vid`. This uses the standard union-find algorithm with path
/// compression: http://en.wikipedia.org/wiki/Disjoint-set_data_structure
pub fn get(&mut self, tcx: &ty::ctxt, vid: K) -> Node<K, V> {
loop { }
}
fn is_root(&self, key: &K) -> bool { loop { } }
/// Sets the value for `vid` to `new_value`. `vid` MUST be a root node! Also, we must be in the
/// middle of a snapshot.
pub fn set(&mut self, tcx: &ty::ctxt<'tcx>, key: K,
new_value: VarValue<K, V>) {
loop { }
}
/// Either redirects node_a to node_b or vice versa, depending on the relative rank. Returns
/// the new root and rank. You should then update the value of the new root to something
/// suitable.
pub fn unify(&mut self, tcx: &ty::ctxt<'tcx>,
node_a: &Node<K, V>, node_b: &Node<K, V>)
-> (K, uint) {
loop { }
}
}
impl <K, V> sv::SnapshotVecDelegate<VarValue<K, V>, ()> for
Delegate {
fn reverse(&mut self, _: &mut Vec<VarValue<K, V>>, _: ()) {
loop { }
}
}
/// Indicates a type that does not have any kind of subtyping
/// relationship.
pub trait SimplyUnifiable<'tcx>: Clone + PartialEq + Repr<'tcx> {
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
fn to_type_err(expected_found<Self>) -> ty::type_err<'tcx>;
}
pub fn err<'tcx,
V: SimplyUnifiable<'tcx>>(a_is_expected: bool, a_t: V,
b_t: V) -> ures<'tcx> {
loop { }
}
pub trait InferCtxtMethodsForSimplyUnifiableTypes<'tcx,
V: SimplyUnifiable<'tcx>,
K: UnifyKey<'tcx,
Option<V>>> {
fn simple_vars(&self, a_is_expected: bool, a_id: K, b_id: K)
-> ures<'tcx>;
fn simple_var_t(&self, a_is_expected: bool, a_id: K, b: V)
-> ures<'tcx>;
fn probe_var(&self, a_id: K) -> Option<Ty<'tcx>>;
}
impl <'a, 'tcx, V: SimplyUnifiable<'tcx>, K: UnifyKey<'tcx,
Option<V>>> InferCtxtMethodsForSimplyUnifiableTypes<'tcx,
V, K> for InferCtxt<'a, 'tcx> {
/// Unifies two simple keys. Because simple keys do not have any subtyping relationships, if
/// both keys have already been associated with a value, then those two values must be the
/// same.
fn simple_vars(&self, a_is_expected: bool, a_id: K, b_id: K)
-> ures<'tcx> {
loop { }
}
/// Sets the value of the key `a_id` to `b`. Because simple keys do not have any subtyping
/// relationships, if `a_id` already has a value, it must be the same as `b`.
fn simple_var_t(&self, a_is_expected: bool, a_id: K, b: V)
-> ures<'tcx> {
loop { }
}
fn probe_var(&self, a_id: K) -> Option<Ty<'tcx>> { loop { } }
}
impl <'tcx> UnifyKey<'tcx, Option<IntVarValue>> for ty::IntVid {
fn index(&self) -> uint { loop { } }
fn from_index(i: uint) -> ty::IntVid { loop { } }
fn unification_table<'v>(infcx: &'v InferCtxt)
->
&'v RefCell<UnificationTable<ty::IntVid,
Option<IntVarValue>>> {
loop { }
}
fn tag(_: Option<ty::IntVid>) -> &'static str { loop { } }
}
impl <'tcx> SimplyUnifiable<'tcx> for IntVarValue {
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
loop { }
}
fn to_type_err(err: expected_found<IntVarValue>)
-> ty::type_err<'tcx> {
loop { }
}
}
impl <'tcx> UnifyValue<'tcx> for Option<IntVarValue> { }
impl <'tcx> UnifyKey<'tcx, Option<ast::FloatTy>> for ty::FloatVid
{
fn index(&self) -> uint { loop { } }
fn from_index(i: uint) -> ty::FloatVid { loop { } }
fn unification_table<'v>(infcx: &'v InferCtxt)
->
&'v RefCell<UnificationTable<ty::FloatVid,
Option<ast::FloatTy>>> {
loop { }
}
fn tag(_: Option<ty::FloatVid>) -> &'static str { loop { } }
}
impl <'tcx> UnifyValue<'tcx> for Option<ast::FloatTy> { }
impl <'tcx> SimplyUnifiable<'tcx> for ast::FloatTy {
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
loop { }
}
fn to_type_err(err: expected_found<ast::FloatTy>)
-> ty::type_err<'tcx> {
loop { }
}
}
impl <'tcx, K: Repr<'tcx>, V: Repr<'tcx>> Repr<'tcx> for
VarValue<K, V> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
}
pub type Bound<T> = Option<T>;
pub type cres<'tcx, T> = Result<T, ty::type_err<'tcx>>;
pub type ures<'tcx> = cres<'tcx, ()>;
pub type fres<T> = Result<T, fixup_err>;
pub type CoerceResult<'tcx> =
cres<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
pub struct InferCtxt<'a, 'tcx:'a> {
pub tcx: &'a ty::ctxt<'tcx>,
type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
int_unification_table: RefCell<UnificationTable<ty::IntVid,
Option<IntVarValue>>>,
float_unification_table: RefCell<UnificationTable<ty::FloatVid,
Option<ast::FloatTy>>>,
region_vars: RegionVarBindings<'a, 'tcx>,
}
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
/// region that each late-bound region was replaced with.
pub type SkolemizationMap = FnvHashMap<ty::BoundRegion, ty::Region>;
/// Why did we require that the two types be related?
///
/// See `error_reporting.rs` for more details
#[derive(Clone, Copy, Show)]
pub enum TypeOrigin {
Misc(Span),
MethodCompatCheck(Span),
ExprAssignable(Span),
RelateTraitRefs(Span),
RelateSelfType(Span),
RelateOutputImplTypes(Span),
MatchExpressionArm(Span, Span),
IfExpression(Span),
IfExpressionWithNoElse(Span),
RangeExpression(Span),
EquatePredicate(Span),
}
/// See `error_reporting.rs` for more details
#[derive(Clone, Show)]
pub enum ValuePairs<'tcx> {
Types(ty::expected_found<Ty<'tcx>>),
TraitRefs(ty::expected_found<Rc<ty::TraitRef<'tcx>>>),
PolyTraitRefs(ty::expected_found<ty::PolyTraitRef<'tcx>>),
}
/// The trace designates the path through inference that we took to
/// encounter an error or subtyping constraint.
///
/// See `error_reporting.rs` for more details.
#[derive(Clone, Show)]
pub struct TypeTrace<'tcx> {
origin: TypeOrigin,
values: ValuePairs<'tcx>,
}
/// The origin of a `r1 <= r2` constraint.
///
/// See `error_reporting.rs` for more details
#[derive(Clone, Show)]
pub enum SubregionOrigin<'tcx> {
Subtype(TypeTrace<'tcx>),
InfStackClosure(Span),
InvokeClosure(Span),
DerefPointer(Span),
FreeVariable(Span, ast::NodeId),
IndexSlice(Span),
RelateObjectBound(Span),
RelateParamBound(Span, Ty<'tcx>),
RelateRegionParamBound(Span),
RelateDefaultParamBound(Span, Ty<'tcx>),
Reborrow(Span),
ReborrowUpvar(Span, ty::UpvarId),
ReferenceOutlivesReferent(Ty<'tcx>, Span),
ExprTypeIsNotInScope(Ty<'tcx>, Span),
BindingTypeIsNotValidAtDecl(Span),
CallRcvr(Span),
CallArg(Span),
CallReturn(Span),
AddrOf(Span),
AutoBorrow(Span),
}
/// Times when we replace late-bound regions with variables:
#[derive(Clone, Copy, Show)]
pub enum LateBoundRegionConversionTime {
/// when a fn is called
FnCall,
/// when two higher-ranked types are compared
HigherRankedType,
/// when projecting an associated type
AssocTypeProjection(ast::Name),
}
/// Reasons to create a region inference variable
///
/// See `error_reporting.rs` for more details
#[derive(Clone, Show)]
pub enum RegionVariableOrigin<'tcx> {
MiscVariable(Span),
PatternRegion(Span),
AddrOfRegion(Span),
AddrOfSlice(Span),
Autoref(Span),
Coercion(TypeTrace<'tcx>),
EarlyBoundRegion(Span, ast::Name),
LateBoundRegion(Span,
ty::BoundRegion,
LateBoundRegionConversionTime),
UpvarRegion(ty::UpvarId, Span),
BoundRegionInCoherence(ast::Name),
}
#[derive(Copy, Show)]
pub enum fixup_err {
unresolved_int_ty(IntVid),
unresolved_float_ty(FloatVid),
unresolved_ty(TyVid),
}
pub fn fixup_err_to_string(f: fixup_err) -> String { loop { } }
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
-> InferCtxt<'a, 'tcx> {
loop { }
}
/// Computes the least upper-bound of `a` and `b`. If this is not possible, reports an error and
/// returns ty::err.
pub fn common_supertype<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>,
origin: TypeOrigin, a_is_expected: bool,
a: Ty<'tcx>, b: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_subty<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>, a_is_expected: bool,
origin: TypeOrigin, a: Ty<'tcx>, b: Ty<'tcx>)
-> ures<'tcx> {
loop { }
}
pub fn can_mk_subty<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>) -> ures<'tcx> {
loop { }
}
pub fn can_mk_eqty<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>) -> ures<'tcx> {
loop { }
}
pub fn mk_subr<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>,
origin: SubregionOrigin<'tcx>, a: ty::Region,
b: ty::Region) {
loop { }
}
pub fn mk_eqty<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>, a_is_expected: bool,
origin: TypeOrigin, a: Ty<'tcx>, b: Ty<'tcx>)
-> ures<'tcx> {
loop { }
}
pub fn mk_sub_poly_trait_refs<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>,
a_is_expected: bool,
origin: TypeOrigin,
a: ty::PolyTraitRef<'tcx>,
b: ty::PolyTraitRef<'tcx>)
-> ures<'tcx> {
loop { }
}
fn expected_found<T>(a_is_expected: bool, a: T, b: T)
-> ty::expected_found<T> {
loop { }
}
pub fn mk_coercety<'a,
'tcx>(cx: &InferCtxt<'a, 'tcx>,
a_is_expected: bool, origin: TypeOrigin,
a: Ty<'tcx>, b: Ty<'tcx>)
-> CoerceResult<'tcx> {
loop { }
}
trait then<'tcx> {
fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
T: Clone, F: FnOnce() -> Result<T, ty::type_err<'tcx>>;
}
impl <'tcx> then<'tcx> for ures<'tcx> {
fn then<T, F>(&self, f: F) -> Result<T, ty::type_err<'tcx>> where
T: Clone, F: FnOnce() -> Result<T, ty::type_err<'tcx>> {
loop { }
}
}
trait ToUres<'tcx> {
fn to_ures(&self) -> ures<'tcx>;
}
impl <'tcx, T> ToUres<'tcx> for cres<'tcx, T> {
fn to_ures(&self) -> ures<'tcx> { loop { } }
}
trait CresCompare<'tcx, T> {
fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
F: FnOnce() -> ty::type_err<'tcx>;
}
impl <'tcx, T: Clone + PartialEq> CresCompare<'tcx, T> for
cres<'tcx, T> {
fn compare<F>(&self, t: T, f: F) -> cres<'tcx, T> where
F: FnOnce() -> ty::type_err<'tcx> {
loop { }
}
}
pub fn uok<'tcx>() -> ures<'tcx> { loop { } }
#[must_use =
"once you start a snapshot, you should always consume it"]
pub struct CombinedSnapshot {
type_snapshot: type_variable::Snapshot,
int_snapshot: unify::Snapshot<ty::IntVid>,
float_snapshot: unify::Snapshot<ty::FloatVid>,
region_vars_snapshot: RegionSnapshot,
}
impl <'a, 'tcx> InferCtxt<'a, 'tcx> {
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
loop { }
}
pub fn type_var_diverges(&'a self, ty: Ty) -> bool { loop { } }
pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
loop { }
}
pub fn type_is_unconstrained_numeric(&'a self, ty: Ty)
-> UnconstrainedNumeric {
loop { }
}
pub fn combine_fields<'b>(&'b self, a_is_expected: bool,
trace: TypeTrace<'tcx>)
-> CombineFields<'b, 'tcx> {
loop { }
}
pub fn equate<'b>(&'b self, a_is_expected: bool,
trace: TypeTrace<'tcx>) -> Equate<'b, 'tcx> {
loop { }
}
pub fn sub<'b>(&'b self, a_is_expected: bool,
trace: TypeTrace<'tcx>) -> Sub<'b, 'tcx> {
loop { }
}
pub fn lub<'b>(&'b self, a_is_expected: bool,
trace: TypeTrace<'tcx>) -> Lub<'b, 'tcx> {
loop { }
}
fn start_snapshot(&self) -> CombinedSnapshot { loop { } }
fn rollback_to(&self, snapshot: CombinedSnapshot) { loop { } }
fn commit_from(&self, snapshot: CombinedSnapshot) { loop { } }
/// Execute `f` and commit the bindings
pub fn commit_unconditionally<R, F>(&self, f: F) -> R where
F: FnOnce() -> R {
loop { }
}
/// Execute `f` and commit the bindings if successful
pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where
F: FnOnce() -> Result<T, E> {
loop { }
}
/// Execute `f` and commit only the region bindings if successful.
/// The function f must be very careful not to leak any non-region
/// variables that get created.
pub fn commit_regions_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
where F: FnOnce() -> Result<T, E> {
loop { }
}
/// Execute `f`, unroll bindings on panic
pub fn try<T, E, F>(&self, f: F) -> Result<T, E> where
F: FnOnce(&CombinedSnapshot) -> Result<T, E> {
loop { }
}
/// Execute `f` then unroll any bindings it creates
pub fn probe<R, F>(&self, f: F) -> R where
F: FnOnce(&CombinedSnapshot) -> R {
loop { }
}
pub fn add_given(&self, sub: ty::FreeRegion, sup: ty::RegionVid) {
loop { }
}
pub fn sub_types(&self, a_is_expected: bool, origin: TypeOrigin,
a: Ty<'tcx>, b: Ty<'tcx>) -> ures<'tcx> {
loop { }
}
pub fn eq_types(&self, a_is_expected: bool, origin: TypeOrigin,
a: Ty<'tcx>, b: Ty<'tcx>) -> ures<'tcx> {
loop { }
}
pub fn sub_trait_refs(&self, a_is_expected: bool,
origin: TypeOrigin,
a: Rc<ty::TraitRef<'tcx>>,
b: Rc<ty::TraitRef<'tcx>>) -> ures<'tcx> {
loop { }
}
pub fn sub_poly_trait_refs(&self, a_is_expected: bool,
origin: TypeOrigin,
a: ty::PolyTraitRef<'tcx>,
b: ty::PolyTraitRef<'tcx>)
-> ures<'tcx> {
loop { }
}
pub fn skolemize_late_bound_regions<T>(&self,
value: &ty::Binder<T>,
snapshot:
&CombinedSnapshot)
-> (T, SkolemizationMap) where T: TypeFoldable<'tcx> +
Repr<'tcx> {
/*! See `higher_ranked::skolemize_late_bound_regions` */
loop { }
}
pub fn leak_check(&self, skol_map: &SkolemizationMap,
snapshot: &CombinedSnapshot) -> ures<'tcx> {
/*! See `higher_ranked::leak_check` */
loop { }
}
pub fn plug_leaks<T>(&self, skol_map: SkolemizationMap,
snapshot: &CombinedSnapshot, value: &T) -> T
where T: TypeFoldable<'tcx> + Repr<'tcx> {
/*! See `higher_ranked::plug_leaks` */
loop { }
}
pub fn equality_predicate(&self, span: Span,
predicate:
&ty::PolyEquatePredicate<'tcx>)
-> ures<'tcx> {
loop { }
}
pub fn region_outlives_predicate(&self, span: Span,
predicate:
&ty::PolyRegionOutlivesPredicate)
-> ures<'tcx> {
loop { }
}
pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
loop { }
}
pub fn next_ty_var(&self) -> Ty<'tcx> { loop { } }
pub fn next_diverging_ty_var(&self) -> Ty<'tcx> { loop { } }
pub fn next_ty_vars(&self, n: uint) -> Vec<Ty<'tcx>> { loop { } }
pub fn next_int_var_id(&self) -> IntVid { loop { } }
pub fn next_float_var_id(&self) -> FloatVid { loop { } }
pub fn next_region_var(&self, origin: RegionVariableOrigin<'tcx>)
-> ty::Region {
loop { }
}
pub fn region_vars_for_defs(&self, span: Span,
defs: &[ty::RegionParameterDef])
-> Vec<ty::Region> {
loop { }
}
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
pub fn fresh_substs_for_generics(&self, span: Span,
generics: &ty::Generics<'tcx>)
-> subst::Substs<'tcx> {
loop { }
}
/// Given a set of generics defined on a trait, returns a substitution mapping each output
/// type/region parameter to a fresh inference variable, and mapping the self type to
/// `self_ty`.
pub fn fresh_substs_for_trait(&self, span: Span,
generics: &ty::Generics<'tcx>,
self_ty: Ty<'tcx>)
-> subst::Substs<'tcx> {
loop { }
}
pub fn fresh_bound_region(&self, debruijn: ty::DebruijnIndex)
-> ty::Region {
loop { }
}
pub fn resolve_regions_and_report_errors(&self,
subject_node_id:
ast::NodeId) {
loop { }
}
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String { loop { } }
pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
loop { }
}
pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>)
-> String {
loop { }
}
pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn resolve_type_vars_if_possible<T: TypeFoldable<'tcx>>(&self,
value:
&T)
-> T {
/*!
* Where possible, replaces type/int/float variables in
* `value` with their final value. Note that region variables
* are unaffected. If a type variable has not been unified, it
* is left as is. This is an idempotent operation that does
* not affect inference state in any way and so you can do it
* at will.
*/
loop { }
}
pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: &T)
-> fres<T> {
/*!
* Attempts to resolve all type/region variables in
* `value`. Region inference must have been run already (e.g.,
* by calling `resolve_regions_and_report_errors`). If some
* variable was never unified, an `Err` results.
*
* This method is idempotent, but it not typically not invoked
* except during the writeback phase.
*/
loop { }
}
pub fn type_error_message_str<M>(&self, sp: Span, mk_msg: M,
actual_ty: String,
err: Option<&ty::type_err<'tcx>>)
where M: FnOnce(Option<String>, String) -> String {
loop { }
}
pub fn type_error_message_str_with_expected<M>(&self, sp: Span,
mk_msg: M,
expected_ty:
Option<Ty<'tcx>>,
actual_ty: String,
err:
Option<&ty::type_err<'tcx>>)
where M: FnOnce(Option<String>, String) -> String {
loop { }
}
pub fn type_error_message<M>(&self, sp: Span, mk_msg: M,
actual_ty: Ty<'tcx>,
err: Option<&ty::type_err<'tcx>>)
where M: FnOnce(String) -> String {
loop { }
}
pub fn report_mismatched_types(&self, span: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
err: &ty::type_err<'tcx>) {
loop { }
}
pub fn replace_late_bound_regions_with_fresh_var<T>(&self,
span: Span,
lbrct:
LateBoundRegionConversionTime,
value:
&ty::Binder<T>)
-> (T, FnvHashMap<ty::BoundRegion, ty::Region>) where
T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
/// See `verify_generic_bound` method in `region_inference`
pub fn verify_generic_bound(&self, origin: SubregionOrigin<'tcx>,
kind: GenericKind<'tcx>,
a: ty::Region, bs: Vec<ty::Region>) {
loop { }
}
pub fn can_equate<T>(&self, a: &T, b: &T) -> ures<'tcx> where
T: Combineable<'tcx> + Repr<'tcx> {
loop { }
}
}
impl <'tcx> TypeTrace<'tcx> {
pub fn span(&self) -> Span { loop { } }
pub fn dummy(tcx: &ty::ctxt<'tcx>) -> TypeTrace<'tcx> {
loop { }
}
}
impl <'tcx> Repr<'tcx> for TypeTrace<'tcx> {
fn repr(&self, tcx: &ty::ctxt) -> String { loop { } }
}
impl TypeOrigin {
pub fn span(&self) -> Span { loop { } }
}
impl <'tcx> Repr<'tcx> for TypeOrigin {
fn repr(&self, tcx: &ty::ctxt) -> String { loop { } }
}
impl <'tcx> SubregionOrigin<'tcx> {
pub fn span(&self) -> Span { loop { } }
}
impl <'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> RegionVariableOrigin<'tcx> {
pub fn span(&self) -> Span { loop { } }
}
impl <'tcx> Repr<'tcx> for RegionVariableOrigin<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
}
pub mod lang_items {
pub use self::LangItem::*;
use session::Session;
use metadata::csearch::each_lang_item;
use middle::ty;
use middle::weak_lang_items;
use util::nodemap::FnvHashMap;
use syntax::ast;
use syntax::ast_util::local_def;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::parse::token::InternedString;
use syntax::visit::Visitor;
use syntax::visit;
use std::iter::Enumerate;
use std::num::FromPrimitive;
use std::slice;
macro_rules! lets_do_this((
$ (
$ variant : ident , $ name : expr , $ method
: ident ; ) * ) => {
# [
derive (
Copy , FromPrimitive , PartialEq , Eq , Hash
) ] pub enum LangItem { $ ( $ variant ) , *
} pub struct LanguageItems {
pub items : Vec < Option < ast :: DefId >> ,
pub missing : Vec < LangItem > , } impl
LanguageItems {
pub fn new ( ) -> LanguageItems {
fn foo ( _ : LangItem ) -> Option < ast ::
DefId > { None } LanguageItems {
items : vec ! ( $ ( foo ( $ variant ) ) , *
) , missing : Vec :: new ( ) , } } pub fn
items < 'a > ( & 'a self ) -> Enumerate <
slice :: Iter < 'a , Option < ast :: DefId
>> > {
self . items . iter ( ) . enumerate ( ) }
pub fn item_name ( index : uint ) -> &
'static str {
let item : Option < LangItem > =
FromPrimitive :: from_uint ( index ) ; match
item {
$ ( Some ( $ variant ) => $ name , ) * None
=> "???" } } pub fn require (
& self , it : LangItem ) -> Result < ast ::
DefId , String > {
match self . items [ it as uint ] {
Some ( id ) => Ok ( id ) , None => {
Err (
format ! (
"requires `{}` lang_item" , LanguageItems ::
item_name ( it as uint ) ) ) } } } 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 ) , } }
pub fn to_builtin_kind (
& self , id : ast :: DefId ) -> Option < ty
:: BuiltinBound > {
if Some ( id ) == self . send_trait ( ) {
Some ( ty :: BoundSend ) } else if Some ( id
) == self . sized_trait ( ) {
Some ( ty :: BoundSized ) } else if Some (
id ) == self . copy_trait ( ) {
Some ( ty :: BoundCopy ) } else if Some ( id
) == self . sync_trait ( ) {
Some ( ty :: BoundSync ) } else { None } }
pub fn fn_trait_kind (
& self , id : ast :: DefId ) -> Option < ty
:: UnboxedClosureKind > {
let def_id_kinds = [
(
self . fn_trait ( ) , ty ::
FnUnboxedClosureKind ) , (
self . fn_mut_trait ( ) , ty ::
FnMutUnboxedClosureKind ) , (
self . fn_once_trait ( ) , ty ::
FnOnceUnboxedClosureKind ) , ] ; for & (
opt_def_id , kind ) in def_id_kinds . iter (
) {
if Some ( id ) == opt_def_id {
return Some ( kind ) ; } } None } $ (
# [ allow ( dead_code ) ] pub fn $ method (
& self ) -> Option < ast :: DefId > {
self . items [ $ variant as uint ] } ) * }
struct LanguageItemCollector < 'a > {
items : LanguageItems , session : & 'a
Session , item_refs : FnvHashMap < & 'static
str , uint > , } impl < 'a , 'v > Visitor <
'v > for LanguageItemCollector < 'a > {
fn visit_item (
& mut self , item : & ast :: Item ) {
match extract ( item . attrs . as_slice ( )
) {
Some ( value ) => {
let item_index = self . item_refs . get (
value . get ( ) ) . map ( | x | * x ) ;
match item_index {
Some ( item_index ) => {
self . collect_item (
item_index , local_def ( item . id ) , item
. span ) } None => { } } } None => { } }
visit :: walk_item ( self , item ) ; } }
impl < 'a > LanguageItemCollector < 'a > {
pub fn new ( session : & 'a Session ) ->
LanguageItemCollector < 'a > {
let mut item_refs = FnvHashMap :: new ( ) ;
$ (
item_refs . insert (
$ name , $ variant as uint ) ; ) *
LanguageItemCollector {
session : session , items : LanguageItems ::
new ( ) , item_refs : item_refs } } pub fn
collect_item (
& mut self , item_index : uint , item_def_id
: ast :: DefId , span : Span ) {
match self . items . items [ item_index ] {
Some ( original_def_id ) if original_def_id
!= item_def_id => {
span_err ! (
self . session , span , E0152 ,
"duplicate entry for `{}`" , LanguageItems
:: item_name ( item_index ) ) ; } Some ( _ )
| None => { } } self . items . items [
item_index ] = Some ( item_def_id ) ; } pub
fn collect_local_language_items (
& mut self , krate : & ast :: Crate ) {
visit :: walk_crate ( self , krate ) ; } pub
fn collect_external_language_items (
& mut self ) {
let crate_store = & self . session . cstore
; crate_store . iter_crate_data (
| crate_number , _crate_metadata | {
each_lang_item (
crate_store , crate_number , | node_id ,
item_index | {
let def_id = ast :: DefId {
krate : crate_number , node : node_id } ;
self . collect_item (
item_index , def_id , DUMMY_SP ) ; true } )
; } ) } pub fn collect (
& mut self , krate : & ast :: Crate ) {
self . collect_local_language_items ( krate
) ; self . collect_external_language_items (
) ; } } pub fn extract (
attrs : & [ ast :: Attribute ] ) -> Option <
InternedString > {
for attribute in attrs . iter ( ) {
match attribute . value_str ( ) {
Some ( ref value ) if attribute . check_name
( "lang" ) => {
return Some ( value . clone ( ) ) ; } _ =>
{ } } } return None ; } pub fn
collect_language_items (
krate : & ast :: Crate , session : & Session
) -> LanguageItems {
let mut collector = LanguageItemCollector ::
new ( session ) ; collector . collect (
krate ) ; let LanguageItemCollector {
mut items , .. } = collector ;
weak_lang_items :: check_crate (
krate , session , & mut items ) ; session .
abort_if_errors ( ) ; items } });
lets_do_this! (SendTraitLangItem , "send" , send_trait ;
SizedTraitLangItem , "sized" , sized_trait ;
CopyTraitLangItem , "copy" , copy_trait ;
SyncTraitLangItem , "sync" , sync_trait ;
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 ;
IndexMutTraitLangItem , "index_mut" , index_mut_trait ;
RangeStructLangItem , "range" , range_struct ;
RangeFromStructLangItem , "range_from" ,
range_from_struct ; RangeToStructLangItem , "range_to"
, range_to_struct ; FullRangeStructLangItem ,
"full_range" , full_range_struct ; UnsafeTypeLangItem ,
"unsafe" , unsafe_type ; DerefTraitLangItem , "deref" ,
deref_trait ; DerefMutTraitLangItem , "deref_mut" ,
deref_mut_trait ; FnTraitLangItem , "fn" , fn_trait ;
FnMutTraitLangItem , "fn_mut" , fn_mut_trait ;
FnOnceTraitLangItem , "fn_once" , fn_once_trait ;
EqTraitLangItem , "eq" , eq_trait ; OrdTraitLangItem ,
"ord" , ord_trait ; StrEqFnLangItem , "str_eq" ,
str_eq_fn ; PanicFnLangItem , "panic" , panic_fn ;
PanicBoundsCheckFnLangItem , "panic_bounds_check" ,
panic_bounds_check_fn ; PanicFmtLangItem , "panic_fmt"
, panic_fmt ; 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 ;
EhPersonalityLangItem , "eh_personality" ,
eh_personality ; ExchangeHeapLangItem , "exchange_heap"
, exchange_heap ; OwnedBoxLangItem , "owned_box" ,
owned_box ; 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 ; NoCopyItem , "no_copy_bound" ,
no_copy_bound ; NoSyncItem , "no_sync_bound" ,
no_sync_bound ; ManagedItem , "managed_bound" ,
managed_bound ; NonZeroItem , "non_zero" , non_zero ;
IteratorItem , "iterator" , iterator ;
StackExhaustedLangItem , "stack_exhausted" ,
stack_exhausted ;);
}
pub mod liveness {
//! A classic liveness analysis based on dataflow over the AST. Computes,
//! for each local variable in a function, whether that variable is live
//! at a given point. Program execution points are identified by their
//! id.
//!
//! # Basic idea
//!
//! The basic model is that each local variable is assigned an index. We
//! represent sets of local variables using a vector indexed by this
//! index. The value in the vector is either 0, indicating the variable
//! is dead, or the id of an expression that uses the variable.
//!
//! We conceptually walk over the AST in reverse execution order. If we
//! find a use of a variable, we add it to the set of live variables. If
//! we find an assignment to a variable, we remove it from the set of live
//! variables. When we have to merge two flows, we take the union of
//! those two flows---if the variable is live on both paths, we simply
//! pick one id. In the event of loops, we continue doing this until a
//! fixed point is reached.
//!
//! ## Checking initialization
//!
//! At the function entry point, all variables must be dead. If this is
//! not the case, we can report an error using the id found in the set of
//! live variables, which identifies a use of the variable which is not
//! dominated by an assignment.
//!
//! ## Checking moves
//!
//! After each explicit move, the variable must be dead.
//!
//! ## Computing last uses
//!
//! Any use of the variable where the variable is dead afterwards is a
//! last use.
//!
//! # Implementation details
//!
//! The actual implementation contains two (nested) walks over the AST.
//! The outer walk has the job of building up the ir_maps instance for the
//! enclosing function. On the way down the tree, it identifies those AST
//! nodes and variable IDs that will be needed for the liveness analysis
//! and assigns them contiguous IDs. The liveness id for an AST node is
//! called a `live_node` (it's a newtype'd uint) and the id for a variable
//! is called a `variable` (another newtype'd uint).
//!
//! On the way back up the tree, as we are about to exit from a function
//! declaration we allocate a `liveness` instance. Now that we know
//! precisely how many nodes and variables we need, we can allocate all
//! the various arrays that we will need to precisely the right size. We then
//! perform the actual propagation on the `liveness` instance.
//!
//! This propagation is encoded in the various `propagate_through_*()`
//! methods. It effectively does a reverse walk of the AST; whenever we
//! reach a loop node, we iterate until a fixed point is reached.
//!
//! ## The `Users` struct
//!
//! At each live node `N`, we track three pieces of information for each
//! variable `V` (these are encapsulated in the `Users` struct):
//!
//! - `reader`: the `LiveNode` ID of some node which will read the value
//! that `V` holds on entry to `N`. Formally: a node `M` such
//! that there exists a path `P` from `N` to `M` where `P` does not
//! write `V`. If the `reader` is `invalid_node()`, then the current
//! value will never be read (the variable is dead, essentially).
//!
//! - `writer`: the `LiveNode` ID of some node which will write the
//! variable `V` and which is reachable from `N`. Formally: a node `M`
//! such that there exists a path `P` from `N` to `M` and `M` writes
//! `V`. If the `writer` is `invalid_node()`, then there is no writer
//! of `V` that follows `N`.
//!
//! - `used`: a boolean value indicating whether `V` is *used*. We
//! distinguish a *read* from a *use* in that a *use* is some read that
//! is not just used to generate a new value. For example, `x += 1` is
//! a read but not a use. This is used to generate better warnings.
//!
//! ## Special Variables
//!
//! We generate various special variables for various, well, special purposes.
//! These are described in the `specials` struct:
//!
//! - `exit_ln`: a live node that is generated to represent every 'exit' from
//! the function, whether it be by explicit return, panic, or other means.
//!
//! - `fallthrough_ln`: a live node that represents a fallthrough
//!
//! - `no_ret_var`: a synthetic variable that is only 'read' from, the
//! fallthrough node. This allows us to detect functions where we fail
//! to return explicitly.
//! - `clean_exit_var`: a synthetic variable that is only 'read' from the
//! fallthrough node. It is only live if the function could converge
//! via means other than an explicit `return` expression. That is, it is
//! only dead if the end of the function's block can never be reached.
//! It is the responsibility of typeck to ensure that there are no
//! `return` expressions in a function declared as diverging.
use self::LoopKind::*;
use self::LiveNodeKind::*;
use self::VarKind::*;
use middle::def::*;
use middle::mem_categorization::Typer;
use middle::pat_util;
use middle::region::CodeExtent;
use middle::ty;
use middle::ty::UnboxedClosureTyper;
use lint;
use util::nodemap::NodeMap;
use std::{fmt, io, uint};
use std::rc::Rc;
use std::iter::repeat;
use syntax::ast::{self, NodeId, Expr};
use syntax::codemap::{BytePos, original_sp, Span};
use syntax::parse::token::{self, special_idents};
use syntax::print::pprust::{expr_to_string, block_to_string};
use syntax::ptr::P;
use syntax::ast_util;
use syntax::visit::{self, Visitor, FnKind};
/// For use with `propagate_through_loop`.
enum LoopKind<'a> {
/// An endless `loop` loop.
LoopLoop,
/// A `while` loop, with the given expression as condition.
WhileLoop(&'a Expr),
/// A `for` loop, with the given pattern to bind.
ForLoop(&'a ast::Pat),
}
#[derive(Copy, PartialEq)]
struct Variable(uint);
#[derive(Copy, PartialEq)]
struct LiveNode(uint);
impl Variable {
fn get(&self) -> uint { loop { } }
}
impl LiveNode {
fn get(&self) -> uint { loop { } }
}
impl Clone for LiveNode {
fn clone(&self) -> LiveNode { loop { } }
}
#[derive(Copy, PartialEq, Show)]
enum LiveNodeKind {
FreeVarNode(Span),
ExprNode(Span),
VarDefNode(Span),
ExitNode,
}
fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt)
-> String {
loop { }
}
impl <'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, id: NodeId) {
loop { }
}
fn visit_local(&mut self, l: &ast::Local) { loop { } }
fn visit_expr(&mut self, ex: &Expr) { loop { } }
fn visit_arm(&mut self, a: &ast::Arm) { loop { } }
}
pub fn check_crate(tcx: &ty::ctxt) { loop { } }
impl fmt::Show for LiveNode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl fmt::Show for Variable {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl LiveNode {
fn is_valid(&self) -> bool { loop { } }
}
fn invalid_node() -> LiveNode { loop { } }
struct CaptureInfo {
ln: LiveNode,
var_nid: NodeId,
}
#[derive(Copy, Show)]
struct LocalInfo {
id: NodeId,
ident: ast::Ident,
}
#[derive(Copy, Show)]
enum VarKind {
Arg(NodeId, ast::Ident),
Local(LocalInfo),
ImplicitRet,
CleanExit,
}
struct IrMaps<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
num_live_nodes: uint,
num_vars: uint,
live_node_map: NodeMap<LiveNode>,
variable_map: NodeMap<Variable>,
capture_info_map: NodeMap<Rc<Vec<CaptureInfo>>>,
var_kinds: Vec<VarKind>,
lnks: Vec<LiveNodeKind>,
}
impl <'a, 'tcx> IrMaps<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>) -> IrMaps<'a, 'tcx> { loop { } }
fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode {
loop { }
}
fn add_live_node_for_node(&mut self, node_id: NodeId,
lnk: LiveNodeKind) {
loop { }
}
fn add_variable(&mut self, vk: VarKind) -> Variable { loop { } }
fn variable(&self, node_id: NodeId, span: Span) -> Variable {
loop { }
}
fn variable_name(&self, var: Variable) -> String { loop { } }
fn set_captures(&mut self, node_id: NodeId,
cs: Vec<CaptureInfo>) {
loop { }
}
fn lnk(&self, ln: LiveNode) -> LiveNodeKind { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, n: NodeId) {
loop { }
}
fn visit_local(&mut self, l: &ast::Local) { loop { } }
fn visit_expr(&mut self, ex: &Expr) { loop { } }
fn visit_arm(&mut self, a: &ast::Arm) { loop { } }
}
fn visit_fn(ir: &mut IrMaps, fk: FnKind, decl: &ast::FnDecl,
body: &ast::Block, sp: Span, id: ast::NodeId) {
loop { }
}
fn visit_local(ir: &mut IrMaps, local: &ast::Local) { loop { } }
fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) { loop { } }
fn visit_expr(ir: &mut IrMaps, expr: &Expr) { loop { } }
#[derive(Clone, Copy)]
struct Users {
reader: LiveNode,
writer: LiveNode,
used: bool,
}
fn invalid_users() -> Users { loop { } }
#[derive(Copy)]
struct Specials {
exit_ln: LiveNode,
fallthrough_ln: LiveNode,
no_ret_var: Variable,
clean_exit_var: Variable,
}
static ACC_READ: uint = 1u;
static ACC_WRITE: uint = 2u;
static ACC_USE: uint = 4u;
struct Liveness<'a, 'tcx:'a> {
ir: &'a mut IrMaps<'a, 'tcx>,
s: Specials,
successors: Vec<LiveNode>,
users: Vec<Users>,
loop_scope: Vec<NodeId>,
break_ln: NodeMap<LiveNode>,
cont_ln: NodeMap<LiveNode>,
}
impl <'a, 'tcx> Liveness<'a, 'tcx> {
fn new(ir: &'a mut IrMaps<'a, 'tcx>, specials: Specials)
-> Liveness<'a, 'tcx> {
loop { }
}
fn live_node(&self, node_id: NodeId, span: Span) -> LiveNode {
loop { }
}
fn variable(&self, node_id: NodeId, span: Span) -> Variable {
loop { }
}
fn pat_bindings<F>(&mut self, pat: &ast::Pat, mut f: F) where
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span,
NodeId) {
loop { }
}
fn arm_pats_bindings<F>(&mut self, pat: Option<&ast::Pat>, f: F)
where
F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span,
NodeId) {
loop { }
}
fn define_bindings_in_pat(&mut self, pat: &ast::Pat,
succ: LiveNode) -> LiveNode {
loop { }
}
fn define_bindings_in_arm_pats(&mut self, pat: Option<&ast::Pat>,
succ: LiveNode) -> LiveNode {
loop { }
}
fn idx(&self, ln: LiveNode, var: Variable) -> uint { loop { } }
fn live_on_entry(&self, ln: LiveNode, var: Variable)
-> Option<LiveNodeKind> {
loop { }
}
fn live_on_exit(&self, ln: LiveNode, var: Variable)
-> Option<LiveNodeKind> {
loop { }
}
fn used_on_entry(&self, ln: LiveNode, var: Variable) -> bool {
loop { }
}
fn assigned_on_entry(&self, ln: LiveNode, var: Variable)
-> Option<LiveNodeKind> {
loop { }
}
fn assigned_on_exit(&self, ln: LiveNode, var: Variable)
-> Option<LiveNodeKind> {
loop { }
}
fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode,
mut op: F) where
F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint) {
loop { }
}
fn write_vars<F>(&self, wr: &mut io::Writer, ln: LiveNode,
mut test: F) -> io::IoResult<()> where
F: FnMut(uint) -> LiveNode {
loop { }
}
fn find_loop_scope(&self, opt_label: Option<ast::Ident>,
id: NodeId, sp: Span) -> NodeId {
loop { }
}
#[allow(unused_must_use)]
fn ln_str(&self, ln: LiveNode) -> String { loop { } }
fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) {
loop { }
}
fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) {
loop { }
}
fn merge_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode,
first_merge: bool) -> bool {
loop { }
}
fn define(&mut self, writer: LiveNode, var: Variable) {
loop { }
}
fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
loop { }
}
fn compute(&mut self, decl: &ast::FnDecl, body: &ast::Block)
-> LiveNode {
loop { }
}
fn propagate_through_fn_block(&mut self, _: &ast::FnDecl,
blk: &ast::Block) -> LiveNode {
loop { }
}
fn propagate_through_block(&mut self, blk: &ast::Block,
succ: LiveNode) -> LiveNode {
loop { }
}
fn propagate_through_stmt(&mut self, stmt: &ast::Stmt,
succ: LiveNode) -> LiveNode {
loop { }
}
fn propagate_through_decl(&mut self, decl: &ast::Decl,
succ: LiveNode) -> LiveNode {
loop { }
}
fn propagate_through_local(&mut self, local: &ast::Local,
succ: LiveNode) -> LiveNode {
loop { }
}
fn propagate_through_exprs(&mut self, exprs: &[P<Expr>],
succ: LiveNode) -> LiveNode {
loop { }
}
fn propagate_through_opt_expr(&mut self, opt_expr: Option<&Expr>,
succ: LiveNode) -> LiveNode {
loop { }
}
fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
-> LiveNode {
loop { }
}
fn propagate_through_lvalue_components(&mut self, expr: &Expr,
succ: LiveNode)
-> LiveNode {
loop { }
}
fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
-> LiveNode {
loop { }
}
fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
-> LiveNode {
loop { }
}
fn propagate_through_loop(&mut self, expr: &Expr, kind: LoopKind,
body: &ast::Block, succ: LiveNode)
-> LiveNode {
loop { }
}
fn with_loop_nodes<R,
F>(&mut self, loop_node_id: NodeId,
break_ln: LiveNode, cont_ln: LiveNode, f: F)
-> R where F: FnOnce(&mut Liveness<'a, 'tcx>) -> R {
loop { }
}
}
fn check_local(this: &mut Liveness, local: &ast::Local) { loop { } }
fn check_arm(this: &mut Liveness, arm: &ast::Arm) { loop { } }
fn check_expr(this: &mut Liveness, expr: &Expr) { loop { } }
fn check_fn(_v: &Liveness, _fk: FnKind, _decl: &ast::FnDecl,
_body: &ast::Block, _sp: Span, _id: NodeId) {
loop { }
}
impl <'a, 'tcx> Liveness<'a, 'tcx> {
fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
loop { }
}
fn check_ret(&self, id: NodeId, sp: Span, _fk: FnKind,
entry_ln: LiveNode, body: &ast::Block) {
loop { }
}
fn check_lvalue(&mut self, expr: &Expr) { loop { } }
fn should_warn(&self, var: Variable) -> Option<String> {
loop { }
}
fn warn_about_unused_args(&self, decl: &ast::FnDecl,
entry_ln: LiveNode) {
loop { }
}
fn warn_about_unused_or_dead_vars_in_pat(&mut self,
pat: &ast::Pat) {
loop { }
}
fn warn_about_unused(&self, sp: Span, id: NodeId, ln: LiveNode,
var: Variable) -> bool {
loop { }
}
fn warn_about_dead_assign(&self, sp: Span, id: NodeId,
ln: LiveNode, var: Variable) {
loop { }
}
}
}
pub mod mem_categorization {
//! # Categorization
//!
//! The job of the categorization module is to analyze an expression to
//! determine what kind of memory is used in evaluating it (for example,
//! where dereferences occur and what kind of pointer is dereferenced;
//! whether the memory is mutable; etc)
//!
//! Categorization effectively transforms all of our expressions into
//! expressions of the following forms (the actual enum has many more
//! possibilities, naturally, but they are all variants of these base
//! forms):
//!
//! E = rvalue // some computed rvalue
//! | x // address of a local variable or argument
//! | *E // deref of a ptr
//! | E.comp // access to an interior component
//!
//! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an
//! address where the result is to be found. If Expr is an lvalue, then this
//! is the address of the lvalue. If Expr is an rvalue, this is the address of
//! some temporary spot in memory where the result is stored.
//!
//! Now, cat_expr() classifies the expression Expr and the address A=ToAddr(Expr)
//! as follows:
//!
//! - cat: what kind of expression was this? This is a subset of the
//! full expression forms which only includes those that we care about
//! for the purpose of the analysis.
//! - mutbl: mutability of the address A
//! - ty: the type of data found at the address A
//!
//! The resulting categorization tree differs somewhat from the expressions
//! themselves. For example, auto-derefs are explicit. Also, an index a[b] is
//! decomposed into two operations: a dereference to reach the array data and
//! then an index to jump forward to the relevant item.
//!
//! ## By-reference upvars
//!
//! One part of the translation which may be non-obvious is that we translate
//! closure upvars into the dereference of a borrowed pointer; this more closely
//! resembles the runtime translation. So, for example, if we had:
//!
//! let mut x = 3;
//! let y = 5;
//! let inc = || x += y;
//!
//! Then when we categorize `x` (*within* the closure) we would yield a
//! result of `*x'`, effectively, where `x'` is a `cat_upvar` reference
//! tied to `x`. The type of `x'` will be a borrowed pointer.
#![allow(non_camel_case_types)]
pub use self::PointerKind::*;
pub use self::InteriorKind::*;
pub use self::FieldName::*;
pub use self::ElementKind::*;
pub use self::MutabilityCategory::*;
pub use self::InteriorSafety::*;
pub use self::AliasableReason::*;
pub use self::Note::*;
pub use self::deref_kind::*;
pub use self::categorization::*;
use middle::def;
use middle::region;
use middle::ty::{self, Ty};
use util::nodemap::{NodeMap};
use util::ppaux::{Repr, UserString};
use syntax::ast::{MutImmutable, MutMutable};
use syntax::ast;
use syntax::ast_map;
use syntax::codemap::Span;
use syntax::print::pprust;
use syntax::parse::token;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Clone, PartialEq, Show)]
pub enum categorization<'tcx> {
cat_rvalue(ty::Region),
cat_static_item,
cat_upvar(Upvar),
cat_local(ast::NodeId),
cat_deref(cmt<'tcx>, uint, PointerKind),
cat_interior(cmt<'tcx>, InteriorKind),
cat_downcast(cmt<'tcx>, ast::DefId),
}
#[derive(Clone, Copy, PartialEq, Show)]
pub struct Upvar {
pub id: ty::UpvarId,
pub kind: ty::UnboxedClosureKind,
pub is_unboxed: bool,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum PointerKind {
/// `Box<T>`
Unique,
/// `&T`
BorrowedPtr(ty::BorrowKind, ty::Region),
/// `*T`
UnsafePtr(ast::Mutability),
/// Implicit deref of the `&T` that results from an overloaded index `[]`.
Implicit(ty::BorrowKind, ty::Region),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum InteriorKind {
InteriorField(FieldName),
InteriorElement(ElementKind),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum FieldName { NamedField(ast::Name), PositionalField(uint), }
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum ElementKind { VecElement, OtherElement, }
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum MutabilityCategory { McImmutable, McDeclared, McInherited, }
#[derive(Clone, Copy, PartialEq, Show)]
pub enum Note {
NoteClosureEnv(ty::UpvarId),
NoteUpvarRef(ty::UpvarId),
NoteNone,
}
#[derive(Clone, PartialEq, Show)]
pub struct cmt_<'tcx> {
pub id: ast::NodeId,
pub span: Span,
pub cat: categorization<'tcx>,
pub mutbl: MutabilityCategory,
pub ty: Ty<'tcx>,
pub note: Note,
}
pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
#[derive(Copy)]
pub enum deref_kind {
deref_ptr(PointerKind),
deref_interior(InteriorKind),
}
pub fn deref_kind(t: Ty) -> McResult<deref_kind> { loop { } }
pub trait ast_node {
fn id(&self) -> ast::NodeId;
fn span(&self) -> Span;
}
impl ast_node for ast::Expr {
fn id(&self) -> ast::NodeId { loop { } }
fn span(&self) -> Span { loop { } }
}
impl ast_node for ast::Pat {
fn id(&self) -> ast::NodeId { loop { } }
fn span(&self) -> Span { loop { } }
}
pub struct MemCategorizationContext<'t, TYPER: 't> {
typer: &'t TYPER,
}
impl <'t, TYPER: 't> Copy for MemCategorizationContext<'t, TYPER> { }
pub type McResult<T> = Result<T, ()>;
/// The `Typer` trait provides the interface for the mem-categorization
/// module to the results of the type check. It can be used to query
/// the type assigned to an expression node, to inquire after adjustments,
/// and so on.
///
/// This interface is needed because mem-categorization is used from
/// two places: `regionck` and `borrowck`. `regionck` executes before
/// type inference is complete, and hence derives types and so on from
/// intermediate tables. This also implies that type errors can occur,
/// and hence `node_ty()` and friends return a `Result` type -- any
/// error will propagate back up through the mem-categorization
/// routines.
///
/// In the borrow checker, in contrast, type checking is complete and we
/// know that no errors have occurred, so we simply consult the tcx and we
/// can be sure that only `Ok` results will occur.
pub trait Typer<'tcx>: ty::UnboxedClosureTyper<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
fn expr_ty_adjusted(&self, expr: &ast::Expr)
-> McResult<Ty<'tcx>>;
fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool;
fn node_method_ty(&self, method_call: ty::MethodCall)
-> Option<Ty<'tcx>>;
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>;
fn adjustments<'a>(&'a self)
-> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId)
-> Option<region::CodeExtent>;
fn upvar_borrow(&self, upvar_id: ty::UpvarId)
-> Option<ty::UpvarBorrow>;
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause;
}
impl MutabilityCategory {
pub fn from_mutbl(m: ast::Mutability) -> MutabilityCategory {
loop { }
}
pub fn from_borrow_kind(borrow_kind: ty::BorrowKind)
-> MutabilityCategory {
loop { }
}
pub fn from_pointer_kind(base_mutbl: MutabilityCategory,
ptr: PointerKind) -> MutabilityCategory {
loop { }
}
fn from_local(tcx: &ty::ctxt, id: ast::NodeId)
-> MutabilityCategory {
loop { }
}
pub fn inherit(&self) -> MutabilityCategory { loop { } }
pub fn is_mutable(&self) -> bool { loop { } }
pub fn is_immutable(&self) -> bool { loop { } }
pub fn to_user_str(&self) -> &'static str { loop { } }
}
impl <'t, 'tcx, TYPER: Typer<'tcx>>
MemCategorizationContext<'t, TYPER> {
pub fn new(typer: &'t TYPER)
-> MemCategorizationContext<'t, TYPER> {
loop { }
}
fn tcx(&self) -> &'t ty::ctxt<'tcx> { loop { } }
fn expr_ty(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
loop { }
}
fn expr_ty_adjusted(&self, expr: &ast::Expr)
-> McResult<Ty<'tcx>> {
loop { }
}
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
loop { }
}
fn pat_ty(&self, pat: &ast::Pat) -> McResult<Ty<'tcx>> {
loop { }
}
pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
loop { }
}
pub fn cat_expr_autoderefd(&self, expr: &ast::Expr,
autoderefs: uint)
-> McResult<cmt<'tcx>> {
loop { }
}
pub fn cat_expr_unadjusted(&self, expr: &ast::Expr)
-> McResult<cmt<'tcx>> {
loop { }
}
pub fn cat_def(&self, id: ast::NodeId, span: Span,
expr_ty: Ty<'tcx>, def: def::Def)
-> McResult<cmt<'tcx>> {
loop { }
}
fn cat_upvar(&self, id: ast::NodeId, span: Span,
var_id: ast::NodeId, fn_node_id: ast::NodeId,
kind: ty::UnboxedClosureKind,
mode: ast::CaptureClause, is_unboxed: bool)
-> McResult<cmt<'tcx>> {
loop { }
}
pub fn cat_rvalue_node(&self, id: ast::NodeId, span: Span,
expr_ty: Ty<'tcx>) -> cmt<'tcx> {
loop { }
}
pub fn cat_rvalue(&self, cmt_id: ast::NodeId, span: Span,
temp_scope: ty::Region, expr_ty: Ty<'tcx>)
-> cmt<'tcx> {
loop { }
}
pub fn cat_field<N: ast_node>(&self, node: &N,
base_cmt: cmt<'tcx>,
f_name: ast::Name, f_ty: Ty<'tcx>)
-> cmt<'tcx> {
loop { }
}
pub fn cat_tup_field<N: ast_node>(&self, node: &N,
base_cmt: cmt<'tcx>,
f_idx: uint, f_ty: Ty<'tcx>)
-> cmt<'tcx> {
loop { }
}
fn cat_deref<N: ast_node>(&self, node: &N, base_cmt: cmt<'tcx>,
deref_cnt: uint)
-> McResult<cmt<'tcx>> {
loop { }
}
fn cat_deref_common<N: ast_node>(&self, node: &N,
base_cmt: cmt<'tcx>,
deref_cnt: uint,
deref_ty: Ty<'tcx>,
implicit: bool)
-> McResult<cmt<'tcx>> {
loop { }
}
pub fn cat_index<N: ast_node>(&self, elt: &N,
mut base_cmt: cmt<'tcx>)
-> McResult<cmt<'tcx>> {
//! Creates a cmt for an indexing operation (`[]`).
//!
//! One subtle aspect of indexing that may not be
//! immediately obvious: for anything other than a fixed-length
//! vector, an operation like `x[y]` actually consists of two
//! disjoint (from the point of view of borrowck) operations.
//! The first is a deref of `x` to create a pointer `p` that points
//! at the first element in the array. The second operation is
//! an index which adds `y*sizeof(T)` to `p` to obtain the
//! pointer to `x[y]`. `cat_index` will produce a resulting
//! cmt containing both this deref and the indexing,
//! presuming that `base_cmt` is not of fixed-length type.
//!
//! # Parameters
//! - `elt`: the AST node being indexed
//! - `base_cmt`: the cmt of `elt`
loop { }
}
fn deref_vec<N: ast_node>(&self, elt: &N, base_cmt: cmt<'tcx>)
-> McResult<cmt<'tcx>> {
loop { }
}
/// Given a pattern P like: `[_, ..Q, _]`, where `vec_cmt` is the cmt for `P`, `slice_pat` is
/// the pattern `Q`, returns:
///
/// * a cmt for `Q`
/// * the mutability and region of the slice `Q`
///
/// These last two bits of info happen to be things that borrowck needs.
pub fn cat_slice_pattern(&self, vec_cmt: cmt<'tcx>,
slice_pat: &ast::Pat)
-> McResult<(cmt<'tcx>, ast::Mutability, ty::Region)> {
loop { }
}
pub fn cat_imm_interior<N: ast_node>(&self, node: &N,
base_cmt: cmt<'tcx>,
interior_ty: Ty<'tcx>,
interior: InteriorKind)
-> cmt<'tcx> {
loop { }
}
pub fn cat_downcast<N: ast_node>(&self, node: &N,
base_cmt: cmt<'tcx>,
downcast_ty: Ty<'tcx>,
variant_did: ast::DefId)
-> cmt<'tcx> {
loop { }
}
pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat,
mut op: F) -> McResult<()> where
F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>,
&ast::Pat) {
loop { }
}
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat,
op: &mut F) -> McResult<()> where
F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>,
&ast::Pat) {
loop { }
}
fn overloaded_method_return_ty(&self, method_ty: Ty<'tcx>)
-> Ty<'tcx> {
loop { }
}
}
#[derive(Copy)]
pub enum InteriorSafety { InteriorUnsafe, InteriorSafe, }
#[derive(Copy)]
pub enum AliasableReason {
AliasableBorrowed,
AliasableClosure(ast::NodeId),
AliasableOther,
AliasableStatic(InteriorSafety),
AliasableStaticMut(InteriorSafety),
}
impl <'tcx> cmt_<'tcx> {
pub fn guarantor(&self) -> cmt<'tcx> {
//! Returns `self` after stripping away any owned pointer derefs or
//! interior content. The return value is basically the `cmt` which
//! determines how long the value in `self` remains live.
loop { }
}
/// Returns `Some(_)` if this lvalue represents a freely aliasable pointer type.
pub fn freely_aliasable(&self, ctxt: &ty::ctxt<'tcx>)
-> Option<AliasableReason> {
loop { }
}
pub fn upvar(&self) -> Option<cmt<'tcx>> { loop { } }
pub fn descriptive_string(&self, tcx: &ty::ctxt) -> String {
loop { }
}
}
impl <'tcx> Repr<'tcx> for cmt_<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for categorization<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
pub fn ptr_sigil(ptr: PointerKind) -> &'static str { loop { } }
impl <'tcx> Repr<'tcx> for PointerKind {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for InteriorKind {
fn repr(&self, _tcx: &ty::ctxt) -> String { loop { } }
}
fn element_kind(t: Ty) -> ElementKind { loop { } }
impl <'tcx> Repr<'tcx> for ty::UnboxedClosureKind {
fn repr(&self, _: &ty::ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for Upvar {
fn repr(&self, tcx: &ty::ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for Upvar {
fn user_string(&self, _: &ty::ctxt) -> String { loop { } }
}
}
pub mod pat_util {
use middle::def::*;
use middle::ty;
use util::nodemap::FnvHashMap;
use syntax::ast;
use syntax::ast_util::{walk_pat};
use syntax::codemap::{Span, DUMMY_SP};
pub type PatIdMap = FnvHashMap<ast::Ident, ast::NodeId>;
pub fn pat_id_map(dm: &DefMap, pat: &ast::Pat) -> PatIdMap {
loop { }
}
pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
loop { }
}
pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
loop { }
}
pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool { loop { } }
pub fn pat_is_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
loop { }
}
pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {
loop { }
}
/// Call `it` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn pat_bindings<I>(dm: &DefMap, pat: &ast::Pat, mut it: I) where
I: FnMut(ast::BindingMode, ast::NodeId, Span, &ast::SpannedIdent) {
loop { }
}
/// Checks if the pattern contains any patterns that bind something to
/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`.
pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
loop { }
}
pub fn simple_identifier<'a>(pat: &'a ast::Pat)
-> Option<&'a ast::Ident> {
loop { }
}
pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
loop { }
}
}
pub mod privacy {
//! A pass that checks to make sure private fields and methods aren't used
//! outside their scopes. This pass will also generate a set of exported items
//! which are available for use externally when compiled as a library.
pub use self::PrivateDep::*;
pub use self::ImportUse::*;
pub use self::LastPrivate::*;
use self::PrivacyResult::*;
use self::FieldName::*;
use std::mem::replace;
use metadata::csearch;
use middle::def;
use middle::ty::{self, Ty};
use middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam,
MethodTypeParam};
use middle::ty::{MethodStatic, MethodStaticUnboxedClosure,
MethodObject, MethodTraitObject};
use util::nodemap::{DefIdSet, NodeMap, NodeSet};
use syntax::{ast, ast_map};
use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::visit::{self, Visitor};
type Context<'a, 'tcx> = (&'a MethodMap<'tcx>, &'a def::ExportMap);
/// A set of AST nodes exported by the crate.
pub type ExportedItems = NodeSet;
/// A set containing all exported definitions from external crates.
/// The set does not contain any entries from local crates.
pub type ExternalExports = DefIdSet;
/// A set of AST nodes that are fully public in the crate. This map is used for
/// documentation purposes (reexporting a private struct inlines the doc,
/// reexporting a public struct doesn't inline the doc).
pub type PublicItems = NodeSet;
pub type LastPrivateMap = NodeMap<LastPrivate>;
#[derive(Copy, Show)]
pub enum LastPrivate {
LastMod(PrivateDep),
LastImport {
value_priv: Option<PrivateDep>,
value_used: ImportUse,
type_priv: Option<PrivateDep>,
type_used: ImportUse,
},
}
#[derive(Copy, Show)]
pub enum PrivateDep { AllPublic, DependsOn(ast::DefId), }
#[derive(Copy, PartialEq, Show)]
pub enum ImportUse { Unused, Used, }
impl LastPrivate {
pub fn or(self, other: LastPrivate) -> LastPrivate { loop { } }
}
/// Result of a checking operation - None => no errors were found. Some => an
/// error and contains the span and message for reporting that error and
/// optionally the same for a note about the error.
type CheckResult = Option<(Span, String, Option<(Span, String)>)>;
/// The parent visitor, used to determine what's the parent of what (node-wise)
struct ParentVisitor {
parents: NodeMap<ast::NodeId>,
curparent: ast::NodeId,
}
impl <'v> Visitor<'v> for ParentVisitor {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
loop { }
}
fn visit_fn(&mut self, a: visit::FnKind<'v>, b: &'v ast::FnDecl,
c: &'v ast::Block, d: Span, id: ast::NodeId) {
loop { }
}
fn visit_struct_def(&mut self, s: &ast::StructDef, _: ast::Ident,
_: &'v ast::Generics, n: ast::NodeId) {
loop { }
}
}
/// The embargo visitor, used to determine the exports of the ast
struct EmbargoVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
export_map: &'a def::ExportMap,
prev_exported: bool,
exported_items: ExportedItems,
reexports: NodeSet,
public_items: PublicItems,
prev_public: bool,
}
impl <'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
fn exported_trait(&self, _id: ast::NodeId) -> bool { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
loop { }
}
fn visit_mod(&mut self, m: &ast::Mod, _sp: Span,
id: ast::NodeId) {
loop { }
}
}
/// The privacy visitor, where privacy checks take place (violations reported)
struct PrivacyVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
curitem: ast::NodeId,
in_foreign: bool,
parents: NodeMap<ast::NodeId>,
external_exports: ExternalExports,
last_private_map: LastPrivateMap,
}
enum PrivacyResult {
Allowable,
ExternallyDenied,
DisallowedBy(ast::NodeId),
}
enum FieldName { UnnamedField(uint), NamedField(ast::Ident), }
impl <'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
fn nodestr(&self, id: ast::NodeId) -> String { loop { } }
fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
loop { }
}
/// For a local private node in the AST, this function will determine
/// whether the node is accessible by the current module that iteration is
/// inside.
fn private_accessible(&self, id: ast::NodeId) -> bool {
loop { }
}
fn report_error(&self, result: CheckResult) -> bool { loop { } }
/// Guarantee that a particular definition is public. Returns a CheckResult
/// which contains any errors found. These can be reported using `report_error`.
/// If the result is `None`, no errors were found.
fn ensure_public(&self, span: Span, to_check: ast::DefId,
source_did: Option<ast::DefId>, msg: &str)
-> CheckResult {
loop { }
}
fn check_field(&mut self, span: Span, id: ast::DefId,
name: FieldName) {
loop { }
}
fn check_static_method(&mut self, span: Span,
method_id: ast::DefId, name: ast::Ident) {
loop { }
}
fn check_path(&mut self, span: Span, path_id: ast::NodeId,
path: &ast::Path) {
loop { }
}
fn check_method(&mut self, span: Span, origin: &MethodOrigin,
ident: ast::Ident) {
loop { }
}
}
impl <'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_expr(&mut self, expr: &ast::Expr) { loop { } }
fn visit_view_item(&mut self, a: &ast::ViewItem) { loop { } }
fn visit_pat(&mut self, pattern: &ast::Pat) { loop { } }
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
loop { }
}
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
loop { }
}
}
/// The privacy sanity check visitor, ensures unnecessary visibility isn't here
struct SanePrivacyVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
in_fn: bool,
}
impl <'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) {
loop { }
}
fn visit_view_item(&mut self, i: &ast::ViewItem) { loop { } }
}
impl <'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
/// Validates all of the visibility qualifiers placed on the item given. This
/// ensures that there are no extraneous qualifiers that don't actually do
/// anything. In theory these qualifiers wouldn't parse, but that may happen
/// later on down the road...
fn check_sane_privacy(&self, item: &ast::Item) { loop { } }
/// When inside of something like a function or a method, visibility has no
/// control over anything so this forbids any mention of any visibility
fn check_all_inherited(&self, item: &ast::Item) { loop { } }
}
struct VisiblePrivateTypesVisitor<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
exported_items: &'a ExportedItems,
public_items: &'a PublicItems,
in_variant: bool,
}
struct CheckTypeForPrivatenessVisitor<'a, 'b:'a, 'tcx:'b> {
inner: &'a VisiblePrivateTypesVisitor<'b, 'tcx>,
/// whether the type refers to private types.
contains_private: bool,
/// whether we've recurred at all (i.e. if we're pointing at the
/// first type on which visit_ty was called).
at_outer_type: bool,
outer_type_is_public_path: bool,
}
impl <'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
loop { }
}
fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
loop { }
}
fn check_ty_param_bound(&self,
ty_param_bound: &ast::TyParamBound) {
loop { }
}
}
impl <'a, 'b, 'tcx, 'v> Visitor<'v> for
CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) { loop { } }
fn visit_expr(&mut self, _: &ast::Expr) { loop { } }
}
impl <'a, 'tcx, 'v> Visitor<'v> for
VisiblePrivateTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_generics(&mut self, generics: &ast::Generics) {
loop { }
}
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
loop { }
}
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, id: ast::NodeId) {
loop { }
}
fn visit_ty(&mut self, t: &ast::Ty) { loop { } }
fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
loop { }
}
fn visit_struct_field(&mut self, s: &ast::StructField) {
loop { }
}
fn visit_view_item(&mut self, _: &ast::ViewItem) { loop { } }
fn visit_block(&mut self, _: &ast::Block) { loop { } }
fn visit_expr(&mut self, _: &ast::Expr) { loop { } }
}
pub fn check_crate(tcx: &ty::ctxt, export_map: &def::ExportMap,
external_exports: ExternalExports,
last_private_map: LastPrivateMap)
-> (ExportedItems, PublicItems) {
loop { }
}
}
pub mod reachable {
use middle::def;
use middle::ty;
use middle::privacy;
use session::config;
use util::nodemap::NodeSet;
use std::collections::HashSet;
use syntax::abi;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::{is_local, PostExpansionMethod};
use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone};
use syntax::attr;
use syntax::visit::Visitor;
use syntax::visit;
fn attributes_specify_inlining(attrs: &[ast::Attribute]) -> bool {
loop { }
}
fn generics_require_inlining(generics: &ast::Generics) -> bool {
loop { }
}
fn item_might_be_inlined(item: &ast::Item) -> bool { loop { } }
fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
impl_src: ast::DefId) -> bool {
loop { }
}
struct ReachableContext<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
reachable_symbols: NodeSet,
worklist: Vec<ast::NodeId>,
any_library: bool,
}
impl <'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr) { loop { } }
fn visit_item(&mut self, _item: &ast::Item) { loop { } }
}
impl <'a, 'tcx> ReachableContext<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>) -> ReachableContext<'a, 'tcx> {
loop { }
}
fn def_id_represents_local_inlined_item(&self, def_id: ast::DefId)
-> bool {
loop { }
}
fn propagate(&mut self) { loop { } }
fn propagate_node(&mut self, node: &ast_map::Node,
search_item: ast::NodeId) {
loop { }
}
fn mark_destructors_reachable(&mut self) { loop { } }
}
pub fn find_reachable(tcx: &ty::ctxt,
exported_items: &privacy::ExportedItems)
-> NodeSet {
loop { }
}
}
pub mod region {
//! This file actually contains two passes related to regions. The first
//! pass builds up the `scope_map`, which describes the parent links in
//! the region hierarchy. The second pass infers which types must be
//! region parameterized.
//!
//! Most of the documentation on regions can be found in
//! `middle/typeck/infer/region_inference.rs`
use session::Session;
use middle::ty::{self, Ty, FreeRegion};
use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
use util::common::can_reach;
use std::cell::RefCell;
use std::hash::{Hash};
use syntax::codemap::Span;
use syntax::{ast, visit};
use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr,
Local};
use syntax::ast_util::{stmt_id};
use syntax::visit::{Visitor, FnKind};
/// CodeExtent represents a statically-describable extent that can be
/// used to bound the lifetime/region for values.
///
/// FIXME (pnkfelix): This currently derives `PartialOrd` and `Ord` to
/// placate the same deriving in `ty::FreeRegion`, but we may want to
/// actually attach a more meaningful ordering to scopes than the one
/// generated via deriving here.
#[derive(Clone,
PartialEq,
PartialOrd,
Eq,
Ord,
Hash,
RustcEncodable,
RustcDecodable,
Show,
Copy)]
pub enum CodeExtent { Misc(ast::NodeId), }
impl CodeExtent {
/// Creates a scope that represents the dynamic extent associated
/// with `node_id`.
pub fn from_node_id(node_id: ast::NodeId) -> CodeExtent {
loop { }
}
/// Returns a node id associated with this scope.
///
/// NB: likely to be replaced as API is refined; e.g. pnkfelix
/// anticipates `fn entry_node_id` and `fn each_exit_node_id`.
pub fn node_id(&self) -> ast::NodeId { loop { } }
/// Maps this scope to a potentially new one according to the
/// NodeId transformer `f_id`.
pub fn map_id<F>(&self, f_id: F) -> CodeExtent where
F: FnOnce(ast::NodeId) -> ast::NodeId {
loop { }
}
}
/// The region maps encode information about region relationships.
///
/// - `scope_map` maps from a scope id to the enclosing scope id; this is
/// usually corresponding to the lexical nesting, though in the case of
/// closures the parent scope is the innermost conditional expression or repeating
/// block
///
/// - `var_map` maps from a variable or binding id to the block in which
/// that variable is declared.
///
/// - `free_region_map` maps from a free region `a` to a list of free
/// regions `bs` such that `a <= b for all b in bs`
/// - the free region map is populated during type check as we check
/// each function. See the function `relate_free_regions` for
/// more information.
///
/// - `rvalue_scopes` includes entries for those expressions whose cleanup
/// scope is larger than the default. The map goes from the expression
/// id to the cleanup scope id. For rvalues not present in this table,
/// the appropriate cleanup scope is the innermost enclosing statement,
/// conditional expression, or repeating block (see `terminating_scopes`).
///
/// - `terminating_scopes` is a set containing the ids of each statement,
/// or conditional/repeating expression. These scopes are calling "terminating
/// scopes" because, when attempting to find the scope of a temporary, by
/// default we search up the enclosing scopes until we encounter the
/// terminating scope. A conditional/repeating
/// expression is one which is not guaranteed to execute exactly once
/// upon entering the parent scope. This could be because the expression
/// only executes conditionally, such as the expression `b` in `a && b`,
/// or because the expression may execute many times, such as a loop
/// body. The reason that we distinguish such expressions is that, upon
/// exiting the parent scope, we cannot statically know how many times
/// the expression executed, and thus if the expression creates
/// temporaries we cannot know statically how many such temporaries we
/// would have to cleanup. Therefore we ensure that the temporaries never
/// outlast the conditional/repeating expression, preventing the need
/// for dynamic checks and/or arbitrary amounts of stack space.
pub struct RegionMaps {
scope_map: RefCell<FnvHashMap<CodeExtent, CodeExtent>>,
var_map: RefCell<NodeMap<CodeExtent>>,
free_region_map: RefCell<FnvHashMap<FreeRegion, Vec<FreeRegion>>>,
rvalue_scopes: RefCell<NodeMap<CodeExtent>>,
terminating_scopes: RefCell<FnvHashSet<CodeExtent>>,
}
#[derive(Copy)]
pub struct Context {
var_parent: Option<ast::NodeId>,
parent: Option<ast::NodeId>,
}
struct RegionResolutionVisitor<'a> {
sess: &'a Session,
region_maps: &'a RegionMaps,
cx: Context,
}
impl RegionMaps {
pub fn relate_free_regions(&self, sub: FreeRegion,
sup: FreeRegion) {
loop { }
}
pub fn record_encl_scope(&self, sub: CodeExtent,
sup: CodeExtent) {
loop { }
}
pub fn record_var_scope(&self, var: ast::NodeId,
lifetime: CodeExtent) {
loop { }
}
pub fn record_rvalue_scope(&self, var: ast::NodeId,
lifetime: CodeExtent) {
loop { }
}
/// Records that a scope is a TERMINATING SCOPE. Whenever we create automatic temporaries --
/// e.g. by an expression like `a().f` -- they will be freed within the innermost terminating
/// scope.
pub fn mark_as_terminating_scope(&self, scope_id: CodeExtent) {
loop { }
}
pub fn opt_encl_scope(&self, id: CodeExtent)
-> Option<CodeExtent> {
//! Returns the narrowest scope that encloses `id`, if any.
loop { }
}
#[allow(dead_code)]
pub fn encl_scope(&self, id: CodeExtent) -> CodeExtent {
//! Returns the narrowest scope that encloses `id`, if any.
loop { }
}
/// Returns the lifetime of the local variable `var_id`
pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent {
loop { }
}
pub fn temporary_scope(&self, expr_id: ast::NodeId)
-> Option<CodeExtent> {
//! Returns the scope when temp created by expr_id will be cleaned up
loop { }
}
pub fn var_region(&self, id: ast::NodeId) -> ty::Region {
//! Returns the lifetime of the variable `id`.
loop { }
}
pub fn scopes_intersect(&self, scope1: CodeExtent,
scope2: CodeExtent) -> bool {
loop { }
}
/// Returns true if `subscope` is equal to or is lexically nested inside `superscope` and false
/// otherwise.
pub fn is_subscope_of(&self, subscope: CodeExtent,
superscope: CodeExtent) -> bool {
loop { }
}
/// Determines whether two free regions have a subregion relationship
/// by walking the graph encoded in `free_region_map`. Note that
/// it is possible that `sub != sup` and `sub <= sup` and `sup <= sub`
/// (that is, the user can give two different names to the same lifetime).
pub fn sub_free_region(&self, sub: FreeRegion, sup: FreeRegion)
-> bool {
loop { }
}
/// Determines whether one region is a subregion of another. This is intended to run *after
/// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
pub fn is_subregion_of(&self, sub_region: ty::Region,
super_region: ty::Region) -> bool {
loop { }
}
/// Finds the nearest common ancestor (if any) of two scopes. That is, finds the smallest
/// scope which is greater than or equal to both `scope_a` and `scope_b`.
pub fn nearest_common_ancestor(&self, scope_a: CodeExtent,
scope_b: CodeExtent)
-> Option<CodeExtent> {
loop { }
}
}
/// Records the current parent (if any) as the parent of `child_id`.
fn record_superlifetime(visitor: &mut RegionResolutionVisitor,
child_id: ast::NodeId, _sp: Span) {
loop { }
}
/// Records the lifetime of a local variable as `cx.var_parent`
fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
var_id: ast::NodeId, _sp: Span) {
loop { }
}
fn resolve_block(visitor: &mut RegionResolutionVisitor,
blk: &ast::Block) {
loop { }
}
fn resolve_arm(visitor: &mut RegionResolutionVisitor,
arm: &ast::Arm) {
loop { }
}
fn resolve_pat(visitor: &mut RegionResolutionVisitor,
pat: &ast::Pat) {
loop { }
}
fn resolve_stmt(visitor: &mut RegionResolutionVisitor,
stmt: &ast::Stmt) {
loop { }
}
fn resolve_expr(visitor: &mut RegionResolutionVisitor,
expr: &ast::Expr) {
loop { }
}
fn resolve_local(visitor: &mut RegionResolutionVisitor,
local: &ast::Local) {
loop { }
}
fn resolve_item(visitor: &mut RegionResolutionVisitor,
item: &ast::Item) {
loop { }
}
fn resolve_fn(visitor: &mut RegionResolutionVisitor, fk: FnKind,
decl: &ast::FnDecl, body: &ast::Block, sp: Span,
id: ast::NodeId) {
loop { }
}
impl <'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
fn visit_block(&mut self, b: &Block) { loop { } }
fn visit_item(&mut self, i: &Item) { loop { } }
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, n: NodeId) {
loop { }
}
fn visit_arm(&mut self, a: &Arm) { loop { } }
fn visit_pat(&mut self, p: &Pat) { loop { } }
fn visit_stmt(&mut self, s: &Stmt) { loop { } }
fn visit_expr(&mut self, ex: &Expr) { loop { } }
fn visit_local(&mut self, l: &Local) { loop { } }
}
pub fn resolve_crate(sess: &Session, krate: &ast::Crate)
-> RegionMaps {
loop { }
}
pub fn resolve_inlined_item(sess: &Session, region_maps: &RegionMaps,
item: &ast::InlinedItem) {
loop { }
}
}
pub mod recursion_limit {
use session::Session;
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use std::str::FromStr;
pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) {
loop { }
}
}
pub mod resolve_lifetime {
//! Name resolution for lifetimes.
//!
//! Name resolution for lifetimes follows MUCH simpler rules than the
//! full resolve. For example, lifetime names are never exported or
//! used between functions, and they operate in a purely top-down
//! way. Therefore we break lifetime name resolution into a separate pass.
pub use self::DefRegion::*;
use self::ScopeChain::*;
use session::Session;
use middle::def::{self, DefMap};
use middle::region;
use middle::subst;
use middle::ty;
use std::fmt;
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token::special_idents;
use syntax::parse::token;
use syntax::print::pprust::{lifetime_to_string};
use syntax::visit;
use syntax::visit::Visitor;
use util::nodemap::NodeMap;
#[derive(Clone,
Copy,
PartialEq,
Eq,
Hash,
RustcEncodable,
RustcDecodable,
Show)]
pub enum DefRegion {
DefStaticRegion,
DefEarlyBoundRegion(subst::ParamSpace, u32, ast::NodeId),
DefLateBoundRegion(ty::DebruijnIndex, ast::NodeId),
DefFreeRegion(region::CodeExtent, ast::NodeId),
}
pub type NamedRegionMap = NodeMap<DefRegion>;
struct LifetimeContext<'a> {
sess: &'a Session,
named_region_map: &'a mut NamedRegionMap,
scope: Scope<'a>,
def_map: &'a DefMap,
}
enum ScopeChain<'a> {
/// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
/// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
EarlyScope(subst::ParamSpace,
&'a Vec<ast::LifetimeDef>,
Scope<'a>),
/// LateScope(['a, 'b, ...], s) extends s with late-bound
/// lifetimes introduced by the declaration binder_id.
LateScope(&'a Vec<ast::LifetimeDef>, Scope<'a>),
/// lifetimes introduced by items within a code block are scoped
/// to that block.
BlockScope(region::CodeExtent, Scope<'a>),
RootScope,
}
type Scope<'a> = &'a ScopeChain<'a>;
static ROOT_SCOPE: ScopeChain<'static> = RootScope;
pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap)
-> NamedRegionMap {
loop { }
}
impl <'a, 'v> Visitor<'v> for LifetimeContext<'a> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) {
loop { }
}
fn visit_ty(&mut self, ty: &ast::Ty) { loop { } }
fn visit_ty_method(&mut self, m: &ast::TypeMethod) { loop { } }
fn visit_block(&mut self, b: &ast::Block) { loop { } }
fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
loop { }
}
fn visit_generics(&mut self, generics: &ast::Generics) {
loop { }
}
fn visit_poly_trait_ref(&mut self, trait_ref: &ast::PolyTraitRef,
_modifier: &ast::TraitBoundModifier) {
loop { }
}
fn visit_trait_ref(&mut self, trait_ref: &ast::TraitRef) {
loop { }
}
}
impl <'a> LifetimeContext<'a> {
fn with<F>(&mut self, wrap_scope: ScopeChain, f: F) where
F: FnOnce(Scope, &mut LifetimeContext) {
loop { }
}
/// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
///
/// Handles visiting fns and methods. These are a bit complicated because we must distinguish
/// early- vs late-bound lifetime parameters. We do this by checking which lifetimes appear
/// within type bounds; those are early bound lifetimes, and the rest are late bound.
///
/// For example:
///
/// fn foo<'a,'b,'c,T:Trait<'b>>(...)
///
/// Here `'a` and `'c` are late bound but `'b` is early bound. Note that early- and late-bound
/// lifetimes may be interspersed together.
///
/// If early bound lifetimes are present, we separate them into their own list (and likewise
/// for late bound). They will be numbered sequentially, starting from the lowest index that is
/// already in scope (for a fn item, that will be 0, but for a method it might not be). Late
/// bound lifetimes are resolved by name and associated with a binder id (`binder_id`), so the
/// ordering is not important there.
fn visit_early_late<F>(&mut self, early_space: subst::ParamSpace,
generics: &ast::Generics, walk: F) where
F: FnOnce(&mut LifetimeContext) {
loop { }
}
fn resolve_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
loop { }
}
fn resolve_free_lifetime_ref(&mut self,
scope_data: region::CodeExtent,
lifetime_ref: &ast::Lifetime,
scope: Scope) {
loop { }
}
fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
loop { }
}
fn check_lifetime_defs(&mut self, old_scope: Scope,
lifetimes: &Vec<ast::LifetimeDef>) {
loop { }
}
fn check_lifetime_def_for_shadowing(&self, mut old_scope: Scope,
lifetime: &ast::Lifetime) {
loop { }
}
fn insert_lifetime(&mut self, lifetime_ref: &ast::Lifetime,
def: DefRegion) {
loop { }
}
}
fn search_lifetimes<'a>(lifetimes: &'a Vec<ast::LifetimeDef>,
lifetime_ref: &ast::Lifetime)
-> Option<(u32, &'a ast::Lifetime)> {
loop { }
}
pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics)
-> Vec<ast::LifetimeDef> {
loop { }
}
/// Given a set of generic declarations, returns a list of names containing all early bound
/// lifetime names for those generics. (In fact, this list may also contain other names.)
fn early_bound_lifetime_names(generics: &ast::Generics)
-> Vec<ast::Name> {
loop { }
}
impl <'a> fmt::Show for ScopeChain<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
loop { }
}
}
}
pub mod stability {
//! A pass that annotates every item and method with its stability level,
//! propagating default levels lexically from parent to children ast nodes.
use middle::ty;
use metadata::csearch;
use syntax::codemap::Span;
use syntax::{attr, visit};
use syntax::ast;
use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId,
Variant};
use syntax::ast::{Item, RequiredMethod, ProvidedMethod, TraitItem};
use syntax::ast::{TypeMethod, Method, Generics, StructField,
TypeTraitItem};
use syntax::ast_util::is_local;
use syntax::attr::Stability;
use syntax::visit::{FnKind, FkMethod, Visitor};
use util::nodemap::{NodeMap, DefIdMap};
use util::ppaux::Repr;
use std::mem::replace;
/// A stability index, giving the stability level for items and methods.
pub struct Index {
local: NodeMap<Stability>,
extern_cache: DefIdMap<Option<Stability>>,
}
struct Annotator {
index: Index,
parent: Option<Stability>,
}
impl Annotator {
fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
attrs: &Vec<Attribute>, f: F) where
F: FnOnce(&mut Annotator) {
loop { }
}
}
impl <'v> Visitor<'v> for Annotator {
fn visit_item(&mut self, i: &Item) { loop { } }
fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
_: &'v Block, _: Span, _: NodeId) {
loop { }
}
fn visit_trait_item(&mut self, t: &TraitItem) { loop { } }
fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
loop { }
}
fn visit_struct_field(&mut self, s: &StructField) { loop { } }
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
loop { }
}
}
impl Index {
/// Construct the stability index for a crate being compiled.
pub fn build(krate: &Crate) -> Index { loop { } }
}
/// Lookup the stability for a node, loading external crate
/// metadata as necessary.
pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option<Stability> {
loop { }
}
pub fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool { loop { } }
}
pub mod subst {
pub use self::ParamSpace::*;
pub use self::RegionSubsts::*;
use middle::ty::{self, Ty};
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
use util::ppaux::Repr;
use std::fmt;
use std::slice::Iter;
use std::vec::Vec;
use syntax::codemap::{Span, DUMMY_SP};
/// A substitution mapping type/region parameters to new values. We
/// identify each in-scope parameter by an *index* and a *parameter
/// space* (which indices where the parameter is defined; see
/// `ParamSpace`).
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct Substs<'tcx> {
pub types: VecPerParamSpace<Ty<'tcx>>,
pub regions: RegionSubsts,
}
/// Represents the values to use when substituting lifetime parameters.
/// If the value is `ErasedRegions`, then this subst is occurring during
/// trans, and all region parameters will be replaced with `ty::ReStatic`.
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub enum RegionSubsts {
ErasedRegions,
NonerasedRegions(VecPerParamSpace<ty::Region>),
}
impl <'tcx> Substs<'tcx> {
pub fn new(t: VecPerParamSpace<Ty<'tcx>>,
r: VecPerParamSpace<ty::Region>) -> Substs<'tcx> {
loop { }
}
pub fn new_type(t: Vec<Ty<'tcx>>, r: Vec<ty::Region>)
-> Substs<'tcx> {
loop { }
}
pub fn new_trait(t: Vec<Ty<'tcx>>, r: Vec<ty::Region>,
s: Ty<'tcx>) -> Substs<'tcx> {
loop { }
}
pub fn erased(t: VecPerParamSpace<Ty<'tcx>>) -> Substs<'tcx> {
loop { }
}
pub fn empty() -> Substs<'tcx> { loop { } }
pub fn trans_empty() -> Substs<'tcx> { loop { } }
pub fn is_noop(&self) -> bool { loop { } }
pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef)
-> Ty<'tcx> {
loop { }
}
pub fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
pub fn self_ty(&self) -> Option<Ty<'tcx>> { loop { } }
pub fn with_self_ty(&self, self_ty: Ty<'tcx>) -> Substs<'tcx> {
loop { }
}
pub fn erase_regions(self) -> Substs<'tcx> { loop { } }
/// Since ErasedRegions are only to be used in trans, most of the compiler can use this method
/// to easily access the set of region substitutions.
pub fn regions<'a>(&'a self) -> &'a VecPerParamSpace<ty::Region> {
loop { }
}
/// Since ErasedRegions are only to be used in trans, most of the compiler can use this method
/// to easily access the set of region substitutions.
pub fn mut_regions<'a>(&'a mut self)
-> &'a mut VecPerParamSpace<ty::Region> {
loop { }
}
pub fn with_method(self, m_types: Vec<Ty<'tcx>>,
m_regions: Vec<ty::Region>) -> Substs<'tcx> {
loop { }
}
}
impl RegionSubsts {
fn map<A, F>(self, a: A, op: F) -> RegionSubsts where
F: FnOnce(VecPerParamSpace<ty::Region>, A) ->
VecPerParamSpace<ty::Region> {
loop { }
}
pub fn is_erased(&self) -> bool { loop { } }
}
#[derive(PartialOrd,
Ord,
PartialEq,
Eq,
Copy,
Clone,
Hash,
RustcEncodable,
RustcDecodable,
Show)]
pub enum ParamSpace { TypeSpace, SelfSpace, FnSpace, }
impl ParamSpace {
pub fn all() -> [ParamSpace; 3] { loop { } }
pub fn to_uint(self) -> uint { loop { } }
pub fn from_uint(u: uint) -> ParamSpace { loop { } }
}
/// Vector of things sorted by param space. Used to keep
/// the set of things declared on the type, self, or method
/// distinct.
#[derive(PartialEq, Eq, Clone, Hash, RustcEncodable, RustcDecodable)]
pub struct VecPerParamSpace<T> {
type_limit: uint,
self_limit: uint,
content: Vec<T>,
}
/// The `split` function converts one `VecPerParamSpace` into this
/// `SeparateVecsPerParamSpace` structure.
pub struct SeparateVecsPerParamSpace<T> {
pub types: Vec<T>,
pub selfs: Vec<T>,
pub fns: Vec<T>,
}
impl <T: fmt::Show> fmt::Show for VecPerParamSpace<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
loop { }
}
}
impl <T> VecPerParamSpace<T> {
fn limits(&self, space: ParamSpace) -> (uint, uint) { loop { } }
pub fn empty() -> VecPerParamSpace<T> { loop { } }
pub fn params_from_type(types: Vec<T>) -> VecPerParamSpace<T> {
loop { }
}
/// `t` is the type space.
/// `s` is the self space.
/// `a` is the assoc space.
/// `f` is the fn space.
pub fn new(t: Vec<T>, s: Vec<T>, f: Vec<T>)
-> VecPerParamSpace<T> {
loop { }
}
fn new_internal(content: Vec<T>, type_limit: uint,
self_limit: uint) -> VecPerParamSpace<T> {
loop { }
}
/// Appends `value` to the vector associated with `space`.
///
/// Unlike the `push` method in `Vec`, this should not be assumed
/// to be a cheap operation (even when amortized over many calls).
pub fn push(&mut self, space: ParamSpace, value: T) { loop { } }
/// Appends `values` to the vector associated with `space`.
///
/// Unlike the `extend` method in `Vec`, this should not be assumed
/// to be a cheap operation (even when amortized over many calls).
pub fn extend<I: Iterator<Item =
T>>(&mut self, space: ParamSpace, mut values: I) {
loop { }
}
pub fn pop(&mut self, space: ParamSpace) -> Option<T> {
loop { }
}
pub fn truncate(&mut self, space: ParamSpace, len: uint) {
loop { }
}
pub fn replace(&mut self, space: ParamSpace, elems: Vec<T>) {
loop { }
}
pub fn get_self<'a>(&'a self) -> Option<&'a T> { loop { } }
pub fn len(&self, space: ParamSpace) -> uint { loop { } }
pub fn is_empty_in(&self, space: ParamSpace) -> bool { loop { } }
pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] {
loop { }
}
pub fn get_mut_slice<'a>(&'a mut self, space: ParamSpace)
-> &'a mut [T] {
loop { }
}
pub fn opt_get<'a>(&'a self, space: ParamSpace, index: uint)
-> Option<&'a T> {
loop { }
}
pub fn get<'a>(&'a self, space: ParamSpace, index: uint)
-> &'a T {
loop { }
}
pub fn iter<'a>(&'a self) -> Iter<'a, T> { loop { } }
pub fn iter_enumerated<'a>(&'a self) -> EnumeratedItems<'a, T> {
loop { }
}
pub fn as_slice(&self) -> &[T] { loop { } }
pub fn into_vec(self) -> Vec<T> { loop { } }
pub fn all_vecs<P>(&self, mut pred: P) -> bool where
P: FnMut(&[T]) -> bool {
loop { }
}
pub fn all<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
loop { }
}
pub fn any<P>(&self, pred: P) -> bool where P: FnMut(&T) -> bool {
loop { }
}
pub fn is_empty(&self) -> bool { loop { } }
pub fn map<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
P: FnMut(&T) -> U {
loop { }
}
pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U>
where P: FnMut((ParamSpace, uint, &T)) -> U {
loop { }
}
pub fn map_move<U, F>(self, mut pred: F) -> VecPerParamSpace<U>
where F: FnMut(T) -> U {
loop { }
}
pub fn split(self) -> SeparateVecsPerParamSpace<T> { loop { } }
pub fn with_vec(mut self, space: ParamSpace, vec: Vec<T>)
-> VecPerParamSpace<T> {
loop { }
}
}
#[derive(Clone)]
pub struct EnumeratedItems<'a, T: 'a> {
vec: &'a VecPerParamSpace<T>,
space_index: uint,
elem_index: uint,
}
impl <'a, T> EnumeratedItems<'a, T> {
fn new(v: &'a VecPerParamSpace<T>) -> EnumeratedItems<'a, T> {
loop { }
}
fn adjust_space(&mut self) { loop { } }
}
impl <'a, T> Iterator for EnumeratedItems<'a, T> {type
Item
=
(ParamSpace, uint, &'a T);
fn next(&mut self) -> Option<(ParamSpace, uint, &'a T)> {
loop { }
}
}
pub trait Subst<'tcx>: Sized {
fn subst(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
-> Self {
loop { }
}
fn subst_spanned
(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>,
span: Option<Span>) -> Self;
}
impl <'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
fn subst_spanned(&self, tcx: &ty::ctxt<'tcx>,
substs: &Substs<'tcx>, span: Option<Span>) -> T {
loop { }
}
}
struct SubstFolder<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
substs: &'a Substs<'tcx>,
span: Option<Span>,
root_ty: Option<Ty<'tcx>>,
ty_stack_depth: uint,
region_binders_passed: u32,
}
impl <'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn enter_region_binder(&mut self) { loop { } }
fn exit_region_binder(&mut self) { loop { } }
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { loop { } }
}
impl <'a, 'tcx> SubstFolder<'a, 'tcx> {
fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>)
-> Ty<'tcx> {
loop { }
}
/// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
/// when we are substituting a type with escaping regions into a context where we have passed
/// through region binders. That's quite a mouthful. Let's see an example:
///
/// ```
/// type Func<A> = fn(A);
/// type MetaFunc = for<'a> fn(Func<&'a int>)
/// ```
///
/// The type `MetaFunc`, when fully expanded, will be
///
/// for<'a> fn(fn(&'a int))
/// ^~ ^~ ^~~
/// | | |
/// | | DebruijnIndex of 2
/// Binders
///
/// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
/// over the inner binder (remember that we count Debruijn indices from 1). However, in the
/// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a
/// debruijn index of 1. It's only during the substitution that we can see we must increase the
/// depth by 1 to account for the binder that we passed through.
///
/// As a second example, consider this twist:
///
/// ```
/// type FuncTuple<A> = (A,fn(A));
/// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>)
/// ```
///
/// Here the final type will be:
///
/// for<'a> fn((&'a int, fn(&'a int)))
/// ^~~ ^~~
/// | |
/// DebruijnIndex of 1 |
/// DebruijnIndex of 2
///
/// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
/// first case we do not increase the Debruijn index and in the second case we do. The reason
/// is that only in the second case have we passed through a fn binder.
fn shift_regions_through_binders(&self, ty: Ty<'tcx>)
-> Ty<'tcx> {
loop { }
}
fn shift_region_through_binders(&self, region: ty::Region)
-> ty::Region {
loop { }
}
}
}
pub mod traits {
//! Trait Resolution. See doc.rs.
pub use self::SelectionError::*;
pub use self::FulfillmentErrorCode::*;
pub use self::Vtable::*;
pub use self::ObligationCauseCode::*;
use middle::mem_categorization::Typer;
use middle::subst;
use middle::ty::{self, Ty};
use middle::infer::InferCtxt;
use std::slice::Iter;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::{Span, DUMMY_SP};
use util::ppaux::{Repr, UserString};
pub use self::error_reporting::report_fulfillment_errors;
pub use self::error_reporting::suggest_new_overflow_limit;
pub use self::coherence::orphan_check;
pub use self::coherence::OrphanCheckErr;
pub use self::fulfill::{FulfillmentContext, RegionObligation};
pub use self::project::MismatchedProjectionTypes;
pub use self::project::normalize;
pub use self::project::Normalized;
pub use self::object_safety::is_object_safe;
pub use self::object_safety::object_safety_violations;
pub use self::object_safety::ObjectSafetyViolation;
pub use self::object_safety::MethodViolationCode;
pub use self::select::SelectionContext;
pub use self::select::SelectionCache;
pub use self::select::{MethodMatchResult, MethodMatched,
MethodAmbiguous, MethodDidNotMatch};
pub use self::select::{MethodMatchedData};
pub use self::util::elaborate_predicates;
pub use self::util::get_vtable_index_of_object_method;
pub use self::util::trait_ref_for_builtin_bound;
pub use self::util::supertraits;
pub use self::util::Supertraits;
pub use self::util::transitive_bounds;
pub use self::util::upcast;
mod coherence {
//! See `doc.rs` for high-level documentation
use super::SelectionContext;
use super::{Obligation, ObligationCause};
use super::project;
use super::util;
use middle::subst::{Subst};
use middle::ty::{self, Ty};
use middle::infer::InferCtxt;
use std::collections::HashSet;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::DUMMY_SP;
use util::ppaux::Repr;
pub fn impl_can_satisfy(infcx: &InferCtxt,
impl1_def_id: ast::DefId,
impl2_def_id: ast::DefId) -> bool {
loop { }
}
#[allow(missing_copy_implementations)]
pub enum OrphanCheckErr<'tcx> {
NoLocalInputType,
UncoveredTy(Ty<'tcx>),
}
/// Checks the coherence orphan rules. `impl_def_id` should be the
/// def-id of a trait impl. To pass, either the trait must be local, or else
/// two conditions must be satisfied:
///
/// 1. All type parameters in `Self` must be "covered" by some local type constructor.
/// 2. Some local type must appear in `Self`.
pub fn orphan_check<'tcx>(tcx: &ty::ctxt<'tcx>,
impl_def_id: ast::DefId)
-> Result<(), OrphanCheckErr<'tcx>> {
loop { }
}
fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
ty: Ty<'tcx>) -> bool {
loop { }
}
fn type_parameters_covered_by_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
ty: Ty<'tcx>)
-> HashSet<Ty<'tcx>> {
loop { }
}
/// All type parameters reachable from `ty`
fn type_parameters_reachable_from_ty<'tcx>(ty: Ty<'tcx>)
-> HashSet<Ty<'tcx>> {
loop { }
}
}
mod error_reporting {
use super::{FulfillmentError, FulfillmentErrorCode,
MismatchedProjectionTypes, ObligationCauseCode,
OutputTypeParameterMismatch, PredicateObligation,
SelectionError};
use fmt_macros::{Parser, Piece, Position};
use middle::infer::InferCtxt;
use middle::ty::{self, AsPredicate, ReferencesError,
ToPolyTraitRef, TraitRef};
use std::collections::HashMap;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::attr::{AttributeMethods, AttrMetaMethods};
use util::ppaux::{Repr, UserString};
pub fn report_fulfillment_errors<'a,
'tcx>(infcx:
&InferCtxt<'a, 'tcx>,
errors:
&Vec<FulfillmentError<'tcx>>) {
loop { }
}
fn report_fulfillment_error<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
error:
&FulfillmentError<'tcx>) {
loop { }
}
pub fn report_projection_error<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
obligation:
&PredicateObligation<'tcx>,
error:
&MismatchedProjectionTypes<'tcx>) {
loop { }
}
fn report_on_unimplemented<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
trait_ref: &TraitRef<'tcx>,
span: Span) -> Option<String> {
loop { }
}
pub fn report_selection_error<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
obligation:
&PredicateObligation<'tcx>,
error:
&SelectionError<'tcx>) {
loop { }
}
pub fn maybe_report_ambiguity<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
obligation:
&PredicateObligation<'tcx>) {
loop { }
}
fn note_obligation_cause<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
obligation:
&PredicateObligation<'tcx>) {
loop { }
}
fn note_obligation_cause_code<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
_predicate:
&ty::Predicate<'tcx>,
cause_span: Span,
cause_code:
&ObligationCauseCode<'tcx>) {
loop { }
}
pub fn suggest_new_overflow_limit(tcx: &ty::ctxt, span: Span) {
loop { }
}
}
mod fulfill {
use middle::infer::{InferCtxt};
use middle::mem_categorization::Typer;
use middle::ty::{self, RegionEscape, Ty};
use std::collections::HashSet;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default;
use syntax::ast;
use util::common::ErrorReported;
use util::ppaux::Repr;
use util::nodemap::NodeMap;
use super::CodeAmbiguity;
use super::CodeProjectionError;
use super::CodeSelectionError;
use super::FulfillmentError;
use super::ObligationCause;
use super::PredicateObligation;
use super::project;
use super::select::SelectionContext;
use super::Unimplemented;
use super::util::predicate_for_builtin_bound;
/// The fulfillment context is used to drive trait resolution. It
/// consists of a list of obligations that must be (eventually)
/// satisfied. The job is to track which are satisfied, which yielded
/// errors, and which are still pending. At any point, users can call
/// `select_where_possible`, and the fulfilment context will try to do
/// selection, retaining only those obligations that remain
/// ambiguous. This may be helpful in pushing type inference
/// along. Once all type inference constraints have been generated, the
/// method `select_all_or_error` can be used to report any remaining
/// ambiguous cases as errors.
pub struct FulfillmentContext<'tcx> {
duplicate_set: HashSet<ty::Predicate<'tcx>>,
predicates: Vec<PredicateObligation<'tcx>>,
attempted_mark: uint,
region_obligations: NodeMap<Vec<RegionObligation<'tcx>>>,
}
pub struct RegionObligation<'tcx> {
pub sub_region: ty::Region,
pub sup_type: Ty<'tcx>,
pub cause: ObligationCause<'tcx>,
}
impl <'tcx> FulfillmentContext<'tcx> {
pub fn new() -> FulfillmentContext<'tcx> { loop { } }
/// "Normalize" a projection type `<SomeType as SomeTrait>::X` by
/// creating a fresh type variable `$0` as well as a projection
/// predicate `<SomeType as SomeTrait>::X == $0`. When the
/// inference engine runs, it will attempt to find an impl of
/// `SomeTrait` or a where clause that lets us unify `$0` with
/// something concrete. If this fails, we'll unify `$0` with
/// `projection_ty` again.
pub fn normalize_projection_type<'a>(&mut self,
infcx:
&InferCtxt<'a, 'tcx>,
typer:
&ty::UnboxedClosureTyper<'tcx>,
projection_ty:
ty::ProjectionTy<'tcx>,
cause:
ObligationCause<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn register_builtin_bound<'a>(&mut self,
infcx: &InferCtxt<'a, 'tcx>,
ty: Ty<'tcx>,
builtin_bound:
ty::BuiltinBound,
cause:
ObligationCause<'tcx>) {
loop { }
}
pub fn register_region_obligation<'a>(&mut self,
infcx:
&InferCtxt<'a,
'tcx>,
t_a: Ty<'tcx>,
r_b: ty::Region,
cause:
ObligationCause<'tcx>) {
loop { }
}
pub fn register_predicate_obligation<'a>(&mut self,
infcx:
&InferCtxt<'a,
'tcx>,
obligation:
PredicateObligation<'tcx>) {
loop { }
}
pub fn region_obligations(&self, body_id: ast::NodeId)
-> &[RegionObligation<'tcx>] {
loop { }
}
pub fn select_all_or_error<'a>(&mut self,
infcx: &InferCtxt<'a, 'tcx>,
typer:
&ty::UnboxedClosureTyper<'tcx>)
-> Result<(), Vec<FulfillmentError<'tcx>>> {
loop { }
}
/// Attempts to select obligations that were registered since the call to a selection routine.
/// This is used by the type checker to eagerly attempt to resolve obligations in hopes of
/// gaining type information. It'd be equally valid to use `select_where_possible` but it
/// results in `O(n^2)` performance (#18208).
pub fn select_new_obligations<'a>(&mut self,
infcx: &InferCtxt<'a, 'tcx>,
typer:
&ty::UnboxedClosureTyper<'tcx>)
-> Result<(), Vec<FulfillmentError<'tcx>>> {
loop { }
}
pub fn select_where_possible<'a>(&mut self,
infcx: &InferCtxt<'a, 'tcx>,
typer:
&ty::UnboxedClosureTyper<'tcx>)
-> Result<(), Vec<FulfillmentError<'tcx>>> {
loop { }
}
pub fn pending_obligations(&self)
-> &[PredicateObligation<'tcx>] {
loop { }
}
/// Attempts to select obligations using `selcx`. If `only_new_obligations` is true, then it
/// only attempts to select obligations that haven't been seen before.
fn select<'a>(&mut self,
selcx: &mut SelectionContext<'a, 'tcx>,
only_new_obligations: bool)
-> Result<(), Vec<FulfillmentError<'tcx>>> {
loop { }
}
}
fn process_predicate<'a,
'tcx>(selcx: &mut SelectionContext<'a, 'tcx>,
obligation: &PredicateObligation<'tcx>,
new_obligations:
&mut Vec<PredicateObligation<'tcx>>,
errors:
&mut Vec<FulfillmentError<'tcx>>,
region_obligations:
&mut NodeMap<Vec<RegionObligation<'tcx>>>)
-> bool {
/*!
* Processes a predicate obligation and modifies the appropriate
* output array with the successful/error result. Returns `false`
* if the predicate could not be processed due to insufficient
* type inference.
*/
loop { }
}
impl <'tcx> Repr<'tcx> for RegionObligation<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
t_a: Ty<'tcx>,
r_b: ty::Region,
cause: ObligationCause<'tcx>,
region_obligations:
&mut NodeMap<Vec<RegionObligation<'tcx>>>) {
loop { }
}
}
mod project {
//! Code for projecting associated types out of trait references.
use super::elaborate_predicates;
use super::Obligation;
use super::ObligationCause;
use super::Overflow;
use super::PredicateObligation;
use super::SelectionContext;
use super::SelectionError;
use super::VtableImplData;
use middle::infer;
use middle::subst::Subst;
use middle::ty::{self, AsPredicate, ReferencesError, RegionEscape,
HasProjectionTypes, ToPolyTraitRef, Ty};
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
use std::rc::Rc;
use util::ppaux::Repr;
pub type PolyProjectionObligation<'tcx> =
Obligation<'tcx, ty::PolyProjectionPredicate<'tcx>>;
pub type ProjectionObligation<'tcx> =
Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
pub type ProjectionTyObligation<'tcx> =
Obligation<'tcx, ty::ProjectionTy<'tcx>>;
/// When attempting to resolve `<T as TraitRef>::Name` ...
pub enum ProjectionTyError<'tcx> {
/// ...we found multiple sources of information and couldn't resolve the ambiguity.
TooManyCandidates,
/// ...an error occurred matching `T : TraitRef`
TraitSelectionError(SelectionError<'tcx>),
}
#[derive(Clone)]
pub struct MismatchedProjectionTypes<'tcx> {
pub err: ty::type_err<'tcx>,
}
enum ProjectionTyCandidate<'tcx> {
ParamEnv(ty::PolyProjectionPredicate<'tcx>),
Impl(VtableImplData<'tcx, PredicateObligation<'tcx>>),
}
struct ProjectionTyCandidateSet<'tcx> {
vec: Vec<ProjectionTyCandidate<'tcx>>,
ambiguous: bool,
}
pub fn poly_project_and_unify_type<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx,
'tcx>,
obligation:
&PolyProjectionObligation<'tcx>)
->
Result<Option<Vec<PredicateObligation<'tcx>>>,
MismatchedProjectionTypes<'tcx>> {
loop { }
}
/// Compute result of projecting an associated type and unify it with
/// `obligation.predicate.ty` (if we can).
fn project_and_unify_type<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx,
'tcx>,
obligation:
&ProjectionObligation<'tcx>)
->
Result<Option<Vec<PredicateObligation<'tcx>>>,
MismatchedProjectionTypes<'tcx>> {
loop { }
}
pub fn normalize<'a, 'b, 'tcx,
T>(selcx: &'a mut SelectionContext<'b, 'tcx>,
cause: ObligationCause<'tcx>, value: &T)
-> Normalized<'tcx, T> where T: TypeFoldable<'tcx> +
HasProjectionTypes + Clone + Repr<'tcx> {
loop { }
}
pub fn normalize_with_depth<'a, 'b, 'tcx,
T>(selcx:
&'a mut SelectionContext<'b,
'tcx>,
cause: ObligationCause<'tcx>,
depth: uint, value: &T)
-> Normalized<'tcx, T> where T: TypeFoldable<'tcx> +
HasProjectionTypes + Clone + Repr<'tcx> {
loop { }
}
struct AssociatedTypeNormalizer<'a, 'b:'a, 'tcx:'b> {
selcx: &'a mut SelectionContext<'b, 'tcx>,
cause: ObligationCause<'tcx>,
obligations: Vec<PredicateObligation<'tcx>>,
depth: uint,
}
impl <'a, 'b, 'tcx> AssociatedTypeNormalizer<'a, 'b, 'tcx> {
fn new(selcx: &'a mut SelectionContext<'b, 'tcx>,
cause: ObligationCause<'tcx>, depth: uint)
-> AssociatedTypeNormalizer<'a, 'b, 'tcx> {
loop { }
}
fn fold<T: TypeFoldable<'tcx> + HasProjectionTypes +
Clone>(&mut self, value: &T) -> T {
loop { }
}
}
impl <'a, 'b, 'tcx> TypeFolder<'tcx> for
AssociatedTypeNormalizer<'a, 'b, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { loop { } }
}
pub struct Normalized<'tcx, T> {
pub value: T,
pub obligations: Vec<PredicateObligation<'tcx>>,
}
pub type NormalizedTy<'tcx> = Normalized<'tcx, Ty<'tcx>>;
impl <'tcx, T> Normalized<'tcx, T> {
pub fn with<U>(self, value: U) -> Normalized<'tcx, U> {
loop { }
}
}
pub fn normalize_projection_type<'a, 'b,
'tcx>(selcx:
&'a mut SelectionContext<'b,
'tcx>,
projection_ty:
ty::ProjectionTy<'tcx>,
cause:
ObligationCause<'tcx>,
depth: uint)
-> NormalizedTy<'tcx> {
loop { }
}
fn opt_normalize_projection_type<'a, 'b,
'tcx>(selcx:
&'a mut SelectionContext<'b,
'tcx>,
projection_ty:
ty::ProjectionTy<'tcx>,
cause:
ObligationCause<'tcx>,
depth: uint)
-> Option<NormalizedTy<'tcx>> {
loop { }
}
/// in various error cases, we just set ty_err and return an obligation
/// that, when fulfilled, will lead to an error
fn normalize_to_error<'a,
'tcx>(selcx:
&mut SelectionContext<'a, 'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
cause: ObligationCause<'tcx>,
depth: uint) -> NormalizedTy<'tcx> {
loop { }
}
enum ProjectedTy<'tcx> {
Progress(Ty<'tcx>, Vec<PredicateObligation<'tcx>>),
NoProgress(Ty<'tcx>),
}
/// Compute the result of a projection type (if we can).
fn project_type<'cx,
'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>)
-> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>> {
loop { }
}
/// The first thing we have to do is scan through the parameter
/// environment to see whether there are any projection predicates
/// there that can answer this question.
fn assemble_candidates_from_param_env<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx,
'tcx>,
obligation:
&ProjectionTyObligation<'tcx>,
obligation_trait_ref:
&Rc<ty::TraitRef<'tcx>>,
candidate_set:
&mut ProjectionTyCandidateSet<'tcx>) {
loop { }
}
fn assemble_candidates_from_predicates<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx,
'tcx>,
obligation:
&ProjectionTyObligation<'tcx>,
obligation_trait_ref:
&Rc<ty::TraitRef<'tcx>>,
candidate_set:
&mut ProjectionTyCandidateSet<'tcx>,
env_predicates:
Vec<ty::Predicate<'tcx>>) {
loop { }
}
fn assemble_candidates_from_object_type<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx,
'tcx>,
obligation:
&ProjectionTyObligation<'tcx>,
obligation_trait_ref:
&Rc<ty::TraitRef<'tcx>>,
candidate_set:
&mut ProjectionTyCandidateSet<'tcx>,
object_ty:
Ty<'tcx>) {
loop { }
}
fn assemble_candidates_from_impls<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx,
'tcx>,
obligation:
&ProjectionTyObligation<'tcx>,
obligation_trait_ref:
&Rc<ty::TraitRef<'tcx>>,
candidate_set:
&mut ProjectionTyCandidateSet<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
fn confirm_candidate<'cx,
'tcx>(selcx:
&mut SelectionContext<'cx, 'tcx>,
obligation:
&ProjectionTyObligation<'tcx>,
candidate: ProjectionTyCandidate<'tcx>)
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>) {
loop { }
}
impl <'tcx> Repr<'tcx> for ProjectionTyError<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
Normalized<'tcx, T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> Normalized<'tcx, T> {
loop { }
}
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for Normalized<'tcx, T> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
}
mod object_safety {
//! "Object safety" refers to the ability for a trait to be converted
//! to an object. In general, traits may only be converted to an
//! object if all of their methods meet certain criteria. In particular,
//! they must:
//!
//! - have a suitable receiver from which we can extract a vtable;
//! - not reference the erased type `Self` except for in this receiver;
//! - not have generic type parameters
use super::supertraits;
use super::elaborate_predicates;
use middle::subst::{self, SelfSpace};
use middle::traits;
use middle::ty::{self, Ty};
use std::rc::Rc;
use syntax::ast;
use util::ppaux::Repr;
pub enum ObjectSafetyViolation<'tcx> {
/// Self : Sized declared on the trait
SizedSelf,
/// Method has something illegal
Method(Rc<ty::Method<'tcx>>, MethodViolationCode),
}
/// Reasons a method might not be object-safe.
#[derive(Copy, Clone, Show)]
pub enum MethodViolationCode {
/// e.g., `fn(self)`
ByValueSelf,
/// e.g., `fn foo()`
StaticMethod,
/// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
ReferencesSelf,
/// e.g., `fn foo<A>()`
Generic,
}
pub fn is_object_safe<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>)
-> bool {
loop { }
}
pub fn object_safety_violations<'tcx>(tcx: &ty::ctxt<'tcx>,
sub_trait_ref:
ty::PolyTraitRef<'tcx>)
-> Vec<ObjectSafetyViolation<'tcx>> {
loop { }
}
fn object_safety_violations_for_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_def_id:
ast::DefId)
-> Vec<ObjectSafetyViolation<'tcx>> {
loop { }
}
fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_def_id: ast::DefId) -> bool {
loop { }
}
fn object_safety_violations_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_def_id:
ast::DefId,
method:
&ty::Method<'tcx>)
-> Option<MethodViolationCode> {
loop { }
}
fn contains_illegal_self_type_reference<'tcx>(tcx:
&ty::ctxt<'tcx>,
trait_def_id:
ast::DefId,
ty: Ty<'tcx>)
-> bool {
loop { }
}
impl <'tcx> Repr<'tcx> for ObjectSafetyViolation<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
}
mod select {
//! See `doc.rs` for high-level documentation
#![allow(dead_code)]
pub use self::MethodMatchResult::*;
pub use self::MethodMatchedData::*;
use self::SelectionCandidate::*;
use self::BuiltinBoundConditions::*;
use self::EvaluationResult::*;
use super::{DerivedObligationCause};
use super::{project};
use super::project::Normalized;
use super::{PredicateObligation, Obligation, TraitObligation,
ObligationCause};
use super::{ObligationCauseCode, BuiltinDerivedObligation};
use super::{SelectionError, Unimplemented, Overflow,
OutputTypeParameterMismatch};
use super::{Selection};
use super::{SelectionResult};
use super::{VtableBuiltin, VtableImpl, VtableParam,
VtableUnboxedClosure, VtableFnPointer, VtableObject};
use super::{VtableImplData, VtableObjectData, VtableBuiltinData};
use super::object_safety;
use super::{util};
use middle::fast_reject;
use middle::mem_categorization::Typer;
use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
use middle::ty::{self, AsPredicate, RegionEscape, ToPolyTraitRef,
Ty};
use middle::infer;
use middle::infer::{InferCtxt, TypeFreshener};
use middle::ty_fold::TypeFoldable;
use std::cell::RefCell;
use std::collections::hash_map::HashMap;
use std::rc::Rc;
use syntax::{abi, ast};
use util::common::ErrorReported;
use util::ppaux::Repr;
pub struct SelectionContext<'cx, 'tcx:'cx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+ 'cx),
/// Freshener used specifically for skolemizing entries on the
/// obligation stack. This ensures that all entries on the stack
/// at one time will have the same set of skolemized entries,
/// which is important for checking for trait bounds that
/// recursively require themselves.
freshener: TypeFreshener<'cx, 'tcx>,
/// If true, indicates that the evaluation should be conservative
/// and consider the possibility of types outside this crate.
/// This comes up primarily when resolving ambiguity. Imagine
/// there is some trait reference `$0 : Bar` where `$0` is an
/// inference variable. If `intercrate` is true, then we can never
/// say for sure that this reference is not implemented, even if
/// there are *no impls at all for `Bar`*, because `$0` could be
/// bound to some type that in a downstream crate that implements
/// `Bar`. This is the suitable mode for coherence. Elsewhere,
/// though, we set this to false, because we are only interested
/// in types that the user could actually have written --- in
/// other words, we consider `$0 : Bar` to be unimplemented if
/// there is no type that the user could *actually name* that
/// would satisfy it. This avoids crippling inference, basically.
intercrate: bool,
}
struct TraitObligationStack<'prev, 'tcx:'prev> {
obligation: &'prev TraitObligation<'tcx>,
/// Trait ref from `obligation` but skolemized with the
/// selection-context's freshener. Used to check for recursion.
fresh_trait_ref: ty::PolyTraitRef<'tcx>,
previous: Option<&'prev TraitObligationStack<'prev, 'tcx>>,
}
#[derive(Clone)]
pub struct SelectionCache<'tcx> {
hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>,
SelectionResult<'tcx,
SelectionCandidate<'tcx>>>>,
}
pub enum MethodMatchResult {
MethodMatched(MethodMatchedData),
MethodAmbiguous(Vec<ast::DefId>),
MethodDidNotMatch,
}
#[derive(Copy, Show)]
pub enum MethodMatchedData {
PreciseMethodMatch,
CoerciveMethodMatch(ast::DefId),
}
/// The selection process begins by considering all impls, where
/// clauses, and so forth that might resolve an obligation. Sometimes
/// we'll be able to say definitively that (e.g.) an impl does not
/// apply to the obligation: perhaps it is defined for `uint` but the
/// obligation is for `int`. In that case, we drop the impl out of the
/// list. But the other cases are considered *candidates*.
///
/// Candidates can either be definitive or ambiguous. An ambiguous
/// candidate is one that might match or might not, depending on how
/// type variables wind up being resolved. This only occurs during inference.
///
/// For selection to succeed, there must be exactly one non-ambiguous
/// candidate. Usually, it is not possible to have more than one
/// definitive candidate, due to the coherence rules. However, there is
/// one case where it could occur: if there is a blanket impl for a
/// trait (that is, an impl applied to all T), and a type parameter
/// with a where clause. In that case, we can have a candidate from the
/// where clause and a second candidate from the impl. This is not a
/// problem because coherence guarantees us that the impl which would
/// be used to satisfy the where clause is the same one that we see
/// now. To resolve this issue, therefore, we ignore impls if we find a
/// matching where clause. Part of the reason for this is that where
/// clauses can give additional information (like, the types of output
/// parameters) that would have to be inferred from the impl.
#[derive(PartialEq, Eq, Show, Clone)]
enum SelectionCandidate<'tcx> {
BuiltinCandidate(ty::BuiltinBound),
ParamCandidate(ty::PolyTraitRef<'tcx>),
ImplCandidate(ast::DefId),
/// This is a trait matching with a projected type as `Self`, and
/// we found an applicable bound in the trait definition.
ProjectionCandidate,
/// Implementation of a `Fn`-family trait by one of the
/// anonymous types generated for a `||` expression.
UnboxedClosureCandidate(ast::DefId, Substs<'tcx>),
/// Implementation of a `Fn`-family trait by one of the anonymous
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
FnPointerCandidate,
ObjectCandidate,
ErrorCandidate,
}
struct SelectionCandidateSet<'tcx> {
vec: Vec<SelectionCandidate<'tcx>>,
ambiguous: bool,
}
enum BuiltinBoundConditions<'tcx> {
If(Vec<Ty<'tcx>>),
ParameterBuiltin,
AmbiguousBuiltin,
}
#[derive(Show)]
enum EvaluationResult<'tcx> {
EvaluatedToOk,
EvaluatedToAmbig,
EvaluatedToErr(SelectionError<'tcx>),
}
impl <'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
loop { }
}
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
closure_typer:
&'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
loop { }
}
pub fn infcx(&self) -> &'cx InferCtxt<'cx, 'tcx> { loop { } }
pub fn tcx(&self) -> &'cx ty::ctxt<'tcx> { loop { } }
pub fn param_env(&self)
-> &'cx ty::ParameterEnvironment<'cx, 'tcx> {
loop { }
}
/// Evaluates whether the obligation can be satisfied. Returns an indication of whether the
/// obligation can be satisfied and, if so, by what means. Never affects surrounding typing
/// environment.
pub fn select(&mut self, obligation: &TraitObligation<'tcx>)
-> SelectionResult<'tcx, Selection<'tcx>> {
loop { }
}
/// Evaluates whether the obligation `obligation` can be satisfied (by any means).
pub fn evaluate_obligation(&mut self,
obligation:
&PredicateObligation<'tcx>)
-> bool {
loop { }
}
fn evaluate_builtin_bound_recursively<'o>(&mut self,
bound:
ty::BuiltinBound,
previous_stack:
&TraitObligationStack<'o,
'tcx>,
ty: Ty<'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
fn evaluate_predicates_recursively<'a, 'o,
I>(&mut self,
stack:
Option<&TraitObligationStack<'o,
'tcx>>,
mut predicates: I)
-> EvaluationResult<'tcx> where I: Iterator<Item =
&'a PredicateObligation<'tcx>>, 'tcx:'a {
loop { }
}
fn evaluate_predicate_recursively<'o>(&mut self,
previous_stack:
Option<&TraitObligationStack<'o,
'tcx>>,
obligation:
&PredicateObligation<'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
fn evaluate_obligation_recursively<'o>(&mut self,
previous_stack:
Option<&TraitObligationStack<'o,
'tcx>>,
obligation:
&TraitObligation<'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
fn evaluate_stack<'o>(&mut self,
stack: &TraitObligationStack<'o, 'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
/// Evaluates whether the impl with id `impl_def_id` could be applied to the self type
/// `obligation_self_ty`. This can be used either for trait or inherent impls.
pub fn evaluate_impl(&mut self, impl_def_id: ast::DefId,
obligation: &TraitObligation<'tcx>)
-> bool {
loop { }
}
fn candidate_from_obligation<'o>(&mut self,
stack:
&TraitObligationStack<'o,
'tcx>)
-> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
loop { }
}
fn candidate_from_obligation_no_cache<'o>(&mut self,
stack:
&TraitObligationStack<'o,
'tcx>)
-> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
loop { }
}
fn pick_candidate_cache(&self,
cache_fresh_trait_pred:
&ty::PolyTraitPredicate<'tcx>)
-> &SelectionCache<'tcx> {
loop { }
}
fn check_candidate_cache(&mut self,
cache_fresh_trait_pred:
&ty::PolyTraitPredicate<'tcx>)
-> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
loop { }
}
fn insert_candidate_cache(&mut self,
cache_fresh_trait_pred:
ty::PolyTraitPredicate<'tcx>,
candidate:
SelectionResult<'tcx,
SelectionCandidate<'tcx>>) {
loop { }
}
fn assemble_candidates<'o>(&mut self,
stack:
&TraitObligationStack<'o,
'tcx>)
->
Result<SelectionCandidateSet<'tcx>,
SelectionError<'tcx>> {
loop { }
}
fn assemble_candidates_from_projected_tys(&mut self,
obligation:
&TraitObligation<'tcx>,
candidates:
&mut SelectionCandidateSet<'tcx>) {
loop { }
}
fn match_projection_obligation_against_bounds_from_trait(&mut self,
obligation:
&TraitObligation<'tcx>,
snapshot:
&infer::CombinedSnapshot)
-> bool {
loop { }
}
fn match_projection(&mut self,
obligation: &TraitObligation<'tcx>,
trait_bound: ty::PolyTraitRef<'tcx>,
skol_trait_ref: Rc<ty::TraitRef<'tcx>>,
skol_map: &infer::SkolemizationMap,
snapshot: &infer::CombinedSnapshot)
-> bool {
loop { }
}
/// Given an obligation like `<SomeTrait for T>`, search the obligations that the caller
/// supplied to find out whether it is listed among them.
///
/// Never affects inference environment.
fn assemble_candidates_from_caller_bounds<'o>(&mut self,
stack:
&TraitObligationStack<'o,
'tcx>,
candidates:
&mut SelectionCandidateSet<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
fn evaluate_where_clause<'o>(&mut self,
stack:
&TraitObligationStack<'o,
'tcx>,
where_clause_trait_ref:
ty::PolyTraitRef<'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
/// Check for the artificial impl that the compiler will create for an obligation like `X :
/// FnMut<..>` where `X` is an unboxed closure type.
///
/// Note: the type parameters on an unboxed closure candidate are modeled as *output* type
/// parameters and hence do not affect whether this trait is a match or not. They will be
/// unified during the confirmation step.
fn assemble_unboxed_closure_candidates(&mut self,
obligation:
&TraitObligation<'tcx>,
candidates:
&mut SelectionCandidateSet<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
/// Implement one of the `Fn()` family for a fn pointer.
fn assemble_fn_pointer_candidates(&mut self,
obligation:
&TraitObligation<'tcx>,
candidates:
&mut SelectionCandidateSet<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
/// Search for impls that might apply to `obligation`.
fn assemble_candidates_from_impls(&mut self,
obligation:
&TraitObligation<'tcx>,
candidate_vec:
&mut Vec<SelectionCandidate<'tcx>>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
/// Search for impls that might apply to `obligation`.
fn assemble_candidates_from_object_ty(&mut self,
obligation:
&TraitObligation<'tcx>,
candidates:
&mut SelectionCandidateSet<'tcx>) {
loop { }
}
/// Further evaluate `candidate` to decide whether all type parameters match and whether nested
/// obligations are met. Returns true if `candidate` remains viable after this further
/// scrutiny.
fn winnow_candidate<'o>(&mut self,
stack:
&TraitObligationStack<'o, 'tcx>,
candidate: &SelectionCandidate<'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
fn winnow_selection<'o>(&mut self,
stack:
Option<&TraitObligationStack<'o,
'tcx>>,
selection: Selection<'tcx>)
-> EvaluationResult<'tcx> {
loop { }
}
/// Returns true if `candidate_i` should be dropped in favor of `candidate_j`.
///
/// This is generally true if either:
/// - candidate i and candidate j are equivalent; or,
/// - candidate i is a concrete impl and candidate j is a where clause bound,
/// and the concrete impl is applicable to the types in the where clause bound.
///
/// The last case refers to cases where there are blanket impls (often conditional
/// blanket impls) as well as a where clause. This can come down to one of two cases:
///
/// - The impl is truly unconditional (it has no where clauses
/// of its own), in which case the where clause is
/// unnecessary, because coherence requires that we would
/// pick that particular impl anyhow (at least so long as we
/// don't have specialization).
///
/// - The impl is conditional, in which case we may not have winnowed it out
/// because we don't know if the conditions apply, but the where clause is basically
/// telling us taht there is some impl, though not necessarily the one we see.
///
/// In both cases we prefer to take the where clause, which is
/// essentially harmless. See issue #18453 for more details of
/// a case where doing the opposite caused us harm.
fn candidate_should_be_dropped_in_favor_of<'o>(&mut self,
stack:
&TraitObligationStack<'o,
'tcx>,
candidate_i:
&SelectionCandidate<'tcx>,
candidate_j:
&SelectionCandidate<'tcx>)
-> bool {
loop { }
}
fn assemble_builtin_bound_candidates<'o>(&mut self,
bound:
ty::BuiltinBound,
stack:
&TraitObligationStack<'o,
'tcx>,
candidates:
&mut SelectionCandidateSet<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
fn builtin_bound(&mut self, bound: ty::BuiltinBound,
obligation: &TraitObligation<'tcx>)
->
Result<BuiltinBoundConditions<'tcx>,
SelectionError<'tcx>> {
loop { }
}
fn confirm_candidate(&mut self,
obligation: &TraitObligation<'tcx>,
candidate: SelectionCandidate<'tcx>)
-> Result<Selection<'tcx>, SelectionError<'tcx>> {
loop { }
}
fn confirm_projection_candidate(&mut self,
obligation:
&TraitObligation<'tcx>) {
loop { }
}
fn confirm_param_candidate(&mut self,
obligation: &TraitObligation<'tcx>,
param: ty::PolyTraitRef<'tcx>)
-> Vec<PredicateObligation<'tcx>> {
loop { }
}
fn confirm_builtin_candidate(&mut self,
obligation:
&TraitObligation<'tcx>,
bound: ty::BuiltinBound)
->
Result<VtableBuiltinData<PredicateObligation<'tcx>>,
SelectionError<'tcx>> {
loop { }
}
fn vtable_builtin_data(&mut self,
obligation: &TraitObligation<'tcx>,
bound: ty::BuiltinBound,
nested: Vec<Ty<'tcx>>)
-> VtableBuiltinData<PredicateObligation<'tcx>> {
loop { }
}
fn confirm_impl_candidate(&mut self,
obligation: &TraitObligation<'tcx>,
impl_def_id: ast::DefId)
->
Result<VtableImplData<'tcx, PredicateObligation<'tcx>>,
SelectionError<'tcx>> {
loop { }
}
fn vtable_impl(&mut self, impl_def_id: ast::DefId,
substs: Normalized<'tcx, Substs<'tcx>>,
cause: ObligationCause<'tcx>,
recursion_depth: uint,
skol_map: infer::SkolemizationMap,
snapshot: &infer::CombinedSnapshot)
-> VtableImplData<'tcx, PredicateObligation<'tcx>> {
loop { }
}
fn confirm_object_candidate(&mut self,
obligation:
&TraitObligation<'tcx>)
-> VtableObjectData<'tcx> {
loop { }
}
fn confirm_fn_pointer_candidate(&mut self,
obligation:
&TraitObligation<'tcx>)
-> Result<ty::Ty<'tcx>, SelectionError<'tcx>> {
loop { }
}
fn confirm_unboxed_closure_candidate(&mut self,
obligation:
&TraitObligation<'tcx>,
closure_def_id:
ast::DefId,
substs: &Substs<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
/// In the case of unboxed closure types and fn pointers,
/// we currently treat the input type parameters on the trait as
/// outputs. This means that when we have a match we have only
/// considered the self type, so we have to go back and make sure
/// to relate the argument types too. This is kind of wrong, but
/// since we control the full set of impls, also not that wrong,
/// and it DOES yield better error messages (since we don't report
/// errors as if there is no applicable impl, but rather report
/// errors are about mismatched argument types.
///
/// Here is an example. Imagine we have an unboxed closure expression
/// and we desugared it so that the type of the expression is
/// `Closure`, and `Closure` expects an int as argument. Then it
/// is "as if" the compiler generated this impl:
///
/// impl Fn(int) for Closure { ... }
///
/// Now imagine our obligation is `Fn(uint) for Closure`. So far
/// we have matched the self-type `Closure`. At this point we'll
/// compare the `int` to `uint` and generate an error.
///
/// Note that this checking occurs *after* the impl has selected,
/// because these output type parameters should not affect the
/// selection of the impl. Therefore, if there is a mismatch, we
/// report an error to the user.
fn confirm_poly_trait_refs(&mut self,
obligation_cause: ObligationCause,
obligation_trait_ref:
ty::PolyTraitRef<'tcx>,
expected_trait_ref:
ty::PolyTraitRef<'tcx>)
-> Result<(), SelectionError<'tcx>> {
loop { }
}
fn rematch_impl(&mut self, impl_def_id: ast::DefId,
obligation: &TraitObligation<'tcx>,
snapshot: &infer::CombinedSnapshot,
skol_map: &infer::SkolemizationMap,
skol_obligation_trait_ref:
Rc<ty::TraitRef<'tcx>>)
-> Normalized<'tcx, Substs<'tcx>> {
loop { }
}
fn match_impl(&mut self, impl_def_id: ast::DefId,
obligation: &TraitObligation<'tcx>,
snapshot: &infer::CombinedSnapshot,
skol_map: &infer::SkolemizationMap,
skol_obligation_trait_ref:
Rc<ty::TraitRef<'tcx>>)
-> Result<Normalized<'tcx, Substs<'tcx>>, ()> {
loop { }
}
fn fast_reject_trait_refs(&mut self,
obligation: &TraitObligation,
impl_trait_ref: &ty::TraitRef)
-> bool {
loop { }
}
/// Normalize `where_clause_trait_ref` and try to match it against
/// `obligation`. If successful, return any predicates that
/// result from the normalization. Normalization is necessary
/// because where-clauses are stored in the parameter environment
/// unnormalized.
fn match_where_clause_trait_ref(&mut self,
obligation:
&TraitObligation<'tcx>,
where_clause_trait_ref:
ty::PolyTraitRef<'tcx>)
-> Result<Vec<PredicateObligation<'tcx>>, ()> {
loop { }
}
/// Returns `Ok` if `poly_trait_ref` being true implies that the
/// obligation is satisfied.
fn match_poly_trait_ref(&mut self,
obligation: &TraitObligation<'tcx>,
poly_trait_ref:
ty::PolyTraitRef<'tcx>)
-> Result<(), ()> {
loop { }
}
/// Determines whether the self type declared against
/// `impl_def_id` matches `obligation_self_ty`. If successful,
/// returns the substitutions used to make them match. See
/// `match_impl()`. For example, if `impl_def_id` is declared
/// as:
///
/// impl<T:Copy> Foo for ~T { ... }
///
/// and `obligation_self_ty` is `int`, we'd back an `Err(_)`
/// result. But if `obligation_self_ty` were `~int`, we'd get
/// back `Ok(T=int)`.
fn match_inherent_impl(&mut self, impl_def_id: ast::DefId,
obligation_cause: &ObligationCause,
obligation_self_ty: Ty<'tcx>)
-> Result<Substs<'tcx>, ()> {
loop { }
}
fn match_self_types(&mut self, cause: &ObligationCause,
provided_self_ty: Ty<'tcx>,
required_self_ty: Ty<'tcx>)
-> Result<(), ()> {
loop { }
}
fn push_stack<'o,
's:'o>(&mut self,
previous_stack:
Option<&'s TraitObligationStack<'s,
'tcx>>,
obligation: &'o TraitObligation<'tcx>)
-> TraitObligationStack<'o, 'tcx> {
loop { }
}
/// Returns set of all impls for a given trait.
fn all_impls(&self, trait_def_id: ast::DefId)
-> Vec<ast::DefId> {
loop { }
}
fn impl_obligations(&mut self, cause: ObligationCause<'tcx>,
recursion_depth: uint,
impl_def_id: ast::DefId,
impl_substs: &Substs<'tcx>,
skol_map: infer::SkolemizationMap,
snapshot: &infer::CombinedSnapshot)
-> VecPerParamSpace<PredicateObligation<'tcx>> {
loop { }
}
fn fn_family_trait_kind(&self, trait_def_id: ast::DefId)
-> Option<ty::UnboxedClosureKind> {
loop { }
}
#[allow(unused_comparisons)]
fn derived_cause(&self, obligation: &TraitObligation<'tcx>,
variant:
fn(DerivedObligationCause<'tcx>)
-> ObligationCauseCode<'tcx>)
-> ObligationCause<'tcx> {
/*!
* Creates a cause for obligations that are derived from
* `obligation` by a recursive search (e.g., for a builtin
* bound, or eventually a `impl Foo for ..`). If `obligation`
* is itself a derived obligation, this is just a clone, but
* otherwise we create a "derived obligation" cause so as to
* keep track of the original root obligation for error
* reporting.
*/
loop { }
}
}
impl <'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> SelectionCache<'tcx> {
pub fn new() -> SelectionCache<'tcx> { loop { } }
}
impl <'o, 'tcx> TraitObligationStack<'o, 'tcx> {
fn iter(&self) -> Option<&TraitObligationStack<'o, 'tcx>> {
loop { }
}
}
impl <'o, 'tcx> Iterator for
Option<&'o TraitObligationStack<'o, 'tcx>> {type
Item
=
&'o TraitObligationStack<'o, 'tcx>;
fn next(&mut self)
-> Option<&'o TraitObligationStack<'o, 'tcx>> {
loop { }
}
}
impl <'o, 'tcx> Repr<'tcx> for TraitObligationStack<'o, 'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> EvaluationResult<'tcx> {
fn may_apply(&self) -> bool { loop { } }
}
impl MethodMatchResult {
pub fn may_apply(&self) -> bool { loop { } }
}
}
mod util {
use middle::subst::{Substs, VecPerParamSpace};
use middle::infer::InferCtxt;
use middle::ty::{self, Ty, AsPredicate, ToPolyTraitRef};
use std::collections::HashSet;
use std::fmt;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap::Span;
use util::common::ErrorReported;
use util::ppaux::Repr;
use super::{Obligation, ObligationCause, PredicateObligation,
VtableImpl, VtableParam, VtableImplData};
/// "Elaboration" is the process of identifying all the predicates that
/// are implied by a source predicate. Currently this basically means
/// walking the "supertraits" and other similar assumptions. For
/// example, if we know that `T : Ord`, the elaborator would deduce
/// that `T : PartialOrd` holds as well. Similarly, if we have `trait
/// Foo : 'static`, and we know that `T : Foo`, then we know that `T :
/// 'static`.
pub struct Elaborator<'cx, 'tcx:'cx> {
tcx: &'cx ty::ctxt<'tcx>,
stack: Vec<StackEntry<'tcx>>,
visited: HashSet<ty::Predicate<'tcx>>,
}
struct StackEntry<'tcx> {
position: uint,
predicates: Vec<ty::Predicate<'tcx>>,
}
pub fn elaborate_trait_ref<'cx,
'tcx>(tcx: &'cx ty::ctxt<'tcx>,
trait_ref:
ty::PolyTraitRef<'tcx>)
-> Elaborator<'cx, 'tcx> {
loop { }
}
pub fn elaborate_trait_refs<'cx,
'tcx>(tcx: &'cx ty::ctxt<'tcx>,
trait_refs:
&[ty::PolyTraitRef<'tcx>])
-> Elaborator<'cx, 'tcx> {
loop { }
}
pub fn elaborate_predicates<'cx,
'tcx>(tcx: &'cx ty::ctxt<'tcx>,
predicates:
Vec<ty::Predicate<'tcx>>)
-> Elaborator<'cx, 'tcx> {
loop { }
}
impl <'cx, 'tcx> Elaborator<'cx, 'tcx> {
pub fn filter_to_traits(self) -> Supertraits<'cx, 'tcx> {
loop { }
}
fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
loop { }
}
}
impl <'cx, 'tcx> Iterator for Elaborator<'cx, 'tcx> {type
Item
=
ty::Predicate<'tcx>;
fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
loop { }
}
}
/// A filter around the `Elaborator` that just yields up supertrait references,
/// not other kinds of predicates.
pub struct Supertraits<'cx, 'tcx:'cx> {
elaborator: Elaborator<'cx, 'tcx>,
}
pub fn supertraits<'cx,
'tcx>(tcx: &'cx ty::ctxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>)
-> Supertraits<'cx, 'tcx> {
loop { }
}
pub fn transitive_bounds<'cx,
'tcx>(tcx: &'cx ty::ctxt<'tcx>,
bounds: &[ty::PolyTraitRef<'tcx>])
-> Supertraits<'cx, 'tcx> {
loop { }
}
impl <'cx, 'tcx> Iterator for Supertraits<'cx, 'tcx> {type
Item
=
ty::PolyTraitRef<'tcx>;
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
loop { }
}
}
pub fn fresh_substs_for_impl<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
span: Span,
impl_def_id: ast::DefId)
-> Substs<'tcx> {
loop { }
}
impl <'tcx, N> fmt::Show for VtableImplData<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
loop { }
}
}
impl <'tcx> fmt::Show for super::VtableObjectData<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
loop { }
}
}
/// See `super::obligations_for_generics`
pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
cause: ObligationCause<'tcx>,
recursion_depth: uint,
generic_bounds:
&ty::GenericBounds<'tcx>)
-> VecPerParamSpace<PredicateObligation<'tcx>> {
loop { }
}
pub fn trait_ref_for_builtin_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
builtin_bound:
ty::BuiltinBound,
param_ty: Ty<'tcx>)
-> Result<Rc<ty::TraitRef<'tcx>>, ErrorReported> {
loop { }
}
pub fn predicate_for_builtin_bound<'tcx>(tcx: &ty::ctxt<'tcx>,
cause:
ObligationCause<'tcx>,
builtin_bound:
ty::BuiltinBound,
recursion_depth: uint,
param_ty: Ty<'tcx>)
-> Result<PredicateObligation<'tcx>, ErrorReported> {
loop { }
}
/// Cast a trait reference into a reference to one of its super
/// traits; returns `None` if `target_trait_def_id` is not a
/// supertrait.
pub fn upcast<'tcx>(tcx: &ty::ctxt<'tcx>,
source_trait_ref: ty::PolyTraitRef<'tcx>,
target_trait_def_id: ast::DefId)
-> Option<ty::PolyTraitRef<'tcx>> {
loop { }
}
/// Given an object of type `object_trait_ref`, returns the index of
/// the method `n_method` found in the trait `trait_def_id` (which
/// should be a supertrait of `object_trait_ref`) within the vtable
/// for `object_trait_ref`.
pub fn get_vtable_index_of_object_method<'tcx>(tcx:
&ty::ctxt<'tcx>,
object_trait_ref:
ty::PolyTraitRef<'tcx>,
trait_def_id:
ast::DefId,
method_index_in_trait:
uint) -> uint {
loop { }
}
impl <'tcx, O: Repr<'tcx>> Repr<'tcx> for
super::Obligation<'tcx, O> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, N: Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, N: Repr<'tcx>> Repr<'tcx> for
super::VtableImplData<'tcx, N> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, N: Repr<'tcx>> Repr<'tcx> for
super::VtableBuiltinData<N> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for super::VtableObjectData<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for super::SelectionError<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for super::FulfillmentError<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for super::FulfillmentErrorCode<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> fmt::Show for super::FulfillmentErrorCode<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
loop { }
}
}
impl <'tcx> Repr<'tcx> for super::MismatchedProjectionTypes<'tcx>
{
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> fmt::Show for super::MismatchedProjectionTypes<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
loop { }
}
}
}
/// An `Obligation` represents some trait reference (e.g. `int:Eq`) for
/// which the vtable must be found. The process of finding a vtable is
/// called "resolving" the `Obligation`. This process consists of
/// either identifying an `impl` (e.g., `impl Eq for int`) that
/// provides the required vtable, or else finding a bound that is in
/// scope. The eventual result is usually a `Selection` (defined below).
#[derive(Clone)]
pub struct Obligation<'tcx, T> {
pub cause: ObligationCause<'tcx>,
pub recursion_depth: uint,
pub predicate: T,
}
pub type PredicateObligation<'tcx> =
Obligation<'tcx, ty::Predicate<'tcx>>;
pub type TraitObligation<'tcx> =
Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
/// Why did we incur this obligation? Used for error reporting.
#[derive(Clone)]
pub struct ObligationCause<'tcx> {
pub span: Span,
pub body_id: ast::NodeId,
pub code: ObligationCauseCode<'tcx>,
}
#[derive(Clone)]
pub enum ObligationCauseCode<'tcx> {
/// Not well classified or should be obvious from span.
MiscObligation,
/// In an impl of trait X for type Y, type Y must
/// also implement all supertraits of X.
ItemObligation(ast::DefId),
/// Obligation incurred due to an object cast.
ObjectCastObligation(Ty<'tcx>),
/// Various cases where expressions must be sized/copy/etc:
AssignmentLhsSized,
StructInitializerSized,
VariableType(ast::NodeId),
ReturnType,
RepeatVec,
ClosureCapture(ast::NodeId, Span, ty::BuiltinBound),
FieldSized,
ObjectSized,
SharedStatic,
BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
ImplDerivedObligation(DerivedObligationCause<'tcx>),
}
#[derive(Clone)]
pub struct DerivedObligationCause<'tcx> {
/// The trait reference of the parent obligation that led to the
/// current obligation. Note that only trait obligations lead to
/// derived obligations, so we just store the trait reference here
/// directly.
parent_trait_ref: ty::PolyTraitRef<'tcx>,
/// The parent trait had this cause
parent_code: Rc<ObligationCauseCode<'tcx>>,
}
pub type Obligations<'tcx, O> =
subst::VecPerParamSpace<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> =
subst::VecPerParamSpace<PredicateObligation<'tcx>>;
pub type TraitObligations<'tcx> =
subst::VecPerParamSpace<TraitObligation<'tcx>>;
pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
#[derive(Clone, Show)]
pub enum SelectionError<'tcx> {
Unimplemented,
Overflow,
OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
ty::PolyTraitRef<'tcx>,
ty::type_err<'tcx>),
}
pub struct FulfillmentError<'tcx> {
pub obligation: PredicateObligation<'tcx>,
pub code: FulfillmentErrorCode<'tcx>,
}
#[derive(Clone)]
pub enum FulfillmentErrorCode<'tcx> {
CodeSelectionError(SelectionError<'tcx>),
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
CodeAmbiguity,
}
/// When performing resolution, it is typically the case that there
/// can be one of three outcomes:
///
/// - `Ok(Some(r))`: success occurred with result `r`
/// - `Ok(None)`: could not definitely determine anything, usually due
/// to inconclusive type inference.
/// - `Err(e)`: error `e` occurred
pub type SelectionResult<'tcx, T> =
Result<Option<T>, SelectionError<'tcx>>;
/// Given the successful resolution of an obligation, the `Vtable`
/// indicates where the vtable comes from. Note that while we call this
/// a "vtable", it does not necessarily indicate dynamic dispatch at
/// runtime. `Vtable` instances just tell the compiler where to find
/// methods, but in generic code those methods are typically statically
/// dispatched -- only when an object is constructed is a `Vtable`
/// instance reified into an actual vtable.
///
/// For example, the vtable may be tied to a specific impl (case A),
/// or it may be relative to some bound that is in scope (case B).
///
///
/// ```
/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
/// impl Clone for int { ... } // Impl_3
///
/// fn foo<T:Clone>(concrete: Option<Box<int>>,
/// param: T,
/// mixed: Option<T>) {
///
/// // Case A: Vtable points at a specific impl. Only possible when
/// // type is concretely known. If the impl itself has bounded
/// // type parameters, Vtable will carry resolutions for those as well:
/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])])
///
/// // Case B: Vtable must be provided by caller. This applies when
/// // type is a type parameter.
/// param.clone(); // VtableParam
///
/// // Case C: A mix of cases A and B.
/// mixed.clone(); // Vtable(Impl_1, [VtableParam])
/// }
/// ```
///
/// ### The type parameter `N`
///
/// See explanation on `VtableImplData`.
#[derive(Show, Clone)]
pub enum Vtable<'tcx, N> {
/// Vtable identifying a particular impl.
VtableImpl(VtableImplData<'tcx, N>),
/// Successful resolution to an obligation provided by the caller
/// for some type parameter. The `Vec<N>` represents the
/// obligations incurred from normalizing the where-clause (if
/// any).
VtableParam(Vec<N>),
/// Virtual calls through an object
VtableObject(VtableObjectData<'tcx>),
/// Successful resolution for a builtin trait.
VtableBuiltin(VtableBuiltinData<N>),
/// Vtable automatically generated for an unboxed closure. The def
/// ID is the ID of the closure expression. This is a `VtableImpl`
/// in spirit, but the impl is generated by the compiler and does
/// not appear in the source.
VtableUnboxedClosure(ast::DefId, subst::Substs<'tcx>),
/// Same as above, but for a fn pointer type with the given signature.
VtableFnPointer(ty::Ty<'tcx>),
}
/// Identifies a particular impl in the source, along with a set of
/// substitutions from the impl's type/lifetime parameters. The
/// `nested` vector corresponds to the nested obligations attached to
/// the impl's type parameters.
///
/// The type parameter `N` indicates the type used for "nested
/// obligations" that are required by the impl. During type check, this
/// is `Obligation`, as one might expect. During trans, however, this
/// is `()`, because trans only requires a shallow resolution of an
/// impl, and nested obligations are satisfied later.
#[derive(Clone)]
pub struct VtableImplData<'tcx, N> {
pub impl_def_id: ast::DefId,
pub substs: subst::Substs<'tcx>,
pub nested: subst::VecPerParamSpace<N>,
}
#[derive(Show, Clone)]
pub struct VtableBuiltinData<N> {
pub nested: subst::VecPerParamSpace<N>,
}
/// A vtable for some object-safe trait `Foo` automatically derived
/// for the object type `Foo`.
#[derive(PartialEq, Eq, Clone)]
pub struct VtableObjectData<'tcx> {
pub object_ty: Ty<'tcx>,
}
/// True if there exist types that satisfy both of the two given impls.
pub fn overlapping_impls(infcx: &InferCtxt, impl1_def_id: ast::DefId,
impl2_def_id: ast::DefId) -> bool {
loop { }
}
/// Creates predicate obligations from the generic bounds.
pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
cause: ObligationCause<'tcx>,
generic_bounds:
&ty::GenericBounds<'tcx>)
-> PredicateObligations<'tcx> {
loop { }
}
/// Determines whether the type `ty` is known to meet `bound` and
/// returns true if so. Returns false if `ty` either does not meet
/// `bound` or is not known to meet bound (note that this is
/// conservative towards *no impl*, which is the opposite of the
/// `evaluate` methods).
pub fn evaluate_builtin_bound<'a,
'tcx>(infcx: &InferCtxt<'a, 'tcx>,
typer:
&ty::UnboxedClosureTyper<'tcx>,
ty: Ty<'tcx>,
bound: ty::BuiltinBound,
span: Span)
-> SelectionResult<'tcx, ()> {
loop { }
}
pub fn type_known_to_meet_builtin_bound<'a,
'tcx>(infcx:
&InferCtxt<'a,
'tcx>,
typer:
&ty::UnboxedClosureTyper<'tcx>,
ty: Ty<'tcx>,
bound: ty::BuiltinBound,
span: Span) -> bool {
loop { }
}
impl <'tcx, O> Obligation<'tcx, O> {
pub fn new(cause: ObligationCause<'tcx>, trait_ref: O)
-> Obligation<'tcx, O> {
loop { }
}
fn with_depth(cause: ObligationCause<'tcx>, recursion_depth: uint,
trait_ref: O) -> Obligation<'tcx, O> {
loop { }
}
pub fn misc(span: Span, body_id: ast::NodeId, trait_ref: O)
-> Obligation<'tcx, O> {
loop { }
}
pub fn with<P>(&self, value: P) -> Obligation<'tcx, P> {
loop { }
}
}
impl <'tcx> ObligationCause<'tcx> {
pub fn new(span: Span, body_id: ast::NodeId,
code: ObligationCauseCode<'tcx>)
-> ObligationCause<'tcx> {
loop { }
}
pub fn misc(span: Span, body_id: ast::NodeId)
-> ObligationCause<'tcx> {
loop { }
}
pub fn dummy() -> ObligationCause<'tcx> { loop { } }
}
impl <'tcx, N> Vtable<'tcx, N> {
pub fn iter_nested(&self) -> Iter<N> { loop { } }
pub fn map_nested<M, F>(&self, op: F) -> Vtable<'tcx, M> where
F: FnMut(&N) -> M {
loop { }
}
pub fn map_move_nested<M, F>(self, op: F) -> Vtable<'tcx, M> where
F: FnMut(N) -> M {
loop { }
}
}
impl <'tcx, N> VtableImplData<'tcx, N> {
pub fn iter_nested(&self) -> Iter<N> { loop { } }
pub fn map_nested<M, F>(&self, op: F) -> VtableImplData<'tcx, M>
where F: FnMut(&N) -> M {
loop { }
}
pub fn map_move_nested<M, F>(self, op: F)
-> VtableImplData<'tcx, M> where F: FnMut(N) -> M {
loop { }
}
}
impl <N> VtableBuiltinData<N> {
pub fn iter_nested(&self) -> Iter<N> { loop { } }
pub fn map_nested<M, F>(&self, op: F) -> VtableBuiltinData<M>
where F: FnMut(&N) -> M {
loop { }
}
pub fn map_move_nested<M, F>(self, op: F) -> VtableBuiltinData<M>
where F: FnMut(N) -> M {
loop { }
}
}
impl <'tcx> FulfillmentError<'tcx> {
fn new(obligation: PredicateObligation<'tcx>,
code: FulfillmentErrorCode<'tcx>)
-> FulfillmentError<'tcx> {
loop { }
}
pub fn is_overflow(&self) -> bool { loop { } }
}
impl <'tcx> TraitObligation<'tcx> {
fn self_ty(&self) -> Ty<'tcx> { loop { } }
}
}
pub mod ty {
#![allow(non_camel_case_types)]
pub use self::terr_vstore_kind::*;
pub use self::type_err::*;
pub use self::BuiltinBound::*;
pub use self::InferTy::*;
pub use self::InferRegion::*;
pub use self::ImplOrTraitItemId::*;
pub use self::UnboxedClosureKind::*;
pub use self::TraitStore::*;
pub use self::ast_ty_to_ty_cache_entry::*;
pub use self::Variance::*;
pub use self::AutoAdjustment::*;
pub use self::Representability::*;
pub use self::UnsizeKind::*;
pub use self::AutoRef::*;
pub use self::ExprKind::*;
pub use self::DtorKind::*;
pub use self::ExplicitSelfCategory::*;
pub use self::FnOutput::*;
pub use self::Region::*;
pub use self::ImplOrTraitItemContainer::*;
pub use self::BorrowKind::*;
pub use self::ImplOrTraitItem::*;
pub use self::BoundRegion::*;
pub use self::sty::*;
pub use self::IntVarValue::*;
pub use self::ExprAdjustment::*;
pub use self::vtable_origin::*;
pub use self::MethodOrigin::*;
pub use self::CopyImplementationError::*;
use back::svh::Svh;
use session::Session;
use lint;
use metadata::csearch;
use middle;
use middle::const_eval;
use middle::def::{self, DefMap, ExportMap};
use middle::dependency_format;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
use middle::mem_categorization as mc;
use middle::region;
use middle::resolve_lifetime;
use middle::infer;
use middle::stability;
use middle::subst::{self, Subst, Substs, VecPerParamSpace};
use middle::traits;
use middle::ty;
use middle::ty_fold::{self, TypeFoldable, TypeFolder};
use middle::ty_walk::TypeWalker;
use util::ppaux::{note_and_explain_region,
bound_region_ptr_to_string};
use util::ppaux::{trait_store_to_string, ty_to_string};
use util::ppaux::{Repr, UserString};
use util::common::{memoized, ErrorReported};
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
use util::nodemap::{FnvHashMap};
use arena::TypedArena;
use std::borrow::BorrowFrom;
use std::cell::{Cell, RefCell};
use std::cmp::{self, Ordering};
use std::fmt::{self, Show};
use std::hash::{Hash, Writer, SipHasher, Hasher};
use std::mem;
use std::ops;
use std::rc::Rc;
use collections::enum_set::{EnumSet, CLike};
use std::collections::{HashMap, HashSet};
use syntax::abi;
use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField,
UnnamedField};
use syntax::ast::{Visibility};
use syntax::ast_util::{self, is_local, lit_is_str, local_def,
PostExpansionMethod};
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span;
use syntax::parse::token::{self, InternedString, special_idents};
use syntax::{ast, ast_map};
pub type Disr = u64;
pub const INITIAL_DISCRIMINANT_VALUE: Disr = 0;
/// The complete set of all analyses described in this module. This is
/// produced by the driver and fed to trans and later passes.
pub struct CrateAnalysis<'tcx> {
pub export_map: ExportMap,
pub exported_items: middle::privacy::ExportedItems,
pub public_items: middle::privacy::PublicItems,
pub ty_cx: ty::ctxt<'tcx>,
pub reachable: NodeSet,
pub name: String,
pub glob_map: Option<GlobMap>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct field<'tcx> {
pub name: ast::Name,
pub mt: mt<'tcx>,
}
#[derive(Clone, Copy, Show)]
pub enum ImplOrTraitItemContainer {
TraitContainer(ast::DefId),
ImplContainer(ast::DefId),
}
impl ImplOrTraitItemContainer {
pub fn id(&self) -> ast::DefId { loop { } }
}
#[derive(Clone, Show)]
pub enum ImplOrTraitItem<'tcx> {
MethodTraitItem(Rc<Method<'tcx>>),
TypeTraitItem(Rc<AssociatedType>),
}
impl <'tcx> ImplOrTraitItem<'tcx> {
fn id(&self) -> ImplOrTraitItemId { loop { } }
pub fn def_id(&self) -> ast::DefId { loop { } }
pub fn name(&self) -> ast::Name { loop { } }
pub fn container(&self) -> ImplOrTraitItemContainer { loop { } }
pub fn as_opt_method(&self) -> Option<Rc<Method<'tcx>>> {
loop { }
}
}
#[derive(Clone, Copy, Show)]
pub enum ImplOrTraitItemId {
MethodTraitItemId(ast::DefId),
TypeTraitItemId(ast::DefId),
}
impl ImplOrTraitItemId {
pub fn def_id(&self) -> ast::DefId { loop { } }
}
#[derive(Clone, Show)]
pub struct Method<'tcx> {
pub name: ast::Name,
pub generics: ty::Generics<'tcx>,
pub fty: BareFnTy<'tcx>,
pub explicit_self: ExplicitSelfCategory,
pub vis: ast::Visibility,
pub def_id: ast::DefId,
pub container: ImplOrTraitItemContainer,
pub provided_source: Option<ast::DefId>,
}
impl <'tcx> Method<'tcx> {
pub fn new(name: ast::Name, generics: ty::Generics<'tcx>,
fty: BareFnTy<'tcx>,
explicit_self: ExplicitSelfCategory,
vis: ast::Visibility, def_id: ast::DefId,
container: ImplOrTraitItemContainer,
provided_source: Option<ast::DefId>) -> Method<'tcx> {
loop { }
}
pub fn container_id(&self) -> ast::DefId { loop { } }
}
#[derive(Clone, Copy, Show)]
pub struct AssociatedType {
pub name: ast::Name,
pub vis: ast::Visibility,
pub def_id: ast::DefId,
pub container: ImplOrTraitItemContainer,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub struct mt<'tcx> {
pub ty: Ty<'tcx>,
pub mutbl: ast::Mutability,
}
#[derive(Clone,
Copy,
PartialEq,
Eq,
Hash,
RustcEncodable,
RustcDecodable,
Show)]
pub enum TraitStore {
/// Box<Trait>
UniqTraitStore,
/// &Trait and &mut Trait
RegionTraitStore(Region, ast::Mutability),
}
#[derive(Clone, Copy, Show)]
pub struct field_ty {
pub name: Name,
pub id: DefId,
pub vis: ast::Visibility,
pub origin: ast::DefId,
}
#[derive(Copy, PartialEq, Eq, Hash)]
pub struct creader_cache_key {
pub cnum: CrateNum,
pub pos: uint,
pub len: uint,
}
#[derive(Copy)]
pub enum ast_ty_to_ty_cache_entry<'tcx> {
atttce_unresolved,
atttce_resolved(Ty<'tcx>),
}
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
pub struct ItemVariances {
pub types: VecPerParamSpace<Variance>,
pub regions: VecPerParamSpace<Variance>,
}
#[derive(Clone,
PartialEq,
RustcDecodable,
RustcEncodable,
Show,
Copy)]
pub enum Variance { Covariant, Invariant, Contravariant, Bivariant, }
#[derive(Clone, Show)]
pub enum AutoAdjustment<'tcx> {
AdjustReifyFnPointer(ast::DefId),
AdjustDerefRef(AutoDerefRef<'tcx>),
}
#[derive(Clone, PartialEq, Show)]
pub enum UnsizeKind<'tcx> {
UnsizeLength(uint),
UnsizeStruct(Box<UnsizeKind<'tcx>>, uint),
UnsizeVtable(TyTrait<'tcx>, Ty<'tcx>),
}
#[derive(Clone, Show)]
pub struct AutoDerefRef<'tcx> {
pub autoderefs: uint,
pub autoref: Option<AutoRef<'tcx>>,
}
#[derive(Clone, PartialEq, Show)]
pub enum AutoRef<'tcx> {
/// Convert from T to &T
/// The third field allows us to wrap other AutoRef adjustments.
AutoPtr(Region, ast::Mutability, Option<Box<AutoRef<'tcx>>>),
/// Convert [T, ..n] to [T] (or similar, depending on the kind)
AutoUnsize(UnsizeKind<'tcx>),
/// Convert Box<[T, ..n]> to Box<[T]> or something similar in a Box.
/// With DST and Box a library type, this should be replaced by UnsizeStruct.
AutoUnsizeUniq(UnsizeKind<'tcx>),
/// Convert from T to *T
/// Value to thin pointer
/// The second field allows us to wrap other AutoRef adjustments.
AutoUnsafe(ast::Mutability, Option<Box<AutoRef<'tcx>>>),
}
fn autoref_object_region(autoref: &AutoRef)
-> (bool, bool, Option<Region>) {
loop { }
}
pub fn adjusted_object_region(adj: &AutoAdjustment)
-> Option<Region> {
loop { }
}
pub fn adjust_is_object(adj: &AutoAdjustment) -> bool { loop { } }
pub fn type_of_adjust<'tcx>(cx: &ctxt<'tcx>,
adj: &AutoAdjustment<'tcx>)
-> Option<Ty<'tcx>> {
loop { }
}
#[derive(Clone,
Copy,
RustcEncodable,
RustcDecodable,
PartialEq,
PartialOrd,
Show)]
pub struct param_index {
pub space: subst::ParamSpace,
pub index: uint,
}
#[derive(Clone, Show)]
pub enum MethodOrigin<'tcx> {
MethodStatic(ast::DefId),
MethodStaticUnboxedClosure(ast::DefId),
MethodTypeParam(MethodParam<'tcx>),
MethodTraitObject(MethodObject<'tcx>),
}
#[derive(Clone, Show)]
pub struct MethodParam<'tcx> {
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
pub method_num: uint,
}
#[derive(Clone, Show)]
pub struct MethodObject<'tcx> {
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
pub object_trait_id: ast::DefId,
pub method_num: uint,
pub real_index: uint,
}
#[derive(Clone)]
pub struct MethodCallee<'tcx> {
pub origin: MethodOrigin<'tcx>,
pub ty: Ty<'tcx>,
pub substs: subst::Substs<'tcx>,
}
/// With method calls, we store some extra information in
/// side tables (i.e method_map). We use
/// MethodCall as a key to index into these tables instead of
/// just directly using the expression's NodeId. The reason
/// for this being that we may apply adjustments (coercions)
/// with the resulting expression also needing to use the
/// side tables. The problem with this is that we don't
/// assign a separate NodeId to this new expression
/// and so it would clash with the base expression if both
/// needed to add to the side tables. Thus to disambiguate
/// we also keep track of whether there's an adjustment in
/// our key.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub struct MethodCall {
pub expr_id: ast::NodeId,
pub adjustment: ExprAdjustment,
}
#[derive(Clone,
PartialEq,
Eq,
Hash,
Show,
RustcEncodable,
RustcDecodable,
Copy)]
pub enum ExprAdjustment { NoAdjustment, AutoDeref(uint), AutoObject, }
impl MethodCall {
pub fn expr(id: ast::NodeId) -> MethodCall { loop { } }
pub fn autoobject(id: ast::NodeId) -> MethodCall { loop { } }
pub fn autoderef(expr_id: ast::NodeId, autoderef: uint)
-> MethodCall {
loop { }
}
}
pub type MethodMap<'tcx> =
RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
pub type vtable_param_res<'tcx> = Vec<vtable_origin<'tcx>>;
pub type vtable_res<'tcx> = VecPerParamSpace<vtable_param_res<'tcx>>;
#[derive(Clone)]
pub enum vtable_origin<'tcx> {
vtable_static(ast::DefId, subst::Substs<'tcx>, vtable_res<'tcx>),
vtable_param(param_index, uint),
vtable_unboxed_closure(ast::DefId),
vtable_error,
}
pub type ObjectCastMap<'tcx> =
RefCell<NodeMap<ty::PolyTraitRef<'tcx>>>;
/// A restriction that certain types must be the same size. The use of
/// `transmute` gives rise to these restrictions. These generally
/// cannot be checked until trans; therefore, each call to `transmute`
/// will push one or more such restriction into the
/// `transmute_restrictions` vector during `intrinsicck`. They are
/// then checked during `trans` by the fn `check_intrinsics`.
#[derive(Copy)]
pub struct TransmuteRestriction<'tcx> {
/// The span whence the restriction comes.
pub span: Span,
/// The type being transmuted from.
pub original_from: Ty<'tcx>,
/// The type being transmuted to.
pub original_to: Ty<'tcx>,
/// The type being transmuted from, with all type parameters
/// substituted for an arbitrary representative. Not to be shown
/// to the end user.
pub substituted_from: Ty<'tcx>,
/// The type being transmuted to, with all type parameters
/// substituted for an arbitrary representative. Not to be shown
/// to the end user.
pub substituted_to: Ty<'tcx>,
/// NodeId of the transmute intrinsic.
pub id: ast::NodeId,
}
/// Internal storage
pub struct CtxtArenas<'tcx> {
type_: TypedArena<TyS<'tcx>>,
substs: TypedArena<Substs<'tcx>>,
bare_fn: TypedArena<BareFnTy<'tcx>>,
region: TypedArena<Region>,
}
impl <'tcx> CtxtArenas<'tcx> {
pub fn new() -> CtxtArenas<'tcx> { loop { } }
}
pub struct CommonTypes<'tcx> {
pub bool: Ty<'tcx>,
pub char: Ty<'tcx>,
pub int: Ty<'tcx>,
pub i8: Ty<'tcx>,
pub i16: Ty<'tcx>,
pub i32: Ty<'tcx>,
pub i64: Ty<'tcx>,
pub uint: Ty<'tcx>,
pub u8: Ty<'tcx>,
pub u16: Ty<'tcx>,
pub u32: Ty<'tcx>,
pub u64: Ty<'tcx>,
pub f32: Ty<'tcx>,
pub f64: Ty<'tcx>,
pub err: Ty<'tcx>,
}
/// The data structure to keep track of all the information that typechecker
/// generates so that so that it can be reused and doesn't have to be redone
/// later on.
pub struct ctxt<'tcx> {
/// The arenas that types etc are allocated from.
arenas: &'tcx CtxtArenas<'tcx>,
/// Specifically use a speedy hash algorithm for this hash map, it's used
/// quite often.
interner: RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
substs_interner: RefCell<FnvHashMap<&'tcx Substs<'tcx>,
&'tcx Substs<'tcx>>>,
bare_fn_interner: RefCell<FnvHashMap<&'tcx BareFnTy<'tcx>,
&'tcx BareFnTy<'tcx>>>,
region_interner: RefCell<FnvHashMap<&'tcx Region, &'tcx Region>>,
/// Common types, pre-interned for your convenience.
pub types: CommonTypes<'tcx>,
pub sess: Session,
pub def_map: DefMap,
pub named_region_map: resolve_lifetime::NamedRegionMap,
pub region_maps: middle::region::RegionMaps,
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated until after typeck. See
/// typeck::check::fn_ctxt for details.
pub node_types: RefCell<NodeMap<Ty<'tcx>>>,
/// Stores the type parameters which were substituted to obtain the type
/// of this node. This only applies to nodes that refer to entities
/// parameterized by type parameters, such as generic fns, types, or
/// other items.
pub item_substs: RefCell<NodeMap<ItemSubsts<'tcx>>>,
/// Maps from a trait item to the trait item "descriptor"
pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
/// Maps from a trait def-id to a list of the def-ids of its trait items
pub trait_item_def_ids: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItemId>>>>,
/// A cache for the trait_items() routine
pub trait_items_cache: RefCell<DefIdMap<Rc<Vec<ImplOrTraitItem<'tcx>>>>>,
pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef<'tcx>>>>>,
pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
/// Maps from node-id of a trait object cast (like `foo as
/// Box<Trait>`) to the trait reference.
pub object_cast_map: ObjectCastMap<'tcx>,
pub map: ast_map::Map<'tcx>,
pub intrinsic_defs: RefCell<DefIdMap<Ty<'tcx>>>,
pub freevars: RefCell<FreevarMap>,
pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
pub short_names_cache: RefCell<FnvHashMap<Ty<'tcx>, String>>,
pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry<'tcx>>>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
pub lang_items: middle::lang_items::LanguageItems,
/// A mapping of fake provided method def_ids to the default implementation
pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
pub struct_fields: RefCell<DefIdMap<Rc<Vec<field_ty>>>>,
/// Maps from def-id of a type or region parameter to its
/// (inferred) variance.
pub item_variance_map: RefCell<DefIdMap<Rc<ItemVariances>>>,
/// True if the variance has been computed yet; false otherwise.
pub variance_computed: Cell<bool>,
/// A mapping from the def ID of an enum or struct type to the def ID
/// of the method that implements its destructor. If the type is not
/// present in this map, it does not have a destructor. This map is
/// populated during the coherence phase of typechecking.
pub destructor_for_type: RefCell<DefIdMap<ast::DefId>>,
/// A method will be in this list if and only if it is a destructor.
pub destructors: RefCell<DefIdSet>,
/// Maps a trait onto a list of impls of that trait.
pub trait_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
/// Maps a DefId of a type to a list of its inherent impls.
/// Contains implementations of methods that are inherent to a type.
/// Methods in these implementations don't need to be exported.
pub inherent_impls: RefCell<DefIdMap<Rc<Vec<ast::DefId>>>>,
/// Maps a DefId of an impl to a list of its items.
/// Note that this contains all of the impls that we know about,
/// including ones in other crates. It's not clear that this is the best
/// way to do it.
pub impl_items: RefCell<DefIdMap<Vec<ImplOrTraitItemId>>>,
/// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
/// present in this set can be warned about.
pub used_unsafe: RefCell<NodeSet>,
/// Set of nodes which mark locals as mutable which end up getting used at
/// some point. Local variable definitions not in this set can be warned
/// about.
pub used_mut_nodes: RefCell<NodeSet>,
/// The set of external nominal types whose implementations have been read.
/// This is used for lazy resolution of methods.
pub populated_external_types: RefCell<DefIdSet>,
/// The set of external traits whose implementations have been read. This
/// is used for lazy resolution of traits.
pub populated_external_traits: RefCell<DefIdSet>,
/// Borrows
pub upvar_borrow_map: RefCell<UpvarBorrowMap>,
/// These two caches are used by const_eval when decoding external statics
/// and variants that are found.
pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
pub method_map: MethodMap<'tcx>,
pub dependency_formats: RefCell<dependency_format::Dependencies>,
/// Records the type of each unboxed closure. The def ID is the ID of the
/// expression defining the unboxed closure.
pub unboxed_closures: RefCell<DefIdMap<UnboxedClosure<'tcx>>>,
pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId,
lint::LintId),
lint::LevelSource>>,
/// The types that must be asserted to be the same size for `transmute`
/// to be valid. We gather up these restrictions in the intrinsicck pass
/// and check them in trans.
pub transmute_restrictions: RefCell<Vec<TransmuteRestriction<'tcx>>>,
/// Maps any item's def-id to its stability index.
pub stability: RefCell<stability::Index>,
/// Maps closures to their capture clauses.
pub capture_modes: RefCell<CaptureModeMap>,
/// Maps def IDs to true if and only if they're associated types.
pub associated_types: RefCell<DefIdMap<bool>>,
/// Caches the results of trait selection. This cache is used
/// for things that do not have to do with the parameters in scope.
pub selection_cache: traits::SelectionCache<'tcx>,
/// Caches the representation hints for struct definitions.
pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
/// Caches whether types are known to impl Copy. Note that type
/// parameters are never placed into this cache, because their
/// results are dependent on the parameter environment.
pub type_impls_copy_cache: RefCell<HashMap<Ty<'tcx>, bool>>,
/// Caches whether types are known to impl Sized. Note that type
/// parameters are never placed into this cache, because their
/// results are dependent on the parameter environment.
pub type_impls_sized_cache: RefCell<HashMap<Ty<'tcx>, bool>>,
/// Caches whether traits are object safe
pub object_safety_cache: RefCell<DefIdMap<bool>>,
}
bitflags! (flags TypeFlags : u32 {
const NO_TYPE_FLAGS = 0b0 , const HAS_PARAMS = 0b1 , const
HAS_SELF = 0b10 , const HAS_TY_INFER = 0b100 , const
HAS_RE_INFER = 0b1000 , const HAS_RE_LATE_BOUND = 0b10000 ,
const HAS_REGIONS = 0b100000 , const HAS_TY_ERR = 0b1000000
, const HAS_PROJECTION = 0b10000000 , const NEEDS_SUBST =
HAS_PARAMS . bits | HAS_SELF . bits | HAS_REGIONS . bits ,
});
macro_rules! sty_debug_print((
$ ctxt : expr , $ ( $ variant : ident ) ,
* ) => {
{
mod inner {
use middle :: ty ; # [ derive ( Copy ) ]
struct DebugStat {
total : uint , region_infer : uint ,
ty_infer : uint , both_infer : uint , }
pub fn go ( tcx : & ty :: ctxt ) {
let mut total = DebugStat {
total : 0 , region_infer : 0 , ty_infer :
0 , both_infer : 0 , } ; $ (
let mut $ variant = total ; ) * for (
_ , t ) in tcx . interner . borrow ( ) .
iter ( ) {
let variant = match t . sty {
ty :: ty_bool | ty :: ty_char | ty ::
ty_int ( .. ) | ty :: ty_uint ( .. ) | ty
:: ty_float ( .. ) | ty :: ty_str =>
continue , ty :: ty_err => continue , $ (
ty :: $ variant ( .. ) => & mut $ variant
, ) * } ; let region = t . flags .
intersects ( ty :: HAS_RE_INFER ) ; let
ty = t . flags . intersects (
ty :: HAS_TY_INFER ) ; variant . total +=
1 ; total . total += 1 ; if region {
total . region_infer += 1 ; variant .
region_infer += 1 } if ty {
total . ty_infer += 1 ; variant .
ty_infer += 1 } if region && ty {
total . both_infer += 1 ; variant .
both_infer += 1 } } println ! (
"Ty interner total ty region both"
) ; $ (
println ! (
" {:18}: {uses:6} {usespc:4.1}%, \
{ty:4.1}% {region:5.1}% {both:4.1}%"
, stringify ! ( $ variant ) , uses = $
variant . total , usespc = $ variant .
total as f64 * 100.0 / total . total as
f64 , ty = $ variant . ty_infer as f64 *
100.0 / total . total as f64 , region = $
variant . region_infer as f64 * 100.0 /
total . total as f64 , both = $ variant .
both_infer as f64 * 100.0 / total . total
as f64 ) ; ) * println ! (
" total {uses:6} \
{ty:4.1}% {region:5.1}% {both:4.1}%"
, uses = total . total , ty = total .
ty_infer as f64 * 100.0 / total . total
as f64 , region = total . region_infer as
f64 * 100.0 / total . total as f64 , both
= total . both_infer as f64 * 100.0 /
total . total as f64 ) } } inner :: go (
$ ctxt ) } });
impl <'tcx> ctxt<'tcx> {
pub fn print_debug_stats(&self) { loop { } }
}
#[derive(Show)]
pub struct TyS<'tcx> {
pub sty: sty<'tcx>,
pub flags: TypeFlags,
region_depth: u32,
}
impl fmt::Show for TypeFlags {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl <'tcx> PartialEq for TyS<'tcx> {
fn eq(&self, other: &TyS<'tcx>) -> bool { loop { } }
}
impl <'tcx> Eq for TyS<'tcx> { }
#[cfg(stage0)]
impl <'tcx, S: Writer> Hash<S> for TyS<'tcx> {
fn hash(&self, s: &mut S) { loop { } }
}
#[cfg(not(stage0))]
impl <'tcx, S: Writer + Hasher> Hash<S> for TyS<'tcx> {
fn hash(&self, s: &mut S) { loop { } }
}
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
/// An entry in the type interner.
pub struct InternedTy<'tcx> {
ty: Ty<'tcx>,
}
impl <'tcx> PartialEq for InternedTy<'tcx> {
fn eq(&self, other: &InternedTy<'tcx>) -> bool { loop { } }
}
impl <'tcx> Eq for InternedTy<'tcx> { }
impl <'tcx, S: Writer + Hasher> Hash<S> for InternedTy<'tcx> {
fn hash(&self, s: &mut S) { loop { } }
}
impl <'tcx> BorrowFrom<InternedTy<'tcx>> for sty<'tcx> {
fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> {
loop { }
}
}
pub fn type_has_params(ty: Ty) -> bool { loop { } }
pub fn type_has_self(ty: Ty) -> bool { loop { } }
pub fn type_has_ty_infer(ty: Ty) -> bool { loop { } }
pub fn type_needs_infer(ty: Ty) -> bool { loop { } }
pub fn type_has_projection(ty: Ty) -> bool { loop { } }
pub fn type_has_late_bound_regions(ty: Ty) -> bool { loop { } }
/// An "escaping region" is a bound region whose binder is not part of `t`.
///
/// So, for example, consider a type like the following, which has two binders:
///
/// for<'a> fn(x: for<'b> fn(&'a int, &'b int))
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
///
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
/// fn type*, that type has an escaping region: `'a`.
///
/// Note that what I'm calling an "escaping region" is often just called a "free region". However,
/// we already use the term "free region". It refers to the regions that we use to represent bound
/// regions on a fn definition while we are typechecking its body.
///
/// To clarify, conceptually there is no particular difference between an "escaping" region and a
/// "free" region. However, there is a big difference in practice. Basically, when "entering" a
/// binding level, one is generally required to do some sort of processing to a bound region, such
/// as replacing it with a fresh/skolemized region, or making an entry in the environment to
/// represent the scope to which it is attached, etc. An escaping region represents a bound region
/// for which this processing has not yet been done.
pub fn type_has_escaping_regions(ty: Ty) -> bool { loop { } }
pub fn type_escapes_depth(ty: Ty, depth: u32) -> bool { loop { } }
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct BareFnTy<'tcx> {
pub unsafety: ast::Unsafety,
pub abi: abi::Abi,
pub sig: PolyFnSig<'tcx>,
}
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct ClosureTy<'tcx> {
pub unsafety: ast::Unsafety,
pub onceness: ast::Onceness,
pub store: TraitStore,
pub bounds: ExistentialBounds<'tcx>,
pub sig: PolyFnSig<'tcx>,
pub abi: abi::Abi,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub enum FnOutput<'tcx> { FnConverging(Ty<'tcx>), FnDiverging, }
impl <'tcx> FnOutput<'tcx> {
pub fn diverges(&self) -> bool { loop { } }
pub fn unwrap(self) -> Ty<'tcx> { loop { } }
}
pub type PolyFnOutput<'tcx> = Binder<FnOutput<'tcx>>;
impl <'tcx> PolyFnOutput<'tcx> {
pub fn diverges(&self) -> bool { loop { } }
}
/// Signature of a function type, which I have arbitrarily
/// decided to use to refer to the input/output types.
///
/// - `inputs` is the list of arguments and their modes.
/// - `output` is the return type.
/// - `variadic` indicates whether this is a variadic function. (only true for foreign fns)
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct FnSig<'tcx> {
pub inputs: Vec<Ty<'tcx>>,
pub output: FnOutput<'tcx>,
pub variadic: bool,
}
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
impl <'tcx> PolyFnSig<'tcx> {
pub fn inputs(&self) -> ty::Binder<Vec<Ty<'tcx>>> { loop { } }
pub fn input(&self, index: uint) -> ty::Binder<Ty<'tcx>> {
loop { }
}
pub fn output(&self) -> ty::Binder<FnOutput<'tcx>> { loop { } }
pub fn variadic(&self) -> bool { loop { } }
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub struct ParamTy {
pub space: subst::ParamSpace,
pub idx: u32,
pub name: ast::Name,
}
/// A [De Bruijn index][dbi] is a standard means of representing
/// regions (and perhaps later types) in a higher-ranked setting. In
/// particular, imagine a type like this:
///
/// for<'a> fn(for<'b> fn(&'b int, &'a int), &'a char)
/// ^ ^ | | |
/// | | | | |
/// | +------------+ 1 | |
/// | | |
/// +--------------------------------+ 2 |
/// | |
/// +------------------------------------------+ 1
///
/// In this type, there are two binders (the outer fn and the inner
/// fn). We need to be able to determine, for any given region, which
/// fn type it is bound by, the inner or the outer one. There are
/// various ways you can do this, but a De Bruijn index is one of the
/// more convenient and has some nice properties. The basic idea is to
/// count the number of binders, inside out. Some examples should help
/// clarify what I mean.
///
/// Let's start with the reference type `&'b int` that is the first
/// argument to the inner function. This region `'b` is assigned a De
/// Bruijn index of 1, meaning "the innermost binder" (in this case, a
/// fn). The region `'a` that appears in the second argument type (`&'a
/// int`) would then be assigned a De Bruijn index of 2, meaning "the
/// second-innermost binder". (These indices are written on the arrays
/// in the diagram).
///
/// What is interesting is that De Bruijn index attached to a particular
/// variable will vary depending on where it appears. For example,
/// the final type `&'a char` also refers to the region `'a` declared on
/// the outermost fn. But this time, this reference is not nested within
/// any other binders (i.e., it is not an argument to the inner fn, but
/// rather the outer one). Therefore, in this case, it is assigned a
/// De Bruijn index of 1, because the innermost binder in that location
/// is the outer fn.
///
/// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
#[derive(Clone,
PartialEq,
Eq,
Hash,
RustcEncodable,
RustcDecodable,
Show,
Copy)]
pub struct DebruijnIndex {
pub depth: u32,
}
/// Representation of regions:
#[derive(Clone,
PartialEq,
Eq,
Hash,
RustcEncodable,
RustcDecodable,
Show,
Copy)]
pub enum Region {
ReEarlyBound(ast::NodeId, subst::ParamSpace, u32, ast::Name),
ReLateBound(DebruijnIndex, BoundRegion),
/// When checking a function body, the types of all arguments and so forth
/// that refer to bound region parameters are modified to refer to free
/// region parameters.
ReFree(FreeRegion),
/// A concrete region naming some expression within the current function.
ReScope(region::CodeExtent),
/// Static data that has an "infinite" lifetime. Top in the region lattice.
ReStatic,
/// A region variable. Should not exist after typeck.
ReInfer(InferRegion),
/// Empty lifetime is for data that is never accessed.
/// Bottom in the region lattice. We treat ReEmpty somewhat
/// specially; at least right now, we do not generate instances of
/// it during the GLB computations, but rather
/// generate an error instead. This is to improve error messages.
/// The only way to get an instance of ReEmpty is to have a region
/// variable with no constraints.
ReEmpty,
}
/// Upvars do not get their own node-id. Instead, we use the pair of
/// the original var id (that is, the root variable that is referenced
/// by the upvar) and the id of the closure expression.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Show)]
pub struct UpvarId {
pub var_id: ast::NodeId,
pub closure_expr_id: ast::NodeId,
}
#[derive(Clone,
PartialEq,
Eq,
Hash,
Show,
RustcEncodable,
RustcDecodable,
Copy)]
pub enum BorrowKind {
/// Data must be immutable and is aliasable.
ImmBorrow,
/// Data must be immutable but not aliasable. This kind of borrow
/// cannot currently be expressed by the user and is used only in
/// implicit closure bindings. It is needed when you the closure
/// is borrowing or mutating a mutable referent, e.g.:
///
/// let x: &mut int = ...;
/// let y = || *x += 5;
///
/// If we were to try to translate this closure into a more explicit
/// form, we'd encounter an error with the code as written:
///
/// struct Env { x: & &mut int }
/// let x: &mut int = ...;
/// let y = (&mut Env { &x }, fn_ptr); // Closure is pair of env and fn
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
///
/// This is then illegal because you cannot mutate a `&mut` found
/// in an aliasable location. To solve, you'd have to translate with
/// an `&mut` borrow:
///
/// struct Env { x: & &mut int }
/// let x: &mut int = ...;
/// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x
/// fn fn_ptr(env: &mut Env) { **env.x += 5; }
///
/// Now the assignment to `**env.x` is legal, but creating a
/// mutable pointer to `x` is not because `x` is not mutable. We
/// could fix this by declaring `x` as `let mut x`. This is ok in
/// user code, if awkward, but extra weird for closures, since the
/// borrow is hidden.
///
/// So we introduce a "unique imm" borrow -- the referent is
/// immutable, but not aliasable. This solves the problem. For
/// simplicity, we don't give users the way to express this
/// borrow, it's just used when translating closures.
UniqueImmBorrow,
/// Data is mutable and not aliasable.
MutBorrow,
}
/// Information describing the borrowing of an upvar. This is computed
/// during `typeck`, specifically by `regionck`. The general idea is
/// that the compiler analyses treat closures like:
///
/// let closure: &'e fn() = || {
/// x = 1; // upvar x is assigned to
/// use(y); // upvar y is read
/// foo(&z); // upvar z is borrowed immutably
/// };
///
/// as if they were "desugared" to something loosely like:
///
/// struct Vars<'x,'y,'z> { x: &'x mut int,
/// y: &'y const int,
/// z: &'z int }
/// let closure: &'e fn() = {
/// fn f(env: &Vars) {
/// *env.x = 1;
/// use(*env.y);
/// foo(env.z);
/// }
/// let env: &'e mut Vars<'x,'y,'z> = &mut Vars { x: &'x mut x,
/// y: &'y const y,
/// z: &'z z };
/// (env, f)
/// };
///
/// This is basically what happens at runtime. The closure is basically
/// an existentially quantified version of the `(env, f)` pair.
///
/// This data structure indicates the region and mutability of a single
/// one of the `x...z` borrows.
///
/// It may not be obvious why each borrowed variable gets its own
/// lifetime (in the desugared version of the example, these are indicated
/// by the lifetime parameters `'x`, `'y`, and `'z` in the `Vars` definition).
/// Each such lifetime must encompass the lifetime `'e` of the closure itself,
/// but need not be identical to it. The reason that this makes sense:
///
/// - Callers are only permitted to invoke the closure, and hence to
/// use the pointers, within the lifetime `'e`, so clearly `'e` must
/// be a sublifetime of `'x...'z`.
/// - The closure creator knows which upvars were borrowed by the closure
/// and thus `x...z` will be reserved for `'x...'z` respectively.
/// - Through mutation, the borrowed upvars can actually escape
/// the closure, so sometimes it is necessary for them to be larger
/// than the closure lifetime itself.
#[derive(PartialEq,
Clone,
RustcEncodable,
RustcDecodable,
Show,
Copy)]
pub struct UpvarBorrow {
pub kind: BorrowKind,
pub region: ty::Region,
}
pub type UpvarBorrowMap = FnvHashMap<UpvarId, UpvarBorrow>;
impl Region {
pub fn is_bound(&self) -> bool { loop { } }
pub fn escapes_depth(&self, depth: u32) -> bool { loop { } }
}
#[derive(Clone,
PartialEq,
PartialOrd,
Eq,
Ord,
Hash,
RustcEncodable,
RustcDecodable,
Show,
Copy)]
/// A "free" region `fr` can be interpreted as "some region
/// at least as big as the scope `fr.scope`".
pub struct FreeRegion {
pub scope: region::CodeExtent,
pub bound_region: BoundRegion,
}
#[derive(Clone,
PartialEq,
PartialOrd,
Eq,
Ord,
Hash,
RustcEncodable,
RustcDecodable,
Show,
Copy)]
pub enum BoundRegion {
/// An anonymous region parameter for a given fn (&T)
BrAnon(u32),
/// Named region parameters for functions (a in &'a T)
///
/// The def-id is needed to distinguish free regions in
/// the event of shadowing.
BrNamed(ast::DefId, ast::Name),
/// Fresh bound identifiers created during GLB computations.
BrFresh(u32),
BrEnv,
}
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub enum sty<'tcx> {
ty_bool,
ty_char,
ty_int(ast::IntTy),
ty_uint(ast::UintTy),
ty_float(ast::FloatTy),
/// Substs here, possibly against intuition, *may* contain `ty_param`s.
/// That is, even after substitution it is possible that there are type
/// variables. This happens when the `ty_enum` corresponds to an enum
/// definition and not a concrete use of it. To get the correct `ty_enum`
/// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
/// the `ast_ty_to_ty_cache`. This is probably true for `ty_struct` as
/// well.`
ty_enum(DefId, &'tcx Substs<'tcx>),
ty_uniq(Ty<'tcx>),
ty_str,
ty_vec(Ty<'tcx>, Option<uint>),
ty_ptr(mt<'tcx>),
ty_rptr(&'tcx Region, mt<'tcx>),
ty_bare_fn(Option<DefId>, &'tcx BareFnTy<'tcx>),
ty_trait(Box<TyTrait<'tcx>>),
ty_struct(DefId, &'tcx Substs<'tcx>),
ty_unboxed_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
ty_tup(Vec<Ty<'tcx>>),
ty_projection(ProjectionTy<'tcx>),
ty_param(ParamTy),
ty_open(Ty<'tcx>),
ty_infer(InferTy),
ty_err,
}
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct TyTrait<'tcx> {
pub principal: ty::PolyTraitRef<'tcx>,
pub bounds: ExistentialBounds<'tcx>,
}
impl <'tcx> TyTrait<'tcx> {
pub fn principal_def_id(&self) -> ast::DefId { loop { } }
/// Object types don't have a self-type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self-type. A common choice is `mk_err()`
/// or some skolemized type.
pub fn principal_trait_ref_with_self_ty(&self, tcx: &ctxt<'tcx>,
self_ty: Ty<'tcx>)
-> ty::PolyTraitRef<'tcx> {
loop { }
}
pub fn projection_bounds_with_self_ty(&self, tcx: &ctxt<'tcx>,
self_ty: Ty<'tcx>)
-> Vec<ty::PolyProjectionPredicate<'tcx>> {
loop { }
}
}
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where clause:
///
/// T : Foo<U>
///
/// This would be represented by a trait-reference where the def-id is the
/// def-id for the trait `Foo` and the substs defines `T` as parameter 0 in the
/// `SelfSpace` and `U` as parameter 0 in the `TypeSpace`.
///
/// Trait references also appear in object types like `Foo<U>`, but in
/// that case the `Self` parameter is absent from the substitutions.
///
/// Note that a `TraitRef` introduces a level of region binding, to
/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
/// U>` or higher-ranked object types.
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
pub substs: &'tcx Substs<'tcx>,
}
pub type PolyTraitRef<'tcx> = Binder<Rc<TraitRef<'tcx>>>;
impl <'tcx> PolyTraitRef<'tcx> {
pub fn self_ty(&self) -> Ty<'tcx> { loop { } }
pub fn def_id(&self) -> ast::DefId { loop { } }
pub fn substs(&self) -> &'tcx Substs<'tcx> { loop { } }
pub fn input_types(&self) -> &[Ty<'tcx>] { loop { } }
pub fn to_poly_trait_predicate(&self)
-> PolyTraitPredicate<'tcx> {
loop { }
}
}
/// Binder is a binder for higher-ranked lifetimes. It is part of the
/// compiler's representation for things like `for<'a> Fn(&'a int)`
/// (which would be represented by the type `PolyTraitRef ==
/// Binder<TraitRef>`). Note that when we skolemize, instantiate,
/// erase, or otherwise "discharge" these bound reons, we change the
/// type from `Binder<T>` to just `T` (see
/// e.g. `liberate_late_bound_regions`).
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct Binder<T>(pub T);
#[derive(Clone, Copy, PartialEq)]
pub enum IntVarValue { IntType(ast::IntTy), UintType(ast::UintTy), }
#[derive(Clone, Copy, Show)]
pub enum terr_vstore_kind { terr_vec, terr_str, terr_fn, terr_trait, }
#[derive(Clone, Copy, Show)]
pub struct expected_found<T> {
pub expected: T,
pub found: T,
}
#[derive(Clone, Copy, Show)]
pub enum type_err<'tcx> {
terr_mismatch,
terr_unsafety_mismatch(expected_found<ast::Unsafety>),
terr_onceness_mismatch(expected_found<Onceness>),
terr_abi_mismatch(expected_found<abi::Abi>),
terr_mutability,
terr_sigil_mismatch(expected_found<TraitStore>),
terr_box_mutability,
terr_ptr_mutability,
terr_ref_mutability,
terr_vec_mutability,
terr_tuple_size(expected_found<uint>),
terr_fixed_array_size(expected_found<uint>),
terr_ty_param_size(expected_found<uint>),
terr_arg_count,
terr_regions_does_not_outlive(Region, Region),
terr_regions_not_same(Region, Region),
terr_regions_no_overlap(Region, Region),
terr_regions_insufficiently_polymorphic(BoundRegion, Region),
terr_regions_overly_polymorphic(BoundRegion, Region),
terr_trait_stores_differ(terr_vstore_kind,
expected_found<TraitStore>),
terr_sorts(expected_found<Ty<'tcx>>),
terr_integer_as_char,
terr_int_mismatch(expected_found<IntVarValue>),
terr_float_mismatch(expected_found<ast::FloatTy>),
terr_traits(expected_found<ast::DefId>),
terr_builtin_bounds(expected_found<BuiltinBounds>),
terr_variadic_mismatch(expected_found<bool>),
terr_cyclic_ty,
terr_convergence_mismatch(expected_found<bool>),
terr_projection_name_mismatched(expected_found<ast::Name>),
terr_projection_bounds_length(expected_found<uint>),
}
/// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
/// as well as the existential type parameter in an object type.
#[derive(PartialEq, Eq, Hash, Clone, Show)]
pub struct ParamBounds<'tcx> {
pub region_bounds: Vec<ty::Region>,
pub builtin_bounds: BuiltinBounds,
pub trait_bounds: Vec<PolyTraitRef<'tcx>>,
pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
}
/// Bounds suitable for an existentially quantified type parameter
/// such as those that appear in object types or closure types. The
/// major difference between this case and `ParamBounds` is that
/// general purpose trait bounds are omitted and there must be
/// *exactly one* region.
#[derive(PartialEq, Eq, Hash, Clone, Show)]
pub struct ExistentialBounds<'tcx> {
pub region_bound: ty::Region,
pub builtin_bounds: BuiltinBounds,
pub projection_bounds: Vec<PolyProjectionPredicate<'tcx>>,
}
pub type BuiltinBounds = EnumSet<BuiltinBound>;
#[derive(Clone,
RustcEncodable,
PartialEq,
Eq,
RustcDecodable,
Hash,
Show,
Copy)]
#[repr(uint)]
pub enum BuiltinBound { BoundSend, BoundSized, BoundCopy, BoundSync, }
pub fn empty_builtin_bounds() -> BuiltinBounds { loop { } }
pub fn all_builtin_bounds() -> BuiltinBounds { loop { } }
/// An existential bound that does not implement any traits.
pub fn region_existential_bound<'tcx>(r: ty::Region)
-> ExistentialBounds<'tcx> {
loop { }
}
impl CLike for BuiltinBound {
fn to_uint(&self) -> uint { loop { } }
fn from_uint(v: uint) -> BuiltinBound { loop { } }
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct TyVid {
pub index: u32,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct IntVid {
pub index: u32,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct FloatVid {
pub index: u32,
}
#[derive(Clone,
PartialEq,
Eq,
RustcEncodable,
RustcDecodable,
Hash,
Copy)]
pub struct RegionVid {
pub index: u32,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum InferTy {
TyVar(TyVid),
IntVar(IntVid),
FloatVar(FloatVid),
/// A `FreshTy` is one that is generated as a replacement for an
/// unbound type variable. This is convenient for caching etc. See
/// `middle::infer::freshen` for more details.
FreshTy(u32),
FreshIntTy(u32),
}
#[derive(Clone,
RustcEncodable,
RustcDecodable,
PartialEq,
Eq,
Hash,
Show,
Copy)]
pub enum UnconstrainedNumeric {
UnconstrainedFloat,
UnconstrainedInt,
Neither,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Show, Copy)]
pub enum InferRegion {
ReVar(RegionVid),
ReSkolemized(u32, BoundRegion),
}
impl cmp::PartialEq for InferRegion {
fn eq(&self, other: &InferRegion) -> bool { loop { } }
fn ne(&self, other: &InferRegion) -> bool { loop { } }
}
impl fmt::Show for TyVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl fmt::Show for IntVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl fmt::Show for FloatVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl fmt::Show for RegionVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl <'tcx> fmt::Show for FnSig<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl fmt::Show for InferTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
impl fmt::Show for IntVarValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
#[derive(Clone, Show)]
pub struct TypeParameterDef<'tcx> {
pub name: ast::Name,
pub def_id: ast::DefId,
pub space: subst::ParamSpace,
pub index: u32,
pub bounds: ParamBounds<'tcx>,
pub default: Option<Ty<'tcx>>,
}
#[derive(RustcEncodable, RustcDecodable, Clone, Show)]
pub struct RegionParameterDef {
pub name: ast::Name,
pub def_id: ast::DefId,
pub space: subst::ParamSpace,
pub index: u32,
pub bounds: Vec<ty::Region>,
}
impl RegionParameterDef {
pub fn to_early_bound_region(&self) -> ty::Region { loop { } }
}
/// Information about the formal type/lifetime parameters associated
/// with an item or method. Analogous to ast::Generics.
#[derive(Clone, Show)]
pub struct Generics<'tcx> {
pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
pub regions: VecPerParamSpace<RegionParameterDef>,
pub predicates: VecPerParamSpace<Predicate<'tcx>>,
}
impl <'tcx> Generics<'tcx> {
pub fn empty() -> Generics<'tcx> { loop { } }
pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
loop { }
}
pub fn has_region_params(&self, space: subst::ParamSpace)
-> bool {
loop { }
}
pub fn is_empty(&self) -> bool { loop { } }
pub fn to_bounds(&self, tcx: &ty::ctxt<'tcx>,
substs: &Substs<'tcx>) -> GenericBounds<'tcx> {
loop { }
}
}
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub enum Predicate<'tcx> {
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the parameters in the `TypeSpace`.
Trait(PolyTraitPredicate<'tcx>),
/// where `T1 == T2`.
Equate(PolyEquatePredicate<'tcx>),
/// where 'a : 'b
RegionOutlives(PolyRegionOutlivesPredicate),
/// where T : 'a
TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
/// where <T as TraitRef>::Name == X, approximately.
/// See `ProjectionPredicate` struct for details.
Projection(PolyProjectionPredicate<'tcx>),
}
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: Rc<TraitRef<'tcx>>,
}
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
impl <'tcx> TraitPredicate<'tcx> {
pub fn def_id(&self) -> ast::DefId { loop { } }
pub fn input_types(&self) -> &[Ty<'tcx>] { loop { } }
pub fn self_ty(&self) -> Ty<'tcx> { loop { } }
}
impl <'tcx> PolyTraitPredicate<'tcx> {
pub fn def_id(&self) -> ast::DefId { loop { } }
}
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct EquatePredicate<'tcx>(pub Ty<'tcx>, pub Ty<'tcx>);
pub type PolyEquatePredicate<'tcx> =
ty::Binder<EquatePredicate<'tcx>>;
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct OutlivesPredicate<A, B>(pub A, pub B);
pub type PolyOutlivesPredicate<A, B> =
ty::Binder<OutlivesPredicate<A, B>>;
pub type PolyRegionOutlivesPredicate =
PolyOutlivesPredicate<ty::Region, ty::Region>;
pub type PolyTypeOutlivesPredicate<'tcx> =
PolyOutlivesPredicate<Ty<'tcx>, ty::Region>;
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
/// 1. `T : TraitRef<..., Item=Type>`
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
///
/// In particular, form #1 is "desugared" to the combination of a
/// normal trait predicate (`T : TraitRef<...>`) and one of these
/// predicates. Form #2 is a broader form in that it also permits
/// equality between arbitrary types. Processing an instance of Form
/// \#2 eventually yields one of these `ProjectionPredicate`
/// instances to normalize the LHS.
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct ProjectionPredicate<'tcx> {
pub projection_ty: ProjectionTy<'tcx>,
pub ty: Ty<'tcx>,
}
pub type PolyProjectionPredicate<'tcx> =
Binder<ProjectionPredicate<'tcx>>;
impl <'tcx> PolyProjectionPredicate<'tcx> {
pub fn item_name(&self) -> ast::Name { loop { } }
pub fn sort_key(&self) -> (ast::DefId, ast::Name) { loop { } }
}
/// Represents the projection of an associated type. In explicit UFCS
/// form this would be written `<T as Trait<..>>::N`.
#[derive(Clone, PartialEq, Eq, Hash, Show)]
pub struct ProjectionTy<'tcx> {
/// The trait reference `T as Trait<..>`.
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
/// The name `N` of the associated type.
pub item_name: ast::Name,
}
impl <'tcx> ProjectionTy<'tcx> {
pub fn sort_key(&self) -> (ast::DefId, ast::Name) { loop { } }
}
pub trait ToPolyTraitRef<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}
impl <'tcx> ToPolyTraitRef<'tcx> for Rc<TraitRef<'tcx>> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { loop { } }
}
impl <'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { loop { } }
}
impl <'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { loop { } }
}
pub trait AsPredicate<'tcx> {
fn as_predicate(&self) -> Predicate<'tcx>;
}
impl <'tcx> AsPredicate<'tcx> for Rc<TraitRef<'tcx>> {
fn as_predicate(&self) -> Predicate<'tcx> { loop { } }
}
impl <'tcx> AsPredicate<'tcx> for PolyTraitRef<'tcx> {
fn as_predicate(&self) -> Predicate<'tcx> { loop { } }
}
impl <'tcx> AsPredicate<'tcx> for PolyEquatePredicate<'tcx> {
fn as_predicate(&self) -> Predicate<'tcx> { loop { } }
}
impl <'tcx> AsPredicate<'tcx> for PolyRegionOutlivesPredicate {
fn as_predicate(&self) -> Predicate<'tcx> { loop { } }
}
impl <'tcx> AsPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
fn as_predicate(&self) -> Predicate<'tcx> { loop { } }
}
impl <'tcx> AsPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
fn as_predicate(&self) -> Predicate<'tcx> { loop { } }
}
impl <'tcx> Predicate<'tcx> {
pub fn has_escaping_regions(&self) -> bool { loop { } }
pub fn to_opt_poly_trait_ref(&self)
-> Option<PolyTraitRef<'tcx>> {
loop { }
}
}
/// Represents the bounds declared on a particular set of type
/// parameters. Should eventually be generalized into a flag list of
/// where clauses. You can obtain a `GenericBounds` list from a
/// `Generics` by using the `to_bounds` method. Note that this method
/// reflects an important semantic invariant of `GenericBounds`: while
/// the bounds in a `Generics` are expressed in terms of the bound type
/// parameters of the impl/trait/whatever, a `GenericBounds` instance
/// represented a set of bounds for some particular instantiation,
/// meaning that the generic parameters have been substituted with
/// their values.
///
/// Example:
///
/// struct Foo<T,U:Bar<T>> { ... }
///
/// Here, the `Generics` for `Foo` would contain a list of bounds like
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
/// like `Foo<int,uint>`, then the `GenericBounds` would be `[[],
/// [uint:Bar<int>]]`.
#[derive(Clone, Show)]
pub struct GenericBounds<'tcx> {
pub predicates: VecPerParamSpace<Predicate<'tcx>>,
}
impl <'tcx> GenericBounds<'tcx> {
pub fn empty() -> GenericBounds<'tcx> { loop { } }
pub fn has_escaping_regions(&self) -> bool { loop { } }
pub fn is_empty(&self) -> bool { loop { } }
}
impl <'tcx> TraitRef<'tcx> {
pub fn new(def_id: ast::DefId, substs: &'tcx Substs<'tcx>)
-> TraitRef<'tcx> {
loop { }
}
pub fn self_ty(&self) -> Ty<'tcx> { loop { } }
pub fn input_types(&self) -> &[Ty<'tcx>] { loop { } }
}
/// When type checking, we use the `ParameterEnvironment` to track
/// details about the type/lifetime parameters that are in scope.
/// It primarily stores the bounds information.
///
/// Note: This information might seem to be redundant with the data in
/// `tcx.ty_param_defs`, but it is not. That table contains the
/// parameter definitions from an "outside" perspective, but this
/// struct will contain the bounds for a parameter as seen from inside
/// the function body. Currently the only real distinction is that
/// bound lifetime parameters are replaced with free ones, but in the
/// future I hope to refine the representation of types so as to make
/// more distinctions clearer.
#[derive(Clone)]
pub struct ParameterEnvironment<'a, 'tcx:'a> {
pub tcx: &'a ctxt<'tcx>,
/// A substitution that can be applied to move from
/// the "outer" view of a type or method to the "inner" view.
/// In general, this means converting from bound parameters to
/// free parameters. Since we currently represent bound/free type
/// parameters in the same way, this only has an effect on regions.
pub free_substs: Substs<'tcx>,
/// Each type parameter has an implicit region bound that
/// indicates it must outlive at least the function body (the user
/// may specify stronger requirements). This field indicates the
/// region of the callee.
pub implicit_region_bound: ty::Region,
/// Obligations that the caller must satisfy. This is basically
/// the set of bounds on the in-scope type parameters, translated
/// into Obligations.
pub caller_bounds: ty::GenericBounds<'tcx>,
/// Caches the results of trait selection. This cache is used
/// for things that have to do with the parameters in scope.
pub selection_cache: traits::SelectionCache<'tcx>,
}
impl <'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId)
-> ParameterEnvironment<'a, 'tcx> {
loop { }
}
}
/// A "type scheme", in ML terminology, is a type combined with some
/// set of generic types that the type is, well, generic over. In Rust
/// terms, it is the "type" of a fn item or struct -- this type will
/// include various generic parameters that must be substituted when
/// the item/struct is referenced. That is called converting the type
/// scheme to a monotype.
///
/// - `generics`: the set of type parameters and their bounds
/// - `ty`: the base types, which may reference the parameters defined
/// in `generics`
///
/// Note that TypeSchemes are also sometimes called "polytypes" (and
/// in fact this struct used to carry that name, so you may find some
/// stray references in a comment or something). We try to reserve the
/// "poly" prefix to refer to higher-ranked things, as in
/// `PolyTraitRef`.
#[derive(Clone, Show)]
pub struct TypeScheme<'tcx> {
pub generics: Generics<'tcx>,
pub ty: Ty<'tcx>,
}
/// As `TypeScheme` but for a trait ref.
pub struct TraitDef<'tcx> {
pub unsafety: ast::Unsafety,
/// Generic type definitions. Note that `Self` is listed in here
/// as having a single bound, the trait itself (e.g., in the trait
/// `Eq`, there is a single bound `Self : Eq`). This is so that
/// default methods get to assume that the `Self` parameters
/// implements the trait.
pub generics: Generics<'tcx>,
/// The "supertrait" bounds.
pub bounds: ParamBounds<'tcx>,
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
/// A list of the associated types defined in this trait. Useful
/// for resolving `X::Foo` type markers.
pub associated_type_names: Vec<ast::Name>,
}
/// Records the substitutions used to translate the polytype for an
/// item into the monotype of an item reference.
#[derive(Clone)]
pub struct ItemSubsts<'tcx> {
pub substs: Substs<'tcx>,
}
/// Records information about each unboxed closure.
#[derive(Clone)]
pub struct UnboxedClosure<'tcx> {
/// The type of the unboxed closure.
pub closure_type: ClosureTy<'tcx>,
/// The kind of unboxed closure this is.
pub kind: UnboxedClosureKind,
}
#[derive(Clone, Copy, PartialEq, Eq, Show)]
pub enum UnboxedClosureKind {
FnUnboxedClosureKind,
FnMutUnboxedClosureKind,
FnOnceUnboxedClosureKind,
}
impl UnboxedClosureKind {
pub fn trait_did(&self, cx: &ctxt) -> ast::DefId { loop { } }
}
pub trait UnboxedClosureTyper<'tcx> {
fn param_env<'a>(&'a self)
-> &'a ty::ParameterEnvironment<'a, 'tcx>;
fn unboxed_closure_kind(&self, def_id: ast::DefId)
-> ty::UnboxedClosureKind;
fn unboxed_closure_type
(&self, def_id: ast::DefId, substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>;
fn unboxed_closure_upvars
(&self, def_id: ast::DefId, substs: &Substs<'tcx>)
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>;
}
impl <'tcx> CommonTypes<'tcx> {
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
-> CommonTypes<'tcx> {
loop { }
}
}
pub fn mk_ctxt<'tcx>(s: Session, arenas: &'tcx CtxtArenas<'tcx>,
dm: DefMap,
named_region_map:
resolve_lifetime::NamedRegionMap,
map: ast_map::Map<'tcx>,
freevars: RefCell<FreevarMap>,
capture_modes: RefCell<CaptureModeMap>,
region_maps: middle::region::RegionMaps,
lang_items: middle::lang_items::LanguageItems,
stability: stability::Index) -> ctxt<'tcx> {
loop { }
}
impl <'tcx> ctxt<'tcx> {
pub fn mk_substs(&self, substs: Substs<'tcx>)
-> &'tcx Substs<'tcx> {
loop { }
}
pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>)
-> &'tcx BareFnTy<'tcx> {
loop { }
}
pub fn mk_region(&self, region: Region) -> &'tcx Region {
loop { }
}
pub fn unboxed_closure_kind(&self, def_id: ast::DefId)
-> ty::UnboxedClosureKind {
loop { }
}
pub fn unboxed_closure_type(&self, def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx> {
loop { }
}
}
pub fn mk_t<'tcx>(cx: &ctxt<'tcx>, st: sty<'tcx>) -> Ty<'tcx> {
loop { }
}
fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
interner:
&mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
st: sty<'tcx>) -> Ty<'tcx> {
loop { }
}
struct FlagComputation {
flags: TypeFlags,
depth: u32,
}
impl FlagComputation {
fn new() -> FlagComputation { loop { } }
fn for_sty(st: &sty) -> FlagComputation { loop { } }
fn add_flags(&mut self, flags: TypeFlags) { loop { } }
fn add_depth(&mut self, depth: u32) { loop { } }
/// Adds the flags/depth from a set of types that appear within the current type, but within a
/// region binder.
fn add_bound_computation(&mut self,
computation: &FlagComputation) {
loop { }
}
fn add_sty(&mut self, st: &sty) { loop { } }
fn add_ty(&mut self, ty: Ty) { loop { } }
fn add_tys(&mut self, tys: &[Ty]) { loop { } }
fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) { loop { } }
fn add_region(&mut self, r: Region) { loop { } }
fn add_substs(&mut self, substs: &Substs) { loop { } }
fn add_bounds(&mut self, bounds: &ExistentialBounds) { loop { } }
}
pub fn mk_mach_int<'tcx>(tcx: &ctxt<'tcx>, tm: ast::IntTy)
-> Ty<'tcx> {
loop { }
}
pub fn mk_mach_uint<'tcx>(tcx: &ctxt<'tcx>, tm: ast::UintTy)
-> Ty<'tcx> {
loop { }
}
pub fn mk_mach_float<'tcx>(tcx: &ctxt<'tcx>, tm: ast::FloatTy)
-> Ty<'tcx> {
loop { }
}
pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { loop { } }
pub fn mk_str_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region,
m: ast::Mutability) -> Ty<'tcx> {
loop { }
}
pub fn mk_enum<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId,
substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_ptr<'tcx>(cx: &ctxt<'tcx>, tm: mt<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn mk_mut_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region,
ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_imm_rptr<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region,
ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_mut_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_imm_ptr<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_nil_ptr<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { loop { } }
pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<uint>)
-> Ty<'tcx> {
loop { }
}
pub fn mk_slice<'tcx>(cx: &ctxt<'tcx>, r: &'tcx Region, tm: mt<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn mk_tup<'tcx>(cx: &ctxt<'tcx>, ts: Vec<Ty<'tcx>>) -> Ty<'tcx> {
loop { }
}
pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { loop { } }
pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
opt_def_id: Option<ast::DefId>,
fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>, def_id: ast::DefId,
input_tys: &[Ty<'tcx>], output: Ty<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn mk_trait<'tcx>(cx: &ctxt<'tcx>,
principal: ty::PolyTraitRef<'tcx>,
bounds: ExistentialBounds<'tcx>) -> Ty<'tcx> {
loop { }
}
fn bound_list_is_sorted(bounds: &[ty::PolyProjectionPredicate])
-> bool {
loop { }
}
pub fn sort_bounds_list(bounds: &mut [ty::PolyProjectionPredicate]) {
loop { }
}
pub fn mk_projection<'tcx>(cx: &ctxt<'tcx>,
trait_ref: Rc<ty::TraitRef<'tcx>>,
item_name: ast::Name) -> Ty<'tcx> {
loop { }
}
pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn mk_unboxed_closure<'tcx>(cx: &ctxt<'tcx>,
closure_id: ast::DefId,
region: &'tcx Region,
substs: &'tcx Substs<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
loop { }
}
pub fn mk_int_var<'tcx>(cx: &ctxt<'tcx>, v: IntVid) -> Ty<'tcx> {
loop { }
}
pub fn mk_float_var<'tcx>(cx: &ctxt<'tcx>, v: FloatVid) -> Ty<'tcx> {
loop { }
}
pub fn mk_infer<'tcx>(cx: &ctxt<'tcx>, it: InferTy) -> Ty<'tcx> {
loop { }
}
pub fn mk_param<'tcx>(cx: &ctxt<'tcx>, space: subst::ParamSpace,
index: u32, name: ast::Name) -> Ty<'tcx> {
loop { }
}
pub fn mk_self_type<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> { loop { } }
pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>,
def: &TypeParameterDef) -> Ty<'tcx> {
loop { }
}
pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
impl <'tcx> TyS<'tcx> {
/// Iterator that walks `self` and any types reachable from
/// `self`, in depth-first order. Note that just walks the types
/// that appear in `self`, it does not descend into the fields of
/// structs or variants. For example:
///
/// ```notrust
/// int => { int }
/// Foo<Bar<int>> => { Foo<Bar<int>>, Bar<int>, int }
/// [int] => { [int], int }
/// ```
pub fn walk(&'tcx self) -> TypeWalker<'tcx> { loop { } }
/// Iterator that walks types reachable from `self`, in
/// depth-first order. Note that this is a shallow walk. For
/// example:
///
/// ```notrust
/// int => { }
/// Foo<Bar<int>> => { Bar<int>, int }
/// [int] => { int }
/// ```
pub fn walk_children(&'tcx self) -> TypeWalker<'tcx> { loop { } }
}
pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F) where
F: FnMut(Ty<'tcx>) {
loop { }
}
/// Walks `ty` and any types appearing within `ty`, invoking the
/// callback `f` on each type. If the callback returns false, then the
/// children of the current type are ignored.
///
/// Note: prefer `ty.walk()` where possible.
pub fn maybe_walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F) where
F: FnMut(Ty<'tcx>) -> bool {
loop { }
}
pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>, fldop: F)
-> Ty<'tcx> where F: FnMut(Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
impl ParamTy {
pub fn new(space: subst::ParamSpace, index: u32, name: ast::Name)
-> ParamTy {
loop { }
}
pub fn for_self() -> ParamTy { loop { } }
pub fn for_def(def: &TypeParameterDef) -> ParamTy { loop { } }
pub fn to_ty<'tcx>(self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn is_self(&self) -> bool { loop { } }
}
impl <'tcx> ItemSubsts<'tcx> {
pub fn empty() -> ItemSubsts<'tcx> { loop { } }
pub fn is_noop(&self) -> bool { loop { } }
}
impl <'tcx> ParamBounds<'tcx> {
pub fn empty() -> ParamBounds<'tcx> { loop { } }
}
pub fn type_is_nil(ty: Ty) -> bool { loop { } }
pub fn type_is_error(ty: Ty) -> bool { loop { } }
pub fn type_needs_subst(ty: Ty) -> bool { loop { } }
pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
loop { }
}
pub fn type_is_ty_var(ty: Ty) -> bool { loop { } }
pub fn type_is_bool(ty: Ty) -> bool { loop { } }
pub fn type_is_self(ty: Ty) -> bool { loop { } }
fn type_is_slice(ty: Ty) -> bool { loop { } }
pub fn type_is_vec(ty: Ty) -> bool { loop { } }
pub fn type_is_structural(ty: Ty) -> bool { loop { } }
pub fn type_is_simd(cx: &ctxt, ty: Ty) -> bool { loop { } }
pub fn sequence_element_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn simd_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn simd_size(cx: &ctxt, ty: Ty) -> uint { loop { } }
pub fn type_is_region_ptr(ty: Ty) -> bool { loop { } }
pub fn type_is_unsafe_ptr(ty: Ty) -> bool { loop { } }
pub fn type_is_unique(ty: Ty) -> bool { loop { } }
pub fn type_is_scalar(ty: Ty) -> bool { loop { } }
/// Returns true if this type is a floating point type and false otherwise.
pub fn type_is_floating_point(ty: Ty) -> bool { loop { } }
/// Type contents is how the type checker reasons about kinds.
/// They track what kinds of things are found within a type. You can
/// think of them as kind of an "anti-kind". They track the kinds of values
/// and thinks that are contained in types. Having a larger contents for
/// a type tends to rule that type *out* from various kinds. For example,
/// a type that contains a reference is not sendable.
///
/// The reason we compute type contents and not kinds is that it is
/// easier for me (nmatsakis) to think about what is contained within
/// a type than to think about what is *not* contained within a type.
#[derive(Clone, Copy)]
pub struct TypeContents {
pub bits: u64,
}
macro_rules! def_type_content_sets((
mod $ mname : ident {
$ ( $ name : ident = $ bits : expr
) , + } ) => {
# [ allow ( non_snake_case ) ] mod
$ mname {
use middle :: ty :: TypeContents ;
$ (
# [
allow ( non_upper_case_globals ) ]
pub const $ name : TypeContents =
TypeContents { bits : $ bits } ; )
+ } });
def_type_content_sets! (mod TC {
None = 0b0000_0000__0000_0000__0000 ,
InteriorUnsized = 0b0000_0000__0000_0000__0001
, InteriorUnsafe =
0b0000_0000__0000_0000__0010 , InteriorParam =
0b0000_0000__0000_0000__0100 , OwnsOwned =
0b0000_0000__0000_0001__0000 , OwnsDtor =
0b0000_0000__0000_0010__0000 , OwnsManaged =
0b0000_0000__0000_0100__0000 , OwnsAll =
0b0000_0000__1111_1111__0000 , ReachesBorrowed
= 0b0000_0010__0000_0000__0000 ,
ReachesMutable = 0b0000_1000__0000_0000__0000
, ReachesFfiUnsafe =
0b0010_0000__0000_0000__0000 , ReachesAll =
0b0011_1111__0000_0000__0000 , NeedsDrop =
0b0000_0000__0000_0111__0000 , Nonsized =
0b0000_0000__0000_0000__0001 , Managed =
0b0000_0100__0000_0100__0000 , All =
0b1111_1111__1111_1111__1111 });
impl TypeContents {
pub fn when(&self, cond: bool) -> TypeContents { loop { } }
pub fn intersects(&self, tc: TypeContents) -> bool { loop { } }
pub fn owns_managed(&self) -> bool { loop { } }
pub fn owns_owned(&self) -> bool { loop { } }
pub fn is_sized(&self, _: &ctxt) -> bool { loop { } }
pub fn interior_param(&self) -> bool { loop { } }
pub fn interior_unsafe(&self) -> bool { loop { } }
pub fn interior_unsized(&self) -> bool { loop { } }
pub fn needs_drop(&self, _: &ctxt) -> bool { loop { } }
/// Includes only those bits that still apply when indirected through a `Box` pointer
pub fn owned_pointer(&self) -> TypeContents { loop { } }
/// Includes only those bits that still apply when indirected through a reference (`&`)
pub fn reference(&self, bits: TypeContents) -> TypeContents {
loop { }
}
/// Includes only those bits that still apply when indirected through a managed pointer (`@`)
pub fn managed_pointer(&self) -> TypeContents { loop { } }
/// Includes only those bits that still apply when indirected through an unsafe pointer (`*`)
pub fn unsafe_pointer(&self) -> TypeContents { loop { } }
pub fn union<T, F>(v: &[T], mut f: F) -> TypeContents where
F: FnMut(&T) -> TypeContents {
loop { }
}
pub fn has_dtor(&self) -> bool { loop { } }
}
impl ops::BitOr for TypeContents {type
Output
=
TypeContents;
fn bitor(self, other: TypeContents) -> TypeContents { loop { } }
}
impl ops::BitAnd for TypeContents {type
Output
=
TypeContents;
fn bitand(self, other: TypeContents) -> TypeContents { loop { } }
}
impl ops::Sub for TypeContents {type
Output
=
TypeContents;
fn sub(self, other: TypeContents) -> TypeContents { loop { } }
}
impl fmt::Show for TypeContents {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
pub fn type_interior_is_unsafe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>)
-> bool {
loop { }
}
pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>)
-> TypeContents {
loop { }
}
fn type_impls_bound<'a,
'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
cache: &RefCell<HashMap<Ty<'tcx>, bool>>,
ty: Ty<'tcx>, bound: ty::BuiltinBound,
span: Span) -> bool {
loop { }
}
pub fn type_moves_by_default<'a,
'tcx>(param_env:
&ParameterEnvironment<'a,
'tcx>, span: Span,
ty: Ty<'tcx>) -> bool {
loop { }
}
pub fn type_is_sized<'a,
'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
span: Span, ty: Ty<'tcx>) -> bool {
loop { }
}
pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
loop { }
}
pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>)
-> bool {
loop { }
}
/// Describes whether a type is representable. For types that are not
/// representable, 'SelfRecursive' and 'ContainsRecursive' are used to
/// distinguish between types that are recursive with themselves and types that
/// contain a different recursive type. These cases can therefore be treated
/// differently when reporting errors.
///
/// The ordering of the cases is significant. They are sorted so that cmp::max
/// will keep the "more erroneous" of two values.
#[derive(Copy, PartialOrd, Ord, Eq, PartialEq, Show)]
pub enum Representability {
Representable,
ContainsRecursive,
SelfRecursive,
}
/// Check whether a type is representable. This means it cannot contain unboxed
/// structural recursion. This check is needed for structs and enums.
pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span,
ty: Ty<'tcx>) -> Representability {
loop { }
}
pub fn type_is_trait(ty: Ty) -> bool { loop { } }
pub fn type_trait_info<'tcx>(ty: Ty<'tcx>)
-> Option<&'tcx TyTrait<'tcx>> {
loop { }
}
pub fn type_is_integral(ty: Ty) -> bool { loop { } }
pub fn type_is_fresh(ty: Ty) -> bool { loop { } }
pub fn type_is_uint(ty: Ty) -> bool { loop { } }
pub fn type_is_char(ty: Ty) -> bool { loop { } }
pub fn type_is_bare_fn(ty: Ty) -> bool { loop { } }
pub fn type_is_bare_fn_item(ty: Ty) -> bool { loop { } }
pub fn type_is_fp(ty: Ty) -> bool { loop { } }
pub fn type_is_numeric(ty: Ty) -> bool { loop { } }
pub fn type_is_signed(ty: Ty) -> bool { loop { } }
pub fn type_is_machine(ty: Ty) -> bool { loop { } }
pub fn type_is_c_like_enum(cx: &ctxt, ty: Ty) -> bool { loop { } }
pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
loop { }
}
pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
loop { }
}
pub fn type_content<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> { loop { } }
pub fn unopen_type<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> { loop { } }
pub fn index<'tcx>(ty: Ty<'tcx>) -> Option<Ty<'tcx>> { loop { } }
pub fn array_element_ty<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>)
-> Option<Ty<'tcx>> {
loop { }
}
/// Returns the type of element at index `i` in tuple or tuple-like type `t`.
/// For an enum `t`, `variant` is None only if `t` is a univariant enum.
pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>,
i: uint,
variant: Option<ast::DefId>)
-> Option<Ty<'tcx>> {
loop { }
}
/// Returns the type of element at field `n` in struct or struct-like type `t`.
/// For an enum `t`, `variant` must be some def id.
pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>,
n: ast::Name,
variant: Option<ast::DefId>)
-> Option<Ty<'tcx>> {
loop { }
}
pub fn node_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-> Rc<ty::TraitRef<'tcx>> {
loop { }
}
pub fn try_node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-> Option<Ty<'tcx>> {
loop { }
}
pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-> Ty<'tcx> {
loop { }
}
pub fn node_id_to_type_opt<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-> Option<Ty<'tcx>> {
loop { }
}
pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
-> ItemSubsts<'tcx> {
loop { }
}
pub fn fn_is_variadic(fty: Ty) -> bool { loop { } }
pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
loop { }
}
/// Returns the ABI of the given function.
pub fn ty_fn_abi(fty: Ty) -> abi::Abi { loop { } }
pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder<Vec<Ty<'tcx>>> {
loop { }
}
pub fn ty_closure_store(fty: Ty) -> TraitStore { loop { } }
pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder<FnOutput<'tcx>> {
loop { }
}
pub fn is_fn_ty(fty: Ty) -> bool { loop { } }
pub fn ty_region(tcx: &ctxt, span: Span, ty: Ty) -> Region {
loop { }
}
pub fn free_region_from_def(free_id: ast::NodeId,
def: &RegionParameterDef) -> ty::Region {
loop { }
}
pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
loop { }
}
pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
loop { }
}
pub fn expr_ty_opt<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr)
-> Option<Ty<'tcx>> {
loop { }
}
/// Returns the type of `expr`, considering any `AutoAdjustment`
/// entry recorded for that expression.
///
/// It would almost certainly be better to store the adjusted ty in with
/// the `AutoAdjustment`, but I opted not to do this because it would
/// require serializing and deserializing the type and, although that's not
/// hard to do, I just hate that code so much I didn't want to touch it
/// unless it was to fix it properly, which seemed a distraction from the
/// task at hand! -nmatsakis
pub fn expr_ty_adjusted<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr)
-> Ty<'tcx> {
loop { }
}
pub fn expr_span(cx: &ctxt, id: NodeId) -> Span { loop { } }
pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
loop { }
}
/// See `expr_ty_adjusted`
pub fn adjust_ty<'tcx,
F>(cx: &ctxt<'tcx>, span: Span, expr_id: ast::NodeId,
unadjusted_ty: Ty<'tcx>,
adjustment: Option<&AutoAdjustment<'tcx>>,
mut method_type: F) -> Ty<'tcx> where
F: FnMut(MethodCall) -> Option<Ty<'tcx>> {
loop { }
}
pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>, span: Span,
ty: Ty<'tcx>,
autoref: Option<&AutoRef<'tcx>>)
-> Ty<'tcx> {
loop { }
}
pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>,
kind: &UnsizeKind<'tcx>, span: Span)
-> Ty<'tcx> {
loop { }
}
pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
loop { }
}
pub fn expr_is_lval(tcx: &ctxt, e: &ast::Expr) -> bool { loop { } }
/// We categorize expressions into three kinds. The distinction between
/// lvalue/rvalue is fundamental to the language. The distinction between the
/// two kinds of rvalues is an artifact of trans which reflects how we will
/// generate code for that kind of expression. See trans/expr.rs for more
/// information.
#[derive(Copy)]
pub enum ExprKind {
LvalueExpr,
RvalueDpsExpr,
RvalueDatumExpr,
RvalueStmtExpr,
}
pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
loop { }
}
pub fn stmt_node_id(s: &ast::Stmt) -> ast::NodeId { loop { } }
pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
-> uint {
loop { }
}
pub fn impl_or_trait_item_idx(id: ast::Name,
trait_items: &[ImplOrTraitItem])
-> Option<uint> {
loop { }
}
pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
loop { }
}
impl <'tcx> Repr<'tcx> for ty::type_err<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
/// Explains the source of a type err in a short, human readable way. This is meant to be placed
/// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
/// afterwards to present additional details, particularly when it comes to lifetime-related
/// errors.
pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>)
-> String {
loop { }
}
pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) {
loop { }
}
pub fn provided_source(cx: &ctxt, id: ast::DefId)
-> Option<ast::DefId> {
loop { }
}
pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> Vec<Rc<Method<'tcx>>> {
loop { }
}
/// Helper for looking things up in the various maps that are populated during
/// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of
/// these share the pattern that if the id is local, it should have been loaded
/// into the map by the `typeck::collect` phase. If the def-id is external,
/// then we have to go consult the crate loading code (and cache the result for
/// the future).
fn lookup_locally_or_in_crate_store<V,
F>(descr: &str,
def_id: ast::DefId,
map: &mut DefIdMap<V>,
load_external: F) -> V where
V: Clone, F: FnOnce() -> V {
loop { }
}
pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId,
idx: uint) -> ImplOrTraitItem<'tcx> {
loop { }
}
pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
-> Rc<Vec<ImplOrTraitItem<'tcx>>> {
loop { }
}
pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> ImplOrTraitItem<'tcx> {
loop { }
}
/// Returns true if the given ID refers to an associated type and false if it
/// refers to anything else.
pub fn is_associated_type(cx: &ctxt, id: ast::DefId) -> bool {
loop { }
}
/// Returns the parameter index that the given associated type corresponds to.
pub fn associated_type_parameter_index(cx: &ctxt,
trait_def: &TraitDef,
associated_type_id: ast::DefId)
-> uint {
loop { }
}
#[derive(Copy, PartialEq, Eq)]
pub struct AssociatedTypeInfo {
pub def_id: ast::DefId,
pub index: uint,
pub name: ast::Name,
}
impl PartialOrd for AssociatedTypeInfo {
fn partial_cmp(&self, other: &AssociatedTypeInfo)
-> Option<Ordering> {
loop { }
}
}
impl Ord for AssociatedTypeInfo {
fn cmp(&self, other: &AssociatedTypeInfo) -> Ordering {
loop { }
}
}
pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
-> Rc<Vec<ImplOrTraitItemId>> {
loop { }
}
pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> Option<Rc<TraitRef<'tcx>>> {
loop { }
}
pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef)
-> ast::DefId {
loop { }
}
pub fn try_add_builtin_trait(tcx: &ctxt, trait_def_id: ast::DefId,
builtin_bounds:
&mut EnumSet<BuiltinBound>) -> bool {
//! Checks whether `trait_ref` refers to one of the builtin
//! traits, like `Send`, and adds the corresponding
//! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
//! is a builtin trait.
loop { }
}
pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> { loop { } }
#[derive(Clone)]
pub struct VariantInfo<'tcx> {
pub args: Vec<Ty<'tcx>>,
pub arg_names: Option<Vec<ast::Ident>>,
pub ctor_ty: Option<Ty<'tcx>>,
pub name: ast::Name,
pub id: ast::DefId,
pub disr_val: Disr,
pub vis: Visibility,
}
impl <'tcx> VariantInfo<'tcx> {
/// Creates a new VariantInfo from the corresponding ast representation.
///
/// Does not do any caching of the value in the type context.
pub fn from_ast_variant(cx: &ctxt<'tcx>,
ast_variant: &ast::Variant,
discriminant: Disr) -> VariantInfo<'tcx> {
loop { }
}
}
pub fn substd_enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId,
substs: &Substs<'tcx>)
-> Vec<Rc<VariantInfo<'tcx>>> {
loop { }
}
pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
loop { }
}
#[derive(Copy)]
pub enum DtorKind { NoDtor, TraitDtor(DefId, bool), }
impl DtorKind {
pub fn is_present(&self) -> bool { loop { } }
pub fn has_drop_flag(&self) -> bool { loop { } }
}
pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind { loop { } }
pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool { loop { } }
pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
F: FnOnce(ast_map::PathElems) -> T {
loop { }
}
pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool {
loop { }
}
pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool { loop { } }
pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
loop { }
}
pub fn enum_variant_with_id<'tcx>(cx: &ctxt<'tcx>,
enum_id: ast::DefId,
variant_id: ast::DefId)
-> Rc<VariantInfo<'tcx>> {
loop { }
}
pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
-> TypeScheme<'tcx> {
loop { }
}
/// Given the did of a trait, returns its canonical trait ref.
pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
-> Rc<ty::TraitDef<'tcx>> {
loop { }
}
/// Given a reference to a trait, returns the "superbounds" declared
/// on the trait, with appropriate substitutions applied. Basically,
/// this applies a filter to the where clauses on the trait, returning
/// those that have the form:
///
/// Self : SuperTrait<...>
/// Self : 'region
pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
trait_ref: &PolyTraitRef<'tcx>)
-> Vec<ty::Predicate<'tcx>> {
loop { }
}
pub fn predicates<'tcx>(tcx: &ctxt<'tcx>, param_ty: Ty<'tcx>,
bounds: &ParamBounds<'tcx>)
-> Vec<Predicate<'tcx>> {
loop { }
}
/// Iterate over attributes of a definition.
pub fn each_attr<F>(tcx: &ctxt, did: DefId, mut f: F) -> bool where
F: FnMut(&ast::Attribute) -> bool {
loop { }
}
/// Determine whether an item is annotated with an attribute
pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool {
loop { }
}
/// Determine whether an item is annotated with `#[repr(packed)]`
pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool { loop { } }
/// Determine whether an item is annotated with `#[simd]`
pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool { loop { } }
/// Obtain the representation annotation for a struct definition.
pub fn lookup_repr_hints(tcx: &ctxt, did: DefId)
-> Rc<Vec<attr::ReprAttr>> {
loop { }
}
pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>, struct_id: DefId,
id: DefId, substs: &Substs<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId)
-> Vec<field_ty> {
loop { }
}
pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
loop { }
}
pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId,
substs: &Substs<'tcx>)
-> Vec<field<'tcx>> {
loop { }
}
pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
loop { }
}
#[derive(Copy, Clone)]
pub struct UnboxedClosureUpvar<'tcx> {
pub def: def::Def,
pub span: Span,
pub ty: Ty<'tcx>,
}
pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
closure_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<UnboxedClosureUpvar<'tcx>>> {
loop { }
}
pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>,
op: ast::BinOp) -> bool {
#![allow(non_upper_case_globals)]
loop { }
}
pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
loop { }
}
pub fn each_bound_trait_and_supertraits<'tcx,
F>(tcx: &ctxt<'tcx>,
bounds:
&[PolyTraitRef<'tcx>],
mut f: F) -> bool where
F: FnMut(PolyTraitRef<'tcx>) -> bool {
loop { }
}
pub fn object_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
opt_principal:
Option<&PolyTraitRef<'tcx>>,
others: BuiltinBounds)
-> Vec<ty::Region> {
loop { }
}
/// Given a set of predicates that apply to an object type, returns
/// the region bounds that the (erased) `Self` type must
/// outlive. Precisely *because* the `Self` type is erased, the
/// parameter `erased_self_ty` must be supplied to indicate what type
/// has been used to represent `Self` in the predicates
/// themselves. This should really be a unique type; `FreshTy(0)` is a
/// popular choice (see `object_region_bounds` above).
///
/// Requires that trait definitions have been processed so that we can
/// elaborate predicates and walk supertraits.
pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
erased_self_ty: Ty<'tcx>,
predicates:
Vec<ty::Predicate<'tcx>>)
-> Vec<ty::Region> {
loop { }
}
pub fn get_tydesc_ty<'tcx>(tcx: &ctxt<'tcx>)
-> Result<Ty<'tcx>, String> {
loop { }
}
pub fn item_variances(tcx: &ctxt, item_id: ast::DefId)
-> Rc<ItemVariances> {
loop { }
}
/// Records a trait-to-implementation mapping.
pub fn record_trait_implementation(tcx: &ctxt, trait_def_id: DefId,
impl_def_id: DefId) {
loop { }
}
/// Populates the type context with all the implementations for the given type
/// if necessary.
pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
type_id:
ast::DefId) {
loop { }
}
/// Populates the type context with all the implementations for the given
/// trait if necessary.
pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt,
trait_id:
ast::DefId) {
loop { }
}
/// Given the def_id of an impl, return the def_id of the trait it implements.
/// If it implements no trait, return `None`.
pub fn trait_id_of_impl(tcx: &ctxt, def_id: ast::DefId)
-> Option<ast::DefId> {
loop { }
}
/// If the given def ID describes a method belonging to an impl, return the
/// ID of the impl that the method belongs to. Otherwise, return `None`.
pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
-> Option<ast::DefId> {
loop { }
}
/// If the given def ID describes an item belonging to a trait (either a
/// default method or an implementation of a trait method), return the ID of
/// the trait that the method belongs to. Otherwise, return `None`.
pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId)
-> Option<ast::DefId> {
loop { }
}
/// If the given def ID describes an item belonging to a trait, (either a
/// default method or an implementation of a trait method), return the ID of
/// the method inside trait definition (this means that if the given def ID
/// is already that of the original trait method, then the return value is
/// the same).
/// Otherwise, return `None`.
pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
-> Option<ImplOrTraitItemId> {
loop { }
}
/// Creates a hash of the type `Ty` which will be the same no matter what crate
/// context it's calculated within. This is used by the `type_id` intrinsic.
pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>,
svh: &Svh) -> u64 {
loop { }
}
impl Variance {
pub fn to_string(self) -> &'static str { loop { } }
}
/// Construct a parameter environment suitable for static contexts or other contexts where there
/// are no free type/lifetime parameters in scope.
pub fn empty_parameter_environment<'a, 'tcx>(cx: &'a ctxt<'tcx>)
-> ParameterEnvironment<'a, 'tcx> {
loop { }
}
/// See `ParameterEnvironment` struct def'n for details
pub fn construct_parameter_environment<'a,
'tcx>(tcx: &'a ctxt<'tcx>,
generics:
&ty::Generics<'tcx>,
free_id: ast::NodeId)
-> ParameterEnvironment<'a, 'tcx> {
loop { }
}
impl BorrowKind {
pub fn from_mutbl(m: ast::Mutability) -> BorrowKind { loop { } }
/// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
/// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
/// mutability that is stronger than necessary so that it at least *would permit* the borrow in
/// question.
pub fn to_mutbl_lossy(self) -> ast::Mutability { loop { } }
pub fn to_user_str(&self) -> &'static str { loop { } }
}
impl <'tcx> ctxt<'tcx> {
pub fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause {
loop { }
}
pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
loop { }
}
}
impl <'a, 'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
loop { }
}
fn expr_ty_adjusted(&self, expr: &ast::Expr)
-> mc::McResult<Ty<'tcx>> {
loop { }
}
fn node_method_ty(&self, method_call: ty::MethodCall)
-> Option<Ty<'tcx>> {
loop { }
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>> {
loop { }
}
fn adjustments(&self)
-> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
loop { }
}
fn is_method_call(&self, id: ast::NodeId) -> bool { loop { } }
fn temporary_scope(&self, rvalue_id: ast::NodeId)
-> Option<region::CodeExtent> {
loop { }
}
fn upvar_borrow(&self, upvar_id: ty::UpvarId)
-> Option<ty::UpvarBorrow> {
loop { }
}
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause {
loop { }
}
fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>)
-> bool {
loop { }
}
}
impl <'a, 'tcx> UnboxedClosureTyper<'tcx> for
ty::ParameterEnvironment<'a, 'tcx> {
fn param_env<'b>(&'b self)
-> &'b ty::ParameterEnvironment<'b, 'tcx> {
loop { }
}
fn unboxed_closure_kind(&self, def_id: ast::DefId)
-> ty::UnboxedClosureKind {
loop { }
}
fn unboxed_closure_type(&self, def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx> {
loop { }
}
fn unboxed_closure_upvars(&self, def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<UnboxedClosureUpvar<'tcx>>> {
loop { }
}
}
/// The category of explicit self.
#[derive(Clone, Copy, Eq, PartialEq, Show)]
pub enum ExplicitSelfCategory {
StaticExplicitSelfCategory,
ByValueExplicitSelfCategory,
ByReferenceExplicitSelfCategory(Region, ast::Mutability),
ByBoxExplicitSelfCategory,
}
/// Pushes all the lifetimes in the given type onto the given list. A
/// "lifetime in a type" is a lifetime specified by a reference or a lifetime
/// in a list of type substitutions. This does *not* traverse into nominal
/// types, nor does it resolve fictitious types.
pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
ty: Ty) {
loop { }
}
/// A free variable referred to in a function.
#[derive(Copy, RustcEncodable, RustcDecodable)]
pub struct Freevar {
/// The variable being accessed free.
pub def: def::Def,
pub span: Span,
}
pub type FreevarMap = NodeMap<Vec<Freevar>>;
pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
pub type TraitMap = NodeMap<Vec<DefId>>;
pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
pub fn with_freevars<T, F>(tcx: &ty::ctxt, fid: ast::NodeId, f: F)
-> T where F: FnOnce(&[Freevar]) -> T {
loop { }
}
impl <'tcx> AutoAdjustment<'tcx> {
pub fn is_identity(&self) -> bool { loop { } }
}
impl <'tcx> AutoDerefRef<'tcx> {
pub fn is_identity(&self) -> bool { loop { } }
}
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
/// `scope_id`.
pub fn liberate_late_bound_regions<'tcx,
T>(tcx: &ty::ctxt<'tcx>,
scope: region::CodeExtent,
value: &Binder<T>) -> T where
T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
pub fn count_late_bound_regions<'tcx,
T>(tcx: &ty::ctxt<'tcx>,
value: &Binder<T>) -> uint where
T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
pub fn binds_late_bound_regions<'tcx,
T>(tcx: &ty::ctxt<'tcx>,
value: &Binder<T>) -> bool where
T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
pub fn assert_no_late_bound_regions<'tcx,
T>(tcx: &ty::ctxt<'tcx>,
value: &Binder<T>) -> T where
T: TypeFoldable<'tcx> + Repr<'tcx> + Clone {
loop { }
}
/// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
/// method lookup and a few other places where precise region relationships are not required.
pub fn erase_late_bound_regions<'tcx,
T>(tcx: &ty::ctxt<'tcx>,
value: &Binder<T>) -> T where
T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
/// assigned starting at 1 and increasing monotonically in the order traversed
/// by the fold operation.
///
/// The chief purpose of this function is to canonicalize regions so that two
/// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
/// structurally identical. For example, `for<'a, 'b> fn(&'a int, &'b int)` and
/// `for<'a, 'b> fn(&'b int, &'a int)` will become identical after anonymization.
pub fn anonymize_late_bound_regions<'tcx,
T>(tcx: &ctxt<'tcx>,
sig: &Binder<T>) -> Binder<T>
where T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
/// Replaces the late-bound-regions in `value` that are bound by `value`.
pub fn replace_late_bound_regions<'tcx, T,
F>(tcx: &ty::ctxt<'tcx>,
binder: &Binder<T>, mut mapf: F)
-> (T, FnvHashMap<ty::BoundRegion, ty::Region>) where
T: TypeFoldable<'tcx> + Repr<'tcx>, F: FnMut(BoundRegion) ->
ty::Region {
loop { }
}
impl DebruijnIndex {
pub fn new(depth: u32) -> DebruijnIndex { loop { } }
pub fn shifted(&self, amount: u32) -> DebruijnIndex { loop { } }
}
impl <'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for UnsizeKind<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for AutoDerefRef<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for AutoRef<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for TyTrait<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::Predicate<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for vtable_origin<'tcx> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { loop { } }
}
pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
trait_ref:
&ty::TraitRef<'tcx>,
method: &ty::Method<'tcx>)
-> subst::Substs<'tcx> {
/*!
* Substitutes the values for the receiver's type parameters
* that are found in method, leaving the method's type parameters
* intact.
*/
loop { }
}
#[derive(Copy)]
pub enum CopyImplementationError {
FieldDoesNotImplementCopy(ast::Name),
VariantDoesNotImplementCopy(ast::Name),
TypeIsStructural,
TypeHasDestructor,
}
pub fn can_type_implement_copy<'a,
'tcx>(param_env:
&ParameterEnvironment<'a,
'tcx>, span: Span,
self_type: Ty<'tcx>)
-> Result<(), CopyImplementationError> {
loop { }
}
pub trait RegionEscape {
fn has_escaping_regions(&self) -> bool { loop { } }
fn has_regions_escaping_depth(&self, depth: u32) -> bool;
}
impl <'tcx> RegionEscape for Ty<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for Substs<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx, T: RegionEscape> RegionEscape for VecPerParamSpace<T> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for TypeScheme<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl RegionEscape for Region {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for Generics<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for Predicate<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for TraitRef<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for subst::RegionSubsts {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx, T: RegionEscape> RegionEscape for Binder<T> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for EquatePredicate<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for TraitPredicate<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <T: RegionEscape, U: RegionEscape> RegionEscape for
OutlivesPredicate<T, U> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for ProjectionPredicate<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> RegionEscape for ProjectionTy<'tcx> {
fn has_regions_escaping_depth(&self, depth: u32) -> bool {
loop { }
}
}
impl <'tcx> Repr<'tcx> for ty::ProjectionPredicate<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
pub trait HasProjectionTypes {
fn has_projection_types(&self) -> bool;
}
impl <'tcx, T: HasProjectionTypes> HasProjectionTypes for Vec<T> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx, T: HasProjectionTypes> HasProjectionTypes for
VecPerParamSpace<T> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for ClosureTy<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for UnboxedClosureUpvar<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for ty::GenericBounds<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for Predicate<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for TraitPredicate<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for EquatePredicate<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl HasProjectionTypes for Region {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <T: HasProjectionTypes, U: HasProjectionTypes> HasProjectionTypes
for OutlivesPredicate<T, U> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for ProjectionPredicate<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for ProjectionTy<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for Ty<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for TraitRef<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for subst::Substs<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx, T> HasProjectionTypes for Option<T> where
T: HasProjectionTypes {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx, T> HasProjectionTypes for Rc<T> where
T: HasProjectionTypes {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx, T> HasProjectionTypes for Box<T> where
T: HasProjectionTypes {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <T> HasProjectionTypes for Binder<T> where T: HasProjectionTypes
{
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for FnOutput<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for FnSig<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for field<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
impl <'tcx> HasProjectionTypes for BareFnTy<'tcx> {
fn has_projection_types(&self) -> bool { loop { } }
}
pub trait ReferencesError {
fn references_error(&self) -> bool;
}
impl <T: ReferencesError> ReferencesError for Binder<T> {
fn references_error(&self) -> bool { loop { } }
}
impl <T: ReferencesError> ReferencesError for Rc<T> {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> ReferencesError for TraitPredicate<'tcx> {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> ReferencesError for ProjectionPredicate<'tcx> {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> ReferencesError for TraitRef<'tcx> {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> ReferencesError for Ty<'tcx> {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> ReferencesError for Predicate<'tcx> {
fn references_error(&self) -> bool { loop { } }
}
impl <A, B> ReferencesError for OutlivesPredicate<A, B> where
A: ReferencesError, B: ReferencesError {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> ReferencesError for EquatePredicate<'tcx> {
fn references_error(&self) -> bool { loop { } }
}
impl ReferencesError for Region {
fn references_error(&self) -> bool { loop { } }
}
impl <'tcx> Repr<'tcx> for ClosureTy<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for UnboxedClosureUpvar<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for field<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
}
pub mod ty_fold {
//! Generalized type folding mechanism. The setup is a bit convoluted
//! but allows for convenient usage. Let T be an instance of some
//! "foldable type" (one which implements `TypeFoldable`) and F be an
//! instance of a "folder" (a type which implements `TypeFolder`). Then
//! the setup is intended to be:
//!
//! T.fold_with(F) --calls--> F.fold_T(T) --calls--> super_fold_T(F, T)
//!
//! This way, when you define a new folder F, you can override
//! `fold_T()` to customize the behavior, and invoke `super_fold_T()`
//! to get the original behavior. Meanwhile, to actually fold
//! something, you can just write `T.fold_with(F)`, which is
//! convenient. (Note that `fold_with` will also transparently handle
//! things like a `Vec<T>` where T is foldable and so on.)
//!
//! In this ideal setup, the only function that actually *does*
//! anything is `super_fold_T`, which traverses the type `T`. Moreover,
//! `super_fold_T` should only ever call `T.fold_with()`.
//!
//! In some cases, we follow a degenerate pattern where we do not have
//! a `fold_T` nor `super_fold_T` method. Instead, `T.fold_with`
//! traverses the structure directly. This is suboptimal because the
//! behavior cannot be overridden, but it's much less work to implement.
//! If you ever *do* need an override that doesn't exist, it's not hard
//! to convert the degenerate pattern into the proper thing.
use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::ty::{self, Ty};
use middle::traits;
use std::rc::Rc;
use syntax::owned_slice::OwnedSlice;
use util::ppaux::Repr;
/// The TypeFoldable trait is implemented for every type that can be folded.
/// Basically, every type that has a corresponding method in TypeFolder.
pub trait TypeFoldable<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
}
/// The TypeFolder trait defines the actual *folding*. There is a
/// method defined for every foldable type. Each of these has a
/// default implementation that does an "identity" fold. Within each
/// identity fold, it should invoke `foo.fold_with(self)` to fold each
/// sub-item.
pub trait TypeFolder<'tcx>: Sized {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
/// Invoked by the `super_*` routines when we enter a region
/// binding level (for example, when entering a function
/// signature). This is used by clients that want to track the
/// Debruijn index nesting level.
fn enter_region_binder(&mut self) { loop { } }
/// Invoked by the `super_*` routines when we exit a region
/// binding level. This is used by clients that want to
/// track the Debruijn index nesting level.
fn exit_region_binder(&mut self) { loop { } }
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
where T: TypeFoldable<'tcx> + Repr<'tcx> {
loop { }
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { loop { } }
fn fold_mt(&mut self, t: &ty::mt<'tcx>) -> ty::mt<'tcx> {
loop { }
}
fn fold_trait_ref(&mut self, t: &ty::TraitRef<'tcx>)
-> ty::TraitRef<'tcx> {
loop { }
}
fn fold_substs(&mut self, substs: &subst::Substs<'tcx>)
-> subst::Substs<'tcx> {
loop { }
}
fn fold_fn_sig(&mut self, sig: &ty::FnSig<'tcx>)
-> ty::FnSig<'tcx> {
loop { }
}
fn fold_output(&mut self, output: &ty::FnOutput<'tcx>)
-> ty::FnOutput<'tcx> {
loop { }
}
fn fold_bare_fn_ty(&mut self, fty: &ty::BareFnTy<'tcx>)
-> ty::BareFnTy<'tcx> {
loop { }
}
fn fold_closure_ty(&mut self, fty: &ty::ClosureTy<'tcx>)
-> ty::ClosureTy<'tcx> {
loop { }
}
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
fn fold_trait_store(&mut self, s: ty::TraitStore)
-> ty::TraitStore {
loop { }
}
fn fold_existential_bounds(&mut self,
s: &ty::ExistentialBounds<'tcx>)
-> ty::ExistentialBounds<'tcx> {
loop { }
}
fn fold_autoref(&mut self, ar: &ty::AutoRef<'tcx>)
-> ty::AutoRef<'tcx> {
loop { }
}
fn fold_item_substs(&mut self, i: ty::ItemSubsts<'tcx>)
-> ty::ItemSubsts<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for () {
fn fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) { loop { } }
}
impl <'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>>
TypeFoldable<'tcx> for (T, U) {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> (T, U) {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> Option<T> {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> Rc<T> {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> Box<T> {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> Vec<T> {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx> + Repr<'tcx>> TypeFoldable<'tcx> for
ty::Binder<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::Binder<T> {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
OwnedSlice<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> OwnedSlice<T> {
loop { }
}
}
impl <'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
VecPerParamSpace<T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> VecPerParamSpace<T> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::TraitStore {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::TraitStore {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> Ty<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::BareFnTy<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::BareFnTy<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::ClosureTy<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::ClosureTy<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::mt<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::mt<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::FnOutput<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::FnOutput<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::FnSig<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::TraitRef<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::field<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::field<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::Region {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::Region {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> subst::Substs<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::ItemSubsts<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::AutoRef<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::AutoRef<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::MethodOrigin<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::MethodOrigin<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::vtable_origin<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::vtable_origin<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds {
fn fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F)
-> ty::BuiltinBounds {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::ExistentialBounds<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::ParamBounds<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::ParamBounds<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::TypeParameterDef<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::RegionParameterDef {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::Generics<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::Predicate<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::ProjectionPredicate<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::ProjectionTy<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::GenericBounds<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::GenericBounds<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::UnsizeKind<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::UnsizeKind<'tcx> {
loop { }
}
}
impl <'tcx, O> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
where O: TypeFoldable<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> traits::Obligation<'tcx, O> {
loop { }
}
}
impl <'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
traits::VtableImplData<'tcx, N> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> traits::VtableImplData<'tcx, N> {
loop { }
}
}
impl <'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
traits::VtableBuiltinData<N> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> traits::VtableBuiltinData<N> {
loop { }
}
}
impl <'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
traits::Vtable<'tcx, N> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> traits::Vtable<'tcx, N> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> traits::VtableObjectData<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::EquatePredicate<'tcx> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::TraitPredicate<'tcx> {
loop { }
}
}
impl <'tcx, T, U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T, U>
where T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::OutlivesPredicate<T, U> {
loop { }
}
}
impl <'tcx> TypeFoldable<'tcx> for ty::UnboxedClosureUpvar<'tcx> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F)
-> ty::UnboxedClosureUpvar<'tcx> {
loop { }
}
}
pub fn super_fold_binder<'tcx, T,
U>(this: &mut T, binder: &ty::Binder<U>)
-> ty::Binder<U> where T: TypeFolder<'tcx>, U: TypeFoldable<'tcx> {
loop { }
}
pub fn super_fold_ty<'tcx,
T: TypeFolder<'tcx>>(this: &mut T, ty: Ty<'tcx>)
-> Ty<'tcx> {
loop { }
}
pub fn super_fold_substs<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
substs:
&subst::Substs<'tcx>)
-> subst::Substs<'tcx> {
loop { }
}
pub fn super_fold_fn_sig<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
sig: &ty::FnSig<'tcx>)
-> ty::FnSig<'tcx> {
loop { }
}
pub fn super_fold_output<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
output:
&ty::FnOutput<'tcx>)
-> ty::FnOutput<'tcx> {
loop { }
}
pub fn super_fold_bare_fn_ty<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
fty:
&ty::BareFnTy<'tcx>)
-> ty::BareFnTy<'tcx> {
loop { }
}
pub fn super_fold_closure_ty<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
fty:
&ty::ClosureTy<'tcx>)
-> ty::ClosureTy<'tcx> {
loop { }
}
pub fn super_fold_trait_ref<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
t:
&ty::TraitRef<'tcx>)
-> ty::TraitRef<'tcx> {
loop { }
}
pub fn super_fold_mt<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
mt: &ty::mt<'tcx>)
-> ty::mt<'tcx> {
loop { }
}
pub fn super_fold_trait_store<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
trait_store:
ty::TraitStore)
-> ty::TraitStore {
loop { }
}
pub fn super_fold_existential_bounds<'tcx,
T: TypeFolder<'tcx>>(this:
&mut T,
bounds:
&ty::ExistentialBounds<'tcx>)
-> ty::ExistentialBounds<'tcx> {
loop { }
}
pub fn super_fold_autoref<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
autoref:
&ty::AutoRef<'tcx>)
-> ty::AutoRef<'tcx> {
loop { }
}
pub fn super_fold_item_substs<'tcx,
T: TypeFolder<'tcx>>(this: &mut T,
substs:
ty::ItemSubsts<'tcx>)
-> ty::ItemSubsts<'tcx> {
loop { }
}
pub struct BottomUpFolder<'a, 'tcx:'a, F> where F: FnMut(Ty<'tcx>) ->
Ty<'tcx> {
pub tcx: &'a ty::ctxt<'tcx>,
pub fldop: F,
}
impl <'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F>
where F: FnMut(Ty<'tcx>) -> Ty<'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { loop { } }
}
/// Folds over the substructure of a type, visiting its component
/// types and all regions that occur *free* within it.
///
/// That is, `Ty` can contain function or method types that bind
/// regions at the call site (`ReLateBound`), and occurrences of
/// regions (aka "lifetimes") that are bound within a type are not
/// visited by this folder; only regions that occur free will be
/// visited by `fld_r`.
pub struct RegionFolder<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
current_depth: u32,
fld_r: &'a mut (FnMut(ty::Region, u32) -> ty::Region+ 'a),
}
impl <'a, 'tcx> RegionFolder<'a, 'tcx> {
pub fn new<F>(tcx: &'a ty::ctxt<'tcx>, fld_r: &'a mut F)
-> RegionFolder<'a, 'tcx> where F: FnMut(ty::Region, u32) ->
ty::Region {
loop { }
}
}
pub fn collect_regions<'tcx, T>(tcx: &ty::ctxt<'tcx>, value: &T)
-> Vec<ty::Region> where T: TypeFoldable<'tcx> {
loop { }
}
pub fn fold_regions<'tcx, T,
F>(tcx: &ty::ctxt<'tcx>, value: &T, mut f: F) -> T
where F: FnMut(ty::Region, u32) -> ty::Region,
T: TypeFoldable<'tcx> {
loop { }
}
impl <'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn enter_region_binder(&mut self) { loop { } }
fn exit_region_binder(&mut self) { loop { } }
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
}
pub struct RegionEraser<'a, 'tcx:'a> {
tcx: &'a ty::ctxt<'tcx>,
}
pub fn erase_regions<'tcx,
T: TypeFoldable<'tcx>>(tcx: &ty::ctxt<'tcx>,
t: T) -> T {
loop { }
}
impl <'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
fn tcx(&self) -> &ty::ctxt<'tcx> { loop { } }
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
loop { }
}
}
pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
loop { }
}
pub fn shift_regions<'tcx, T: TypeFoldable<'tcx> +
Repr<'tcx>>(tcx: &ty::ctxt<'tcx>, amount: u32,
value: &T) -> T {
loop { }
}
}
pub mod ty_walk {
//! An iterator over the type substructure.
use middle::ty::{self, Ty};
use std::iter::Iterator;
pub struct TypeWalker<'tcx> {
stack: Vec<Ty<'tcx>>,
last_subtree: uint,
}
impl <'tcx> TypeWalker<'tcx> {
pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> { loop { } }
fn push_subtypes(&mut self, parent_ty: Ty<'tcx>) { loop { } }
fn push_sig_subtypes(&mut self, sig: &ty::PolyFnSig<'tcx>) {
loop { }
}
fn push_reversed(&mut self, tys: &[Ty<'tcx>]) { loop { } }
/// Skips the subtree of types corresponding to the last type
/// returned by `next()`.
///
/// Example: Imagine you are walking `Foo<Bar<int>, uint>`.
///
/// ```rust
/// let mut iter: TypeWalker = ...;
/// iter.next(); // yields Foo
/// iter.next(); // yields Bar<int>
/// iter.skip_current_subtree(); // skips int
/// iter.next(); // yields uint
/// ```
pub fn skip_current_subtree(&mut self) { loop { } }
}
impl <'tcx> Iterator for TypeWalker<'tcx> {type
Item
=
Ty<'tcx>;
fn next(&mut self) -> Option<Ty<'tcx>> { loop { } }
}
}
pub mod weak_lang_items {
//! Validity checking for weak lang items
use session::config;
use session::Session;
use metadata::csearch;
use middle::lang_items;
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::visit::Visitor;
use syntax::visit;
use std::collections::HashSet;
macro_rules! weak_lang_items((
$ (
$ name : ident , $ item : ident , $ sym :
ident ; ) * ) => (
struct Context < 'a > {
sess : & 'a Session , items : & 'a mut
lang_items :: LanguageItems , }
/// Checks the crate for usage of weak lang items, returning a vector of all the
/// language items required by this crate, but not defined yet.
pub fn check_crate (
krate : & ast :: Crate , sess : & Session
, items : & mut lang_items ::
LanguageItems ) {
if items . stack_exhausted ( ) . is_none
( ) {
items . missing . push (
lang_items :: StackExhaustedLangItem ) ;
} if items . eh_personality ( ) .
is_none ( ) {
items . missing . push (
lang_items :: EhPersonalityLangItem ) ; }
{
let mut cx = Context {
sess : sess , items : items } ; visit ::
walk_crate ( & mut cx , krate ) ; }
verify ( sess , items ) ; } pub fn
link_name (
attrs : & [ ast :: Attribute ] ) ->
Option < InternedString > {
lang_items :: extract ( attrs ) .
and_then (
| name | {
$ (
if name . get ( ) == stringify ! (
$ name ) {
Some (
InternedString :: new (
stringify ! ( $ sym ) ) ) } else ) * {
None } } ) } fn verify (
sess : & Session , items : & lang_items
:: LanguageItems ) {
let needs_check = sess . crate_types .
borrow ( ) . iter ( ) . any (
| kind | {
match * kind {
config :: CrateTypeDylib | config ::
CrateTypeExecutable | config ::
CrateTypeStaticlib => true , config ::
CrateTypeRlib => false , } } ) ; if !
needs_check { return } let mut missing =
HashSet :: new ( ) ; sess . cstore .
iter_crate_data (
| cnum , _ | {
for item in csearch ::
get_missing_lang_items (
& sess . cstore , cnum ) . iter ( ) {
missing . insert ( * item ) ; } } ) ; $ (
if missing . contains (
& lang_items :: $ item ) && items . $
name ( ) . is_none ( ) {
sess . err (
format ! (
"language item required, but not found: `{}`"
, stringify ! ( $ name ) ) . as_slice (
) ) ; } ) * } impl < 'a > Context < 'a >
{
fn register (
& mut self , name : & str , span : Span )
{
$ (
if name == stringify ! ( $ name ) {
if self . items . $ name ( ) . is_none (
) {
self . items . missing . push (
lang_items :: $ item ) ; } } else ) * {
self . sess . span_err (
span , format ! (
"unknown external lang item: `{}`" , name
) . as_slice ( ) ) ; } } } impl < 'a ,
'v > Visitor < 'v > for Context < 'a > {
fn visit_foreign_item (
& mut self , i : & ast :: ForeignItem ) {
match lang_items :: extract (
i . attrs . as_slice ( ) ) {
None => { } Some ( lang_item ) => self .
register (
lang_item . get ( ) , i . span ) , }
visit :: walk_foreign_item ( self , i ) }
} ));
weak_lang_items! (panic_fmt , PanicFmtLangItem , rust_begin_unwind ;
stack_exhausted , StackExhaustedLangItem ,
rust_stack_exhausted ; eh_personality ,
EhPersonalityLangItem , rust_eh_personality ;);
}
}
pub mod metadata {
pub mod common {
#![allow(non_camel_case_types, non_upper_case_globals)]
pub use self::astencode_tag::*;
use std::mem;
use back::svh::Svh;
pub const tag_items: uint = 0;
pub const tag_paths_data_name: uint = 1;
pub const tag_def_id: uint = 2;
pub const tag_items_data: uint = 3;
pub const tag_items_data_item: uint = 4;
pub const tag_items_data_item_family: uint = 5;
pub const tag_items_data_item_type: uint = 7;
pub const tag_items_data_item_symbol: uint = 8;
pub const tag_items_data_item_variant: uint = 9;
pub const tag_items_data_parent_item: uint = 10;
pub const tag_items_data_item_is_tuple_struct_ctor: uint = 11;
pub const tag_index: uint = 12;
pub const tag_index_buckets: uint = 13;
pub const tag_index_buckets_bucket: uint = 14;
pub const tag_index_buckets_bucket_elt: uint = 15;
pub const tag_index_table: uint = 16;
pub const tag_meta_item_name_value: uint = 17;
pub const tag_meta_item_name: uint = 18;
pub const tag_meta_item_value: uint = 19;
pub const tag_attributes: uint = 20;
pub const tag_attribute: uint = 21;
pub const tag_meta_item_word: uint = 22;
pub const tag_meta_item_list: uint = 23;
pub const tag_crate_deps: uint = 24;
pub const tag_crate_dep: uint = 25;
pub const tag_crate_hash: uint = 26;
pub const tag_crate_crate_name: uint = 27;
pub const tag_crate_dep_crate_name: uint = 29;
pub const tag_crate_dep_hash: uint = 30;
pub const tag_mod_impl: uint = 31;
pub const tag_item_trait_item: uint = 32;
pub const tag_item_trait_ref: uint = 33;
pub const tag_item_super_trait_ref: uint = 34;
pub const tag_disr_val: uint = 35;
pub const tag_path: uint = 36;
pub const tag_path_len: uint = 37;
pub const tag_path_elem_mod: uint = 38;
pub const tag_path_elem_name: uint = 39;
pub const tag_item_field: uint = 40;
pub const tag_item_field_origin: uint = 41;
pub const tag_item_variances: uint = 42;
pub const tag_item_impl_item: uint = 48;
pub const tag_item_trait_method_explicit_self: uint = 49;
pub const tag_items_data_item_reexport: uint = 56;
pub const tag_items_data_item_reexport_def_id: uint = 57;
pub const tag_items_data_item_reexport_name: uint = 58;
#[derive(Copy, PartialEq)]
#[repr(uint)]
pub enum astencode_tag {
tag_ast = 64,
tag_tree = 65,
tag_id_range = 66,
tag_table = 67,
tag_table_id = 68,
tag_table_val = 69,
tag_table_def = 70,
tag_table_node_type = 71,
tag_table_item_subst = 72,
tag_table_freevars = 73,
tag_table_tcache = 74,
tag_table_param_defs = 75,
tag_table_mutbl = 76,
tag_table_last_use = 77,
tag_table_spill = 78,
tag_table_method_map = 79,
tag_table_vtable_map = 80,
tag_table_adjustments = 81,
tag_table_moves_map = 82,
tag_table_capture_map = 83,
tag_table_unboxed_closures = 84,
tag_table_upvar_borrow_map = 85,
tag_table_capture_modes = 86,
tag_table_object_cast_map = 87,
}
static first_astencode_tag: uint = tag_ast as uint;
static last_astencode_tag: uint = tag_table_object_cast_map as uint;
impl astencode_tag {
pub fn from_uint(value: uint) -> Option<astencode_tag> {
loop { }
}
}
pub const tag_item_trait_item_sort: uint = 96;
pub const tag_item_trait_parent_sort: uint = 97;
pub const tag_item_impl_type_basename: uint = 98;
pub const tag_crate_triple: uint = 102;
pub const tag_dylib_dependency_formats: uint = 103;
pub const tag_lang_items: uint = 112;
pub const tag_lang_items_item: uint = 113;
pub const tag_lang_items_item_id: uint = 114;
pub const tag_lang_items_item_node_id: uint = 115;
pub const tag_lang_items_missing: uint = 116;
pub const tag_item_unnamed_field: uint = 117;
pub const tag_items_data_item_visibility: uint = 118;
pub const tag_item_method_tps: uint = 121;
pub const tag_item_method_fty: uint = 122;
pub const tag_mod_child: uint = 123;
pub const tag_misc_info: uint = 124;
pub const tag_misc_info_crate_items: uint = 125;
pub const tag_item_method_provided_source: uint = 126;
pub const tag_item_impl_vtables: uint = 127;
pub const tag_impls: uint = 128;
pub const tag_impls_impl: uint = 129;
pub const tag_items_data_item_inherent_impl: uint = 130;
pub const tag_items_data_item_extension_impl: uint = 131;
pub const tag_native_libraries: uint = 135;
pub const tag_native_libraries_lib: uint = 136;
pub const tag_native_libraries_name: uint = 137;
pub const tag_native_libraries_kind: uint = 138;
pub const tag_plugin_registrar_fn: uint = 139;
pub const tag_method_argument_names: uint = 142;
pub const tag_method_argument_name: uint = 143;
pub const tag_reachable_extern_fns: uint = 144;
pub const tag_reachable_extern_fn_id: uint = 145;
pub const tag_items_data_item_stability: uint = 146;
pub const tag_items_data_item_repr: uint = 147;
#[derive(Clone, Show)]
pub struct LinkMeta {
pub crate_name: String,
pub crate_hash: Svh,
}
pub const tag_unboxed_closures: uint = 149;
pub const tag_unboxed_closure: uint = 150;
pub const tag_unboxed_closure_type: uint = 151;
pub const tag_unboxed_closure_kind: uint = 152;
pub const tag_struct_fields: uint = 153;
pub const tag_struct_field: uint = 154;
pub const tag_struct_field_id: uint = 155;
pub const tag_attribute_is_sugared_doc: uint = 156;
pub const tag_trait_def_bounds: uint = 157;
pub const tag_items_data_region: uint = 158;
pub const tag_region_param_def: uint = 160;
pub const tag_region_param_def_ident: uint = 161;
pub const tag_region_param_def_def_id: uint = 162;
pub const tag_region_param_def_space: uint = 163;
pub const tag_region_param_def_index: uint = 164;
pub const tag_type_param_def: uint = 165;
pub const tag_item_generics: uint = 166;
pub const tag_method_ty_generics: uint = 167;
pub const tag_predicate: uint = 168;
pub const tag_predicate_space: uint = 169;
pub const tag_predicate_data: uint = 176;
pub const tag_unsafety: uint = 177;
pub const tag_associated_type_names: uint = 178;
pub const tag_associated_type_name: uint = 179;
pub const tag_polarity: uint = 180;
pub const tag_macro_defs: uint = 181;
pub const tag_macro_def: uint = 182;
pub const tag_macro_def_body: uint = 183;
}
pub mod tyencode {
#![allow(unused_must_use)]
#![allow(non_camel_case_types)]
use std::cell::RefCell;
use middle::region;
use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::ty::ParamTy;
use middle::ty::{self, Ty};
use util::nodemap::FnvHashMap;
use syntax::abi::Abi;
use syntax::ast;
use syntax::diagnostic::SpanHandler;
use syntax::parse::token;
use rbml::io::SeekableMemWriter;
macro_rules! mywrite(( $ ( $ arg : tt ) * ) => (
{ write ! ( $ ( $ arg ) * ) ; } ));
pub struct ctxt<'a, 'tcx:'a> {
pub diag: &'a SpanHandler,
pub ds: fn(ast::DefId) -> String,
pub tcx: &'a ty::ctxt<'tcx>,
pub abbrevs: &'a abbrev_map<'tcx>,
}
pub struct ty_abbrev {
s: String,
}
pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
pub fn enc_ty<'a,
'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
t: Ty<'tcx>) {
loop { }
}
fn enc_mutability(w: &mut SeekableMemWriter, mt: ast::Mutability) {
loop { }
}
fn enc_mt<'a,
'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
mt: ty::mt<'tcx>) {
loop { }
}
fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F)
where F: FnOnce(&mut SeekableMemWriter, T) {
loop { }
}
fn enc_vec_per_param_space<'a, 'tcx, T,
F>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
v: &VecPerParamSpace<T>, mut op: F)
where F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T) {
loop { }
}
pub fn enc_substs<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
substs: &subst::Substs<'tcx>) {
loop { }
}
fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt,
substs: &subst::RegionSubsts) {
loop { }
}
pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt,
r: ty::Region) {
loop { }
}
fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt,
scope: region::CodeExtent) {
loop { }
}
fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt,
br: ty::BoundRegion) {
loop { }
}
pub fn enc_trait_ref<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
s: &ty::TraitRef<'tcx>) {
loop { }
}
pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt,
s: ty::TraitStore) {
loop { }
}
fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
loop { }
}
fn enc_abi(w: &mut SeekableMemWriter, abi: Abi) { loop { } }
fn enc_onceness(w: &mut SeekableMemWriter, o: ast::Onceness) {
loop { }
}
pub fn enc_bare_fn_ty<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
ft: &ty::BareFnTy<'tcx>) {
loop { }
}
pub fn enc_closure_ty<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
ft: &ty::ClosureTy<'tcx>) {
loop { }
}
fn enc_fn_sig<'a,
'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
fsig: &ty::PolyFnSig<'tcx>) {
loop { }
}
pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt,
bs: &ty::BuiltinBounds) {
loop { }
}
pub fn enc_existential_bounds<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
bs:
&ty::ExistentialBounds<'tcx>) {
loop { }
}
pub fn enc_bounds<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
bs: &ty::ParamBounds<'tcx>) {
loop { }
}
pub fn enc_type_param_def<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
loop { }
}
pub fn enc_predicate<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
p: &ty::Predicate<'tcx>) {
loop { }
}
fn enc_projection_predicate<'a,
'tcx>(w: &mut SeekableMemWriter,
cx: &ctxt<'a, 'tcx>,
data:
&ty::ProjectionPredicate<'tcx>) {
loop { }
}
}
pub mod tydecode {
#![allow(non_camel_case_types)]
pub use self::DefIdSource::*;
use middle::region;
use middle::subst;
use middle::subst::VecPerParamSpace;
use middle::ty::{self, AsPredicate, Ty};
use std::rc::Rc;
use std::str;
use syntax::abi;
use syntax::ast;
use syntax::parse::token;
#[derive(Copy, Show)]
pub enum DefIdSource {
NominalType,
TypeWithId,
TypeParameter,
RegionParameter,
UnboxedClosureSource,
}
pub struct PState<'a, 'tcx:'a> {
data: &'a [u8],
krate: ast::CrateNum,
pos: uint,
tcx: &'a ty::ctxt<'tcx>,
}
fn peek(st: &PState) -> char { loop { } }
fn next(st: &mut PState) -> char { loop { } }
fn next_byte(st: &mut PState) -> u8 { loop { } }
fn scan<R, F, G>(st: &mut PState, mut is_last: F, op: G) -> R where
F: FnMut(char) -> bool, G: FnOnce(&[u8]) -> R {
loop { }
}
pub fn parse_ident(st: &mut PState, last: char) -> ast::Ident {
loop { }
}
pub fn parse_name(st: &mut PState, last: char) -> ast::Name {
loop { }
}
fn parse_name_<F>(st: &mut PState, is_last: F) -> ast::Name where
F: FnMut(char) -> bool {
loop { }
}
pub fn parse_state_from_data<'a,
'tcx>(data: &'a [u8],
crate_num: ast::CrateNum,
pos: uint, tcx: &'a ty::ctxt<'tcx>)
-> PState<'a, 'tcx> {
loop { }
}
fn data_log_string(data: &[u8], pos: uint) -> String { loop { } }
pub fn parse_ty_closure_data<'tcx,
F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>,
conv: F) -> ty::ClosureTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_ty_data<'tcx,
F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
-> Ty<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_region_data<F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt, conv: F)
-> ty::Region where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_bare_fn_ty_data<'tcx,
F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>,
conv: F) -> ty::BareFnTy<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_trait_ref_data<'tcx,
F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>,
conv: F) -> Rc<ty::TraitRef<'tcx>>
where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_substs_data<'tcx,
F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
-> subst::Substs<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
pub fn parse_bounds_data<'tcx,
F>(data: &[u8], crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::ParamBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
pub fn parse_existential_bounds_data<'tcx,
F>(data: &[u8],
crate_num: ast::CrateNum,
pos: uint,
tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::ExistentialBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_builtin_bounds_data<F>(data: &[u8],
crate_num: ast::CrateNum,
pos: uint, tcx: &ty::ctxt,
conv: F) -> ty::BuiltinBounds
where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_size(st: &mut PState) -> Option<uint> { loop { } }
fn parse_trait_store_<F>(st: &mut PState, conv: &mut F)
-> ty::TraitStore where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_vec_per_param_space<'a, 'tcx, T,
F>(st: &mut PState<'a, 'tcx>, mut f: F)
-> VecPerParamSpace<T> where F: FnMut(&mut PState<'a, 'tcx>) -> T {
loop { }
}
fn parse_substs<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> subst::Substs<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_substs_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> subst::Substs<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_region_substs_<F>(st: &mut PState, conv: &mut F)
-> subst::RegionSubsts where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_bound_region_<F>(st: &mut PState, conv: &mut F)
-> ty::BoundRegion where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_region<F>(st: &mut PState, mut conv: F) -> ty::Region where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_scope(st: &mut PState) -> region::CodeExtent { loop { } }
fn parse_opt<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, f: F)
-> Option<T> where F: FnOnce(&mut PState<'a, 'tcx>) -> T {
loop { }
}
fn parse_str(st: &mut PState, term: char) -> String { loop { } }
fn parse_trait_ref<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> Rc<ty::TraitRef<'tcx>> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_trait_ref_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> Rc<ty::TraitRef<'tcx>> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_ty<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> Ty<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> Ty<'tcx> where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_mutability(st: &mut PState) -> ast::Mutability { loop { } }
fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::mt<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F)
-> ast::DefId where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_uint(st: &mut PState) -> uint { loop { } }
fn parse_u32(st: &mut PState) -> u32 { loop { } }
fn parse_param_space(st: &mut PState) -> subst::ParamSpace {
loop { }
}
fn parse_hex(st: &mut PState) -> uint { loop { } }
fn parse_unsafety(c: char) -> ast::Unsafety { loop { } }
fn parse_abi_set(st: &mut PState) -> abi::Abi { loop { } }
fn parse_onceness(c: char) -> ast::Onceness { loop { } }
fn parse_closure_ty<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::ClosureTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_closure_ty_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::ClosureTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_bare_fn_ty<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::BareFnTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_bare_fn_ty_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::BareFnTy<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_sig_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::PolyFnSig<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
pub fn parse_def_id(buf: &[u8]) -> ast::DefId { loop { } }
pub fn parse_predicate_data<'tcx,
F>(data: &[u8], start: uint,
crate_num: ast::CrateNum,
tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::Predicate<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
pub fn parse_predicate<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::Predicate<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_predicate_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::Predicate<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_projection_predicate_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>,
conv: &mut F)
-> ty::ProjectionPredicate<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
pub fn parse_type_param_def_data<'tcx,
F>(data: &[u8], start: uint,
crate_num: ast::CrateNum,
tcx: &ty::ctxt<'tcx>, conv: F)
-> ty::TypeParameterDef<'tcx> where F: FnMut(DefIdSource, ast::DefId)
-> ast::DefId {
loop { }
}
fn parse_type_param_def<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::TypeParameterDef<'tcx> where F: FnMut(DefIdSource, ast::DefId)
-> ast::DefId {
loop { }
}
fn parse_type_param_def_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::TypeParameterDef<'tcx> where F: FnMut(DefIdSource, ast::DefId)
-> ast::DefId {
loop { }
}
fn parse_existential_bounds<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::ExistentialBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_existential_bounds_<'a, 'tcx,
F>(st: &mut PState<'a, 'tcx>,
conv: &mut F)
-> ty::ExistentialBounds<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId {
loop { }
}
fn parse_builtin_bounds<F>(st: &mut PState, mut _conv: F)
-> ty::BuiltinBounds where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_builtin_bounds_<F>(st: &mut PState, _conv: &mut F)
-> ty::BuiltinBounds where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_bounds<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, mut conv: F)
-> ty::ParamBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
fn parse_bounds_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
-> ty::ParamBounds<'tcx> where F: FnMut(DefIdSource, ast::DefId) ->
ast::DefId {
loop { }
}
}
pub mod encoder {
#![allow(unused_must_use)]
#![allow(non_camel_case_types)]
pub use self::InlinedItemRef::*;
use back::svh::Svh;
use session::config;
use metadata::common::*;
use metadata::cstore;
use metadata::decoder;
use metadata::tyencode;
use middle::def;
use middle::ty::{lookup_item_type};
use middle::ty::{self, Ty};
use middle::stability;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
use serialize::Encodable;
use std::cell::RefCell;
use std::hash::{Hash, Hasher, SipHasher};
use syntax::abi;
use syntax::ast::{self, DefId, NodeId};
use syntax::ast_map::{PathElem, PathElems};
use syntax::ast_map;
use syntax::ast_util::*;
use syntax::ast_util;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::SpanHandler;
use syntax::parse::token::special_idents;
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::visit::Visitor;
use syntax::visit;
use syntax;
use rbml::writer;
use rbml::io::SeekableMemWriter;
/// A borrowed version of `ast::InlinedItem`.
pub enum InlinedItemRef<'a> {
IIItemRef(&'a ast::Item),
IITraitItemRef(DefId, &'a ast::TraitItem),
IIImplItemRef(DefId, &'a ast::ImplItem),
IIForeignRef(&'a ast::ForeignItem),
}
pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
pub type EncodeInlinedItem<'a> =
Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef)+ 'a>;
pub struct EncodeParams<'a, 'tcx:'a> {
pub diag: &'a SpanHandler,
pub tcx: &'a ty::ctxt<'tcx>,
pub reexports: &'a def::ExportMap,
pub item_symbols: &'a RefCell<NodeMap<String>>,
pub link_meta: &'a LinkMeta,
pub cstore: &'a cstore::CStore,
pub encode_inlined_item: EncodeInlinedItem<'a>,
pub reachable: &'a NodeSet,
}
pub struct EncodeContext<'a, 'tcx:'a> {
pub diag: &'a SpanHandler,
pub tcx: &'a ty::ctxt<'tcx>,
pub reexports: &'a def::ExportMap,
pub item_symbols: &'a RefCell<NodeMap<String>>,
pub link_meta: &'a LinkMeta,
pub cstore: &'a cstore::CStore,
pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
pub type_abbrevs: tyencode::abbrev_map<'tcx>,
pub reachable: &'a NodeSet,
}
fn encode_name(rbml_w: &mut Encoder, name: ast::Name) { loop { } }
fn encode_impl_type_basename(rbml_w: &mut Encoder, name: ast::Ident) {
loop { }
}
pub fn encode_def_id(rbml_w: &mut Encoder, id: DefId) { loop { } }
#[derive(Clone)]
struct entry<T> {
val: T,
pos: u64,
}
fn encode_trait_ref<'a,
'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
trait_ref: &ty::TraitRef<'tcx>, tag: uint) {
loop { }
}
fn encode_family(rbml_w: &mut Encoder, c: char) { loop { } }
pub fn def_to_string(did: DefId) -> String { loop { } }
fn encode_item_variances(rbml_w: &mut Encoder, ecx: &EncodeContext,
id: NodeId) {
loop { }
}
fn encode_bounds_and_type<'a,
'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
pty: &ty::TypeScheme<'tcx>) {
loop { }
}
fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) { loop { } }
pub fn write_closure_type<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
closure_type: &ty::ClosureTy<'tcx>) {
loop { }
}
pub fn write_type<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder, typ: Ty<'tcx>) {
loop { }
}
pub fn write_trait_ref<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
trait_ref: &ty::TraitRef<'tcx>) {
loop { }
}
pub fn write_region(ecx: &EncodeContext, rbml_w: &mut Encoder,
r: ty::Region) {
loop { }
}
fn encode_bounds<'a,
'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
bounds: &ty::ParamBounds<'tcx>, tag: uint) {
loop { }
}
fn encode_type<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder, typ: Ty<'tcx>) {
loop { }
}
fn encode_region(ecx: &EncodeContext, rbml_w: &mut Encoder,
r: ty::Region) {
loop { }
}
fn encode_method_fty<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
typ: &ty::BareFnTy<'tcx>) {
loop { }
}
fn encode_symbol(ecx: &EncodeContext, rbml_w: &mut Encoder,
id: NodeId) {
loop { }
}
fn encode_disr_val(_: &EncodeContext, rbml_w: &mut Encoder,
disr_val: ty::Disr) {
loop { }
}
fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) { loop { } }
fn encode_struct_fields(rbml_w: &mut Encoder, fields: &[ty::field_ty],
origin: DefId) {
loop { }
}
fn encode_enum_variant_info(ecx: &EncodeContext, rbml_w: &mut Encoder,
id: NodeId, variants: &[P<ast::Variant>],
index: &mut Vec<entry<i64>>) {
loop { }
}
fn encode_path<PI: Iterator<Item =
PathElem>>(rbml_w: &mut Encoder, path: PI) {
loop { }
}
fn encode_reexported_static_method(rbml_w: &mut Encoder,
exp: &def::Export,
method_def_id: DefId,
method_name: ast::Name) {
loop { }
}
fn encode_reexported_static_base_methods(ecx: &EncodeContext,
rbml_w: &mut Encoder,
exp: &def::Export) -> bool {
loop { }
}
fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
rbml_w: &mut Encoder,
exp: &def::Export) -> bool {
loop { }
}
fn encode_reexported_static_methods(ecx: &EncodeContext,
rbml_w: &mut Encoder,
mod_path: PathElems,
exp: &def::Export) {
loop { }
}
/// Iterates through "auxiliary node IDs", which are node IDs that describe
/// top-level items that are sub-items of the given item. Specifically:
///
/// * For newtype structs, iterates through the node ID of the constructor.
fn each_auxiliary_node_id<F>(item: &ast::Item, callback: F) -> bool
where F: FnOnce(NodeId) -> bool {
loop { }
}
fn encode_reexports(ecx: &EncodeContext, rbml_w: &mut Encoder,
id: NodeId, path: PathElems) {
loop { }
}
fn encode_info_for_mod(ecx: &EncodeContext, rbml_w: &mut Encoder,
md: &ast::Mod, attrs: &[ast::Attribute],
id: NodeId, path: PathElems, name: ast::Ident,
vis: ast::Visibility) {
loop { }
}
fn encode_struct_field_family(rbml_w: &mut Encoder,
visibility: ast::Visibility) {
loop { }
}
fn encode_visibility(rbml_w: &mut Encoder,
visibility: ast::Visibility) {
loop { }
}
fn encode_unboxed_closure_kind(rbml_w: &mut Encoder,
kind: ty::UnboxedClosureKind) {
loop { }
}
fn encode_explicit_self(rbml_w: &mut Encoder,
explicit_self: &ty::ExplicitSelfCategory) {
loop { }
}
fn encode_item_sort(rbml_w: &mut Encoder, sort: char) { loop { } }
fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) { loop { } }
fn encode_provided_source(rbml_w: &mut Encoder,
source_opt: Option<DefId>) {
loop { }
}
fn encode_info_for_struct(ecx: &EncodeContext, rbml_w: &mut Encoder,
fields: &[ty::field_ty],
global_index: &mut Vec<entry<i64>>)
-> Vec<entry<i64>> {
loop { }
}
fn encode_info_for_struct_ctor(ecx: &EncodeContext,
rbml_w: &mut Encoder, name: ast::Ident,
ctor_id: NodeId,
index: &mut Vec<entry<i64>>,
struct_id: NodeId) {
loop { }
}
fn encode_generics<'a,
'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>,
generics: &ty::Generics<'tcx>, tag: uint) {
loop { }
}
fn encode_method_ty_fields<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
method_ty: &ty::Method<'tcx>) {
loop { }
}
fn encode_info_for_method<'a,
'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
m: &ty::Method<'tcx>,
impl_path: PathElems,
is_default_impl: bool,
parent_id: NodeId,
ast_item_opt:
Option<&ast::ImplItem>) {
loop { }
}
fn encode_info_for_associated_type(ecx: &EncodeContext,
rbml_w: &mut Encoder,
associated_type:
&ty::AssociatedType,
impl_path: PathElems,
parent_id: NodeId,
typedef_opt:
Option<P<ast::Typedef>>) {
loop { }
}
fn encode_method_argument_names(rbml_w: &mut Encoder,
decl: &ast::FnDecl) {
loop { }
}
fn encode_repr_attrs(rbml_w: &mut Encoder, ecx: &EncodeContext,
attrs: &[ast::Attribute]) {
loop { }
}
fn encode_inlined_item(ecx: &EncodeContext, rbml_w: &mut Encoder,
ii: InlinedItemRef) {
loop { }
}
const FN_FAMILY: char = 'f';
const STATIC_METHOD_FAMILY: char = 'F';
const METHOD_FAMILY: char = 'h';
fn should_inline(attrs: &[ast::Attribute]) -> bool { loop { } }
fn encode_inherent_implementations(ecx: &EncodeContext,
rbml_w: &mut Encoder,
def_id: DefId) {
loop { }
}
fn encode_extension_implementations(ecx: &EncodeContext,
rbml_w: &mut Encoder,
trait_def_id: DefId) {
loop { }
}
fn encode_stability(rbml_w: &mut Encoder,
stab_opt: Option<attr::Stability>) {
loop { }
}
fn encode_info_for_item(ecx: &EncodeContext, rbml_w: &mut Encoder,
item: &ast::Item, index: &mut Vec<entry<i64>>,
path: PathElems, vis: ast::Visibility) {
loop { }
}
fn encode_info_for_foreign_item(ecx: &EncodeContext,
rbml_w: &mut Encoder,
nitem: &ast::ForeignItem,
index: &mut Vec<entry<i64>>,
path: PathElems, abi: abi::Abi) {
loop { }
}
fn my_visit_expr(_e: &ast::Expr) { loop { } }
fn my_visit_item(i: &ast::Item, rbml_w: &mut Encoder,
ecx: &EncodeContext, index: &mut Vec<entry<i64>>) {
loop { }
}
fn my_visit_foreign_item(ni: &ast::ForeignItem, rbml_w: &mut Encoder,
ecx: &EncodeContext,
index: &mut Vec<entry<i64>>) {
loop { }
}
struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
rbml_w_for_visit_item: &'a mut Encoder<'b>,
ecx: &'a EncodeContext<'c, 'tcx>,
index: &'a mut Vec<entry<i64>>,
}
impl <'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for
EncodeVisitor<'a, 'b, 'c, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr) { loop { } }
fn visit_item(&mut self, i: &ast::Item) { loop { } }
fn visit_foreign_item(&mut self, ni: &ast::ForeignItem) {
loop { }
}
}
fn encode_info_for_items(ecx: &EncodeContext, rbml_w: &mut Encoder,
krate: &ast::Crate) -> Vec<entry<i64>> {
loop { }
}
fn encode_index<T,
F>(rbml_w: &mut Encoder, index: Vec<entry<T>>,
mut write_fn: F) where
F: FnMut(&mut SeekableMemWriter, &T), T: Hash<SipHasher> {
loop { }
}
fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) { loop { } }
fn encode_meta_item(rbml_w: &mut Encoder, mi: &ast::MetaItem) {
loop { }
}
fn encode_attributes(rbml_w: &mut Encoder, attrs: &[ast::Attribute]) {
loop { }
}
fn encode_unsafety(rbml_w: &mut Encoder, unsafety: ast::Unsafety) {
loop { }
}
fn encode_associated_type_names(rbml_w: &mut Encoder,
names: &[ast::Name]) {
loop { }
}
fn encode_polarity(rbml_w: &mut Encoder,
polarity: ast::ImplPolarity) {
loop { }
}
fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
loop { }
}
fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
loop { }
}
fn encode_native_libraries(ecx: &EncodeContext,
rbml_w: &mut Encoder) {
loop { }
}
fn encode_plugin_registrar_fn(ecx: &EncodeContext,
rbml_w: &mut Encoder) {
loop { }
}
/// Serialize the text of the exported macros
fn encode_macro_defs(rbml_w: &mut Encoder, krate: &ast::Crate) {
loop { }
}
fn encode_unboxed_closures<'a>(ecx: &'a EncodeContext,
rbml_w: &'a mut Encoder) {
loop { }
}
fn encode_struct_field_attrs(rbml_w: &mut Encoder,
krate: &ast::Crate) {
loop { }
}
struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
ecx: &'a EncodeContext<'b, 'tcx>,
rbml_w: &'a mut Encoder<'c>,
}
impl <'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for
ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
}
/// Encodes implementations that are eagerly loaded.
///
/// None of this is necessary in theory; we can load all implementations
/// lazily. However, in two cases the optimizations to lazily load
/// implementations are not yet implemented. These two cases, which require us
/// to load implementations eagerly, are:
///
/// * Destructors (implementations of the Drop trait).
///
/// * Implementations of traits not defined in this crate.
fn encode_impls<'a>(ecx: &'a EncodeContext, krate: &ast::Crate,
rbml_w: &'a mut Encoder) {
loop { }
}
fn encode_misc_info(ecx: &EncodeContext, krate: &ast::Crate,
rbml_w: &mut Encoder) {
loop { }
}
fn encode_reachable_extern_fns(ecx: &EncodeContext,
rbml_w: &mut Encoder) {
loop { }
}
fn encode_crate_dep(rbml_w: &mut Encoder, dep: decoder::CrateDep) {
loop { }
}
fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) { loop { } }
fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
loop { }
}
fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
loop { }
}
fn encode_dylib_dependency_formats(rbml_w: &mut Encoder,
ecx: &EncodeContext) {
loop { }
}
#[allow(non_upper_case_globals)]
pub const metadata_encoding_version: &'static [u8] =
&[b'r', b'u', b's', b't', 0, 0, 0, 1];
pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate)
-> Vec<u8> {
loop { }
}
fn encode_metadata_inner(wr: &mut SeekableMemWriter,
parms: EncodeParams, krate: &ast::Crate) {
loop { }
}
pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
loop { }
}
}
pub mod decoder {
#![allow(non_camel_case_types)]
pub use self::DefLike::*;
use self::Family::*;
use back::svh::Svh;
use metadata::cstore::crate_metadata;
use metadata::common::*;
use metadata::csearch::MethodInfo;
use metadata::csearch;
use metadata::cstore;
use metadata::tydecode::{parse_ty_data, parse_region_data,
parse_def_id, parse_type_param_def_data,
parse_bounds_data, parse_bare_fn_ty_data,
parse_trait_ref_data, parse_predicate_data};
use middle::def;
use middle::lang_items;
use middle::subst;
use middle::ty::{ImplContainer, TraitContainer};
use middle::ty::{self, Ty};
use middle::astencode::vtable_decoder_helpers;
use std::collections::HashMap;
use std::hash::{self, Hash, SipHasher};
use std::io::extensions::u64_from_be_bytes;
use std::io;
use std::num::FromPrimitive;
use std::rc::Rc;
use std::str;
use rbml::reader;
use rbml;
use serialize::Decodable;
use syntax::ast_map;
use syntax::attr;
use syntax::parse::token::{IdentInterner, special_idents};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ast;
use syntax::codemap;
use syntax::ptr::P;
pub type Cmd<'a> = &'a crate_metadata;
fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64)
-> Option<rbml::Doc<'a>> where F: FnMut(&[u8]) -> bool {
loop { }
}
pub fn maybe_find_item<'a>(item_id: ast::NodeId, items: rbml::Doc<'a>)
-> Option<rbml::Doc<'a>> {
loop { }
}
fn find_item<'a>(item_id: ast::NodeId, items: rbml::Doc<'a>)
-> rbml::Doc<'a> {
loop { }
}
fn lookup_item<'a>(item_id: ast::NodeId, data: &'a [u8])
-> rbml::Doc<'a> {
loop { }
}
#[derive(PartialEq)]
enum Family {
ImmStatic,
MutStatic,
Fn,
CtorFn,
StaticMethod,
Method,
Type,
ForeignType,
Mod,
ForeignMod,
Enum,
TupleVariant,
StructVariant,
Impl,
Trait,
Struct,
PublicField,
InheritedField,
Constant,
}
fn item_family(item: rbml::Doc) -> Family { loop { } }
fn item_visibility(item: rbml::Doc) -> ast::Visibility { loop { } }
fn item_sort(item: rbml::Doc) -> char { loop { } }
fn item_symbol(item: rbml::Doc) -> String { loop { } }
fn item_parent_item(d: rbml::Doc) -> Option<ast::DefId> { loop { } }
fn item_reqd_and_translated_parent_item(cnum: ast::CrateNum,
d: rbml::Doc) -> ast::DefId {
loop { }
}
fn item_def_id(d: rbml::Doc, cdata: Cmd) -> ast::DefId { loop { } }
fn get_provided_source(d: rbml::Doc, cdata: Cmd)
-> Option<ast::DefId> {
loop { }
}
fn each_reexport<F>(d: rbml::Doc, f: F) -> bool where
F: FnMut(rbml::Doc) -> bool {
loop { }
}
fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> { loop { } }
fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-> Ty<'tcx> {
loop { }
}
fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
cdata: Cmd) -> ty::BareFnTy<'tcx> {
loop { }
}
pub fn item_type<'tcx>(_item_id: ast::DefId, item: rbml::Doc,
tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
loop { }
}
fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
cdata: Cmd) -> Rc<ty::TraitRef<'tcx>> {
loop { }
}
fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
cdata: Cmd) -> Rc<ty::TraitRef<'tcx>> {
loop { }
}
fn doc_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-> ty::ParamBounds<'tcx> {
loop { }
}
fn trait_def_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
cdata: Cmd) -> ty::ParamBounds<'tcx> {
loop { }
}
fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
loop { }
}
fn item_path(item_doc: rbml::Doc) -> Vec<ast_map::PathElem> {
loop { }
}
fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name {
loop { }
}
fn item_to_def_like(item: rbml::Doc, did: ast::DefId,
cnum: ast::CrateNum) -> DefLike {
loop { }
}
fn parse_unsafety(item_doc: rbml::Doc) -> ast::Unsafety { loop { } }
fn parse_associated_type_names(item_doc: rbml::Doc)
-> Vec<ast::Name> {
loop { }
}
pub fn get_trait_def<'tcx>(cdata: Cmd, item_id: ast::NodeId,
tcx: &ty::ctxt<'tcx>)
-> ty::TraitDef<'tcx> {
loop { }
}
pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>) -> ty::TypeScheme<'tcx> {
loop { }
}
pub fn get_stability(cdata: Cmd, id: ast::NodeId)
-> Option<attr::Stability> {
loop { }
}
pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId)
-> Vec<attr::ReprAttr> {
loop { }
}
pub fn get_impl_trait<'tcx>(cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>)
-> Option<Rc<ty::TraitRef<'tcx>>> {
loop { }
}
pub fn get_impl_vtables<'tcx>(cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>)
-> ty::vtable_res<'tcx> {
loop { }
}
pub fn get_symbol(data: &[u8], id: ast::NodeId) -> String {
loop { }
}
#[derive(Copy, Clone, Show)]
pub enum DefLike { DlDef(def::Def), DlImpl(ast::DefId), DlField, }
/// Iterates over the language items in the given crate.
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
F: FnMut(ast::NodeId, uint) -> bool {
loop { }
}
fn each_child_of_item_or_crate<F,
G>(intr: Rc<IdentInterner>, cdata: Cmd,
item_doc: rbml::Doc,
mut get_crate_data: G,
mut callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata> {
loop { }
}
/// Iterates over each child of the given item.
pub fn each_child_of_item<F,
G>(intr: Rc<IdentInterner>, cdata: Cmd,
id: ast::NodeId, get_crate_data: G,
callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata> {
loop { }
}
/// Iterates over all the top-level crate items.
pub fn each_top_level_item_of_crate<F,
G>(intr: Rc<IdentInterner>,
cdata: Cmd, get_crate_data: G,
callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata> {
loop { }
}
pub fn get_item_path(cdata: Cmd, id: ast::NodeId)
-> Vec<ast_map::PathElem> {
loop { }
}
pub type DecodeInlinedItem<'a> =
Box< for<'tcx>FnMut(Cmd, &ty::ctxt<'tcx>, Vec<ast_map::PathElem>,
rbml::Doc) ->
Result<&'tcx ast::InlinedItem, Vec<ast_map::PathElem>> + 'a>;
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>,
id: ast::NodeId,
mut decode_inlined_item:
DecodeInlinedItem)
-> csearch::found_ast<'tcx> {
loop { }
}
pub fn get_enum_variant_defs(intr: &IdentInterner, cdata: Cmd,
id: ast::NodeId)
-> Vec<(def::Def, ast::Name, ast::Visibility)> {
loop { }
}
pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd,
id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
-> Vec<Rc<ty::VariantInfo<'tcx>>> {
loop { }
}
fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
loop { }
}
/// Returns the def IDs of all the items in the given implementation.
pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
-> Vec<ty::ImplOrTraitItemId> {
loop { }
}
pub fn get_trait_name(intr: Rc<IdentInterner>, cdata: Cmd,
id: ast::NodeId) -> ast::Name {
loop { }
}
pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
cdata: Cmd, id: ast::NodeId)
-> (ast::Name, def::TraitItemKind) {
loop { }
}
pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>)
-> ty::ImplOrTraitItem<'tcx> {
loop { }
}
pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
-> Vec<ty::ImplOrTraitItemId> {
loop { }
}
pub fn get_item_variances(cdata: Cmd, id: ast::NodeId)
-> ty::ItemVariances {
loop { }
}
pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>)
-> Vec<Rc<ty::Method<'tcx>>> {
loop { }
}
/// Returns the supertraits of the given trait.
pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt<'tcx>)
-> Vec<Rc<ty::TraitRef<'tcx>>> {
loop { }
}
pub fn get_type_name_if_impl(cdata: Cmd, node_id: ast::NodeId)
-> Option<ast::Name> {
loop { }
}
pub fn get_methods_if_impl(intr: Rc<IdentInterner>, cdata: Cmd,
node_id: ast::NodeId)
-> Option<Vec<MethodInfo>> {
loop { }
}
/// If node_id is the constructor of a tuple struct, retrieve the NodeId of
/// the actual type definition, otherwise, return None
pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
node_id: ast::NodeId)
-> Option<ast::DefId> {
loop { }
}
pub fn get_item_attrs<F>(cdata: Cmd, orig_node_id: ast::NodeId, f: F)
where F: FnOnce(Vec<ast::Attribute>) {
loop { }
}
pub fn get_struct_field_attrs(cdata: Cmd)
-> HashMap<ast::NodeId, Vec<ast::Attribute>> {
loop { }
}
fn struct_field_family_to_visibility(family: Family)
-> ast::Visibility {
loop { }
}
pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd,
id: ast::NodeId) -> Vec<ty::field_ty> {
loop { }
}
fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
loop { }
}
fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> { loop { } }
fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
out: &mut io::Writer) -> io::IoResult<()> {
loop { }
}
pub fn get_crate_attributes(data: &[u8]) -> Vec<ast::Attribute> {
loop { }
}
#[derive(Clone)]
pub struct CrateDep {
pub cnum: ast::CrateNum,
pub name: String,
pub hash: Svh,
}
pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> { loop { } }
fn list_crate_deps(data: &[u8], out: &mut io::Writer)
-> io::IoResult<()> {
loop { }
}
pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> { loop { } }
pub fn get_crate_hash(data: &[u8]) -> Svh { loop { } }
pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
loop { }
}
pub fn get_crate_triple(data: &[u8]) -> Option<String> { loop { } }
pub fn get_crate_name(data: &[u8]) -> String { loop { } }
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer)
-> io::IoResult<()> {
loop { }
}
pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId {
loop { }
}
pub fn each_impl<F>(cdata: Cmd, mut callback: F) where
F: FnMut(ast::DefId) {
loop { }
}
pub fn each_implementation_for_type<F>(cdata: Cmd, id: ast::NodeId,
mut callback: F) where
F: FnMut(ast::DefId) {
loop { }
}
pub fn each_implementation_for_trait<F>(cdata: Cmd, id: ast::NodeId,
mut callback: F) where
F: FnMut(ast::DefId) {
loop { }
}
pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
-> Option<ast::DefId> {
loop { }
}
pub fn get_native_libraries(cdata: Cmd)
-> Vec<(cstore::NativeLibraryKind, String)> {
loop { }
}
pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
loop { }
}
pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner,
mut f: F) where
F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool {
loop { }
}
pub fn get_dylib_dependency_formats(cdata: Cmd)
-> Vec<(ast::CrateNum, cstore::LinkagePreference)> {
loop { }
}
pub fn get_missing_lang_items(cdata: Cmd)
-> Vec<lang_items::LangItem> {
loop { }
}
pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId)
-> Vec<String> {
loop { }
}
pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
loop { }
}
pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool { loop { } }
fn doc_generics<'tcx>(base_doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
cdata: Cmd, tag: uint) -> ty::Generics<'tcx> {
loop { }
}
pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
loop { }
}
}
pub mod creader {
#![allow(non_camel_case_types)]
//! Validates all used crates and extern libraries and loads their metadata
use back::svh::Svh;
use session::{config, Session};
use session::search_paths::PathKind;
use metadata::cstore;
use metadata::cstore::{CStore, CrateSource, MetadataBlob};
use metadata::decoder;
use metadata::loader;
use metadata::loader::CratePaths;
use std::rc::Rc;
use syntax::ast;
use syntax::abi;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::{COMMAND_LINE_SP, Span, mk_sp};
use syntax::parse;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::visit;
use util::fs;
use log;
pub struct CrateReader<'a> {
sess: &'a Session,
next_crate_num: ast::CrateNum,
}
impl <'a, 'v> visit::Visitor<'v> for CrateReader<'a> {
fn visit_view_item(&mut self, a: &ast::ViewItem) { loop { } }
fn visit_item(&mut self, a: &ast::Item) { loop { } }
}
fn dump_crates(cstore: &CStore) { loop { } }
fn should_link(i: &ast::ViewItem) -> bool { loop { } }
struct CrateInfo {
ident: String,
name: String,
id: ast::NodeId,
should_link: bool,
}
pub fn validate_crate_name(sess: Option<&Session>, s: &str,
sp: Option<Span>) {
loop { }
}
fn register_native_lib(sess: &Session, span: Option<Span>,
name: String,
kind: cstore::NativeLibraryKind) {
loop { }
}
pub struct PluginMetadata<'a> {
sess: &'a Session,
metadata: PMDSource,
dylib: Option<Path>,
info: CrateInfo,
vi_span: Span,
target_only: bool,
}
enum PMDSource {
Registered(Rc<cstore::crate_metadata>),
Owned(MetadataBlob),
}
impl PMDSource {
pub fn as_slice<'a>(&'a self) -> &'a [u8] { loop { } }
}
impl <'a> CrateReader<'a> {
pub fn new(sess: &'a Session) -> CrateReader<'a> { loop { } }
pub fn read_crates(&mut self, krate: &ast::Crate) { loop { } }
fn process_crate(&self, c: &ast::Crate) { loop { } }
fn process_view_item(&mut self, i: &ast::ViewItem) { loop { } }
fn extract_crate_info(&self, i: &ast::ViewItem)
-> Option<CrateInfo> {
loop { }
}
fn process_item(&self, i: &ast::Item) { loop { } }
fn existing_match(&self, name: &str, hash: Option<&Svh>)
-> Option<ast::CrateNum> {
loop { }
}
fn register_crate(&mut self, root: &Option<CratePaths>,
ident: &str, name: &str, span: Span,
lib: loader::Library)
->
(ast::CrateNum, Rc<cstore::crate_metadata>,
cstore::CrateSource) {
loop { }
}
fn resolve_crate(&mut self, root: &Option<CratePaths>,
ident: &str, name: &str, hash: Option<&Svh>,
span: Span, kind: PathKind)
->
(ast::CrateNum, Rc<cstore::crate_metadata>,
cstore::CrateSource) {
loop { }
}
fn resolve_crate_deps(&mut self, root: &Option<CratePaths>,
cdata: &[u8], span: Span)
-> cstore::cnum_map {
loop { }
}
pub fn read_plugin_metadata<'b>(&'b mut self,
krate: CrateOrString<'b>)
-> PluginMetadata<'b> {
loop { }
}
}
#[derive(Copy)]
pub enum CrateOrString<'a> { Krate(&'a ast::ViewItem), Str(&'a str), }
impl <'a> PluginMetadata<'a> {
/// Read exported macros
pub fn exported_macros(&self) -> Vec<ast::MacroDef> { loop { } }
/// Look for a plugin registrar. Returns library path and symbol name.
pub fn plugin_registrar(&self) -> Option<(Path, String)> {
loop { }
}
}
}
pub mod cstore {
#![allow(non_camel_case_types)]
pub use self::MetadataBlob::*;
pub use self::LinkagePreference::*;
pub use self::NativeLibraryKind::*;
use back::svh::Svh;
use metadata::decoder;
use metadata::loader;
use util::nodemap::{FnvHashMap, NodeMap};
use std::cell::RefCell;
use std::rc::Rc;
use flate::Bytes;
use syntax::ast;
use syntax::codemap::Span;
use syntax::parse::token::IdentInterner;
pub type cnum_map = FnvHashMap<ast::CrateNum, ast::CrateNum>;
pub enum MetadataBlob {
MetadataVec(Bytes),
MetadataArchive(loader::ArchiveMetadata),
}
pub struct crate_metadata {
pub name: String,
pub data: MetadataBlob,
pub cnum_map: cnum_map,
pub cnum: ast::CrateNum,
pub span: Span,
}
#[derive(Copy, Show, PartialEq, Clone)]
pub enum LinkagePreference { RequireDynamic, RequireStatic, }
#[derive(Copy, Clone, PartialEq, FromPrimitive)]
pub enum NativeLibraryKind {
NativeStatic,
NativeFramework,
NativeUnknown,
}
#[derive(PartialEq, Clone)]
pub struct CrateSource {
pub dylib: Option<Path>,
pub rlib: Option<Path>,
pub cnum: ast::CrateNum,
}
pub struct CStore {
metas: RefCell<FnvHashMap<ast::CrateNum, Rc<crate_metadata>>>,
/// Map from NodeId's of local extern crate statements to crate numbers
extern_mod_crate_map: RefCell<NodeMap<ast::CrateNum>>,
used_crate_sources: RefCell<Vec<CrateSource>>,
used_libraries: RefCell<Vec<(String, NativeLibraryKind)>>,
used_link_args: RefCell<Vec<String>>,
pub intr: Rc<IdentInterner>,
}
impl CStore {
pub fn new(intr: Rc<IdentInterner>) -> CStore { loop { } }
pub fn next_crate_num(&self) -> ast::CrateNum { loop { } }
pub fn get_crate_data(&self, cnum: ast::CrateNum)
-> Rc<crate_metadata> {
loop { }
}
pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh {
loop { }
}
pub fn set_crate_data(&self, cnum: ast::CrateNum,
data: Rc<crate_metadata>) {
loop { }
}
pub fn iter_crate_data<I>(&self, mut i: I) where
I: FnMut(ast::CrateNum, &crate_metadata) {
loop { }
}
/// Like `iter_crate_data`, but passes source paths (if available) as well.
pub fn iter_crate_data_origins<I>(&self, mut i: I) where
I: FnMut(ast::CrateNum, &crate_metadata, Option<CrateSource>) {
loop { }
}
pub fn add_used_crate_source(&self, src: CrateSource) {
loop { }
}
pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
-> Option<CrateSource> {
loop { }
}
pub fn reset(&self) { loop { } }
pub fn get_used_crates(&self, prefer: LinkagePreference)
-> Vec<(ast::CrateNum, Option<Path>)> {
loop { }
}
pub fn add_used_library(&self, lib: String,
kind: NativeLibraryKind) {
loop { }
}
pub fn get_used_libraries<'a>(&'a self)
-> &'a RefCell<Vec<(String, NativeLibraryKind)>> {
loop { }
}
pub fn add_used_link_args(&self, args: &str) { loop { } }
pub fn get_used_link_args<'a>(&'a self)
-> &'a RefCell<Vec<String>> {
loop { }
}
pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId,
cnum: ast::CrateNum) {
loop { }
}
pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
-> Option<ast::CrateNum> {
loop { }
}
}
impl crate_metadata {
pub fn data<'a>(&'a self) -> &'a [u8] { loop { } }
pub fn name(&self) -> String { loop { } }
pub fn hash(&self) -> Svh { loop { } }
}
impl MetadataBlob {
pub fn as_slice<'a>(&'a self) -> &'a [u8] { loop { } }
}
}
pub mod csearch {
#![allow(non_camel_case_types)]
pub use self::found_ast::*;
use metadata::common::*;
use metadata::cstore;
use metadata::decoder;
use middle::def;
use middle::lang_items;
use middle::ty;
use rbml;
use rbml::reader;
use std::rc::Rc;
use syntax::ast;
use syntax::ast_map;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::expect;
use syntax::parse::token;
use std::collections::hash_map::HashMap;
#[derive(Copy)]
pub struct MethodInfo {
pub name: ast::Name,
pub def_id: ast::DefId,
pub vis: ast::Visibility,
}
pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId)
-> String {
loop { }
}
/// Iterates over all the language items in the given crate.
pub fn each_lang_item<F>(cstore: &cstore::CStore, cnum: ast::CrateNum,
f: F) -> bool where
F: FnMut(ast::NodeId, uint) -> bool {
loop { }
}
/// Iterates over each child of the given item.
pub fn each_child_of_item<F>(cstore: &cstore::CStore,
def_id: ast::DefId, callback: F) where
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility) {
loop { }
}
/// Iterates over each top-level crate item.
pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
cnum: ast::CrateNum,
callback: F) where
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility) {
loop { }
}
pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId)
-> Vec<ast_map::PathElem> {
loop { }
}
pub enum found_ast<'ast> {
found(&'ast ast::InlinedItem),
found_parent(ast::DefId, &'ast ast::InlinedItem),
not_found,
}
pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId,
decode_inlined_item:
decoder::DecodeInlinedItem)
-> found_ast<'tcx> {
loop { }
}
pub fn get_enum_variant_defs(cstore: &cstore::CStore,
enum_id: ast::DefId)
-> Vec<(def::Def, ast::Name, ast::Visibility)> {
loop { }
}
pub fn get_enum_variants<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> Vec<Rc<ty::VariantInfo<'tcx>>> {
loop { }
}
/// Returns information about the given implementation.
pub fn get_impl_items(cstore: &cstore::CStore,
impl_def_id: ast::DefId)
-> Vec<ty::ImplOrTraitItemId> {
loop { }
}
pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> ty::ImplOrTraitItem<'tcx> {
loop { }
}
pub fn get_trait_name(cstore: &cstore::CStore, def: ast::DefId)
-> ast::Name {
loop { }
}
pub fn get_trait_item_name_and_kind(cstore: &cstore::CStore,
def: ast::DefId)
-> (ast::Name, def::TraitItemKind) {
loop { }
}
pub fn get_trait_item_def_ids(cstore: &cstore::CStore,
def: ast::DefId)
-> Vec<ty::ImplOrTraitItemId> {
loop { }
}
pub fn get_item_variances(cstore: &cstore::CStore, def: ast::DefId)
-> ty::ItemVariances {
loop { }
}
pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> Vec<Rc<ty::Method<'tcx>>> {
loop { }
}
pub fn get_supertraits<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> Vec<Rc<ty::TraitRef<'tcx>>> {
loop { }
}
pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
-> Option<ast::Name> {
loop { }
}
pub fn get_methods_if_impl(cstore: &cstore::CStore, def: ast::DefId)
-> Option<Vec<MethodInfo>> {
loop { }
}
pub fn get_item_attrs<F>(cstore: &cstore::CStore, def_id: ast::DefId,
f: F) where F: FnOnce(Vec<ast::Attribute>) {
loop { }
}
pub fn get_struct_fields(cstore: &cstore::CStore, def: ast::DefId)
-> Vec<ty::field_ty> {
loop { }
}
pub fn get_struct_field_attrs(cstore: &cstore::CStore,
def: ast::DefId)
-> HashMap<ast::NodeId, Vec<ast::Attribute>> {
loop { }
}
pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> ty::TypeScheme<'tcx> {
loop { }
}
pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> ty::TraitDef<'tcx> {
loop { }
}
pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>,
class_id: ast::DefId, def: ast::DefId)
-> ty::TypeScheme<'tcx> {
loop { }
}
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> Option<Rc<ty::TraitRef<'tcx>>> {
loop { }
}
pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> ty::vtable_res<'tcx> {
loop { }
}
pub fn get_native_libraries(cstore: &cstore::CStore,
crate_num: ast::CrateNum)
-> Vec<(cstore::NativeLibraryKind, String)> {
loop { }
}
pub fn each_impl<F>(cstore: &cstore::CStore, crate_num: ast::CrateNum,
callback: F) where F: FnMut(ast::DefId) {
loop { }
}
pub fn each_implementation_for_type<F>(cstore: &cstore::CStore,
def_id: ast::DefId,
callback: F) where
F: FnMut(ast::DefId) {
loop { }
}
pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
def_id: ast::DefId,
callback: F) where
F: FnMut(ast::DefId) {
loop { }
}
/// If the given def ID describes an item belonging to a trait (either a
/// default method or an implementation of a trait method), returns the ID of
/// the trait that the method belongs to. Otherwise, returns `None`.
pub fn get_trait_of_item(cstore: &cstore::CStore, def_id: ast::DefId,
tcx: &ty::ctxt) -> Option<ast::DefId> {
loop { }
}
pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
def_id: ast::DefId)
-> Option<ast::DefId> {
loop { }
}
pub fn get_dylib_dependency_formats(cstore: &cstore::CStore,
cnum: ast::CrateNum)
-> Vec<(ast::CrateNum, cstore::LinkagePreference)> {
loop { }
}
pub fn get_missing_lang_items(cstore: &cstore::CStore,
cnum: ast::CrateNum)
-> Vec<lang_items::LangItem> {
loop { }
}
pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId)
-> Vec<String> {
loop { }
}
pub fn get_reachable_extern_fns(cstore: &cstore::CStore,
cnum: ast::CrateNum)
-> Vec<ast::DefId> {
loop { }
}
pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
loop { }
}
pub fn get_stability(cstore: &cstore::CStore, def: ast::DefId)
-> Option<attr::Stability> {
loop { }
}
pub fn is_staged_api(cstore: &cstore::CStore, def: ast::DefId)
-> bool {
loop { }
}
pub fn get_repr_attrs(cstore: &cstore::CStore, def: ast::DefId)
-> Vec<attr::ReprAttr> {
loop { }
}
pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId)
-> bool {
loop { }
}
}
pub mod loader {
//! Finds crate binaries and loads their metadata
//!
//! Might I be the first to welcome you to a world of platform differences,
//! version requirements, dependency graphs, conflicting desires, and fun! This
//! is the major guts (along with metadata::creader) of the compiler for loading
//! crates and resolving dependencies. Let's take a tour!
//!
//! # The problem
//!
//! Each invocation of the compiler is immediately concerned with one primary
//! problem, to connect a set of crates to resolved crates on the filesystem.
//! Concretely speaking, the compiler follows roughly these steps to get here:
//!
//! 1. Discover a set of `extern crate` statements.
//! 2. Transform these directives into crate names. If the directive does not
//! have an explicit name, then the identifier is the name.
//! 3. For each of these crate names, find a corresponding crate on the
//! filesystem.
//!
//! Sounds easy, right? Let's walk into some of the nuances.
//!
//! ## Transitive Dependencies
//!
//! Let's say we've got three crates: A, B, and C. A depends on B, and B depends
//! on C. When we're compiling A, we primarily need to find and locate B, but we
//! also end up needing to find and locate C as well.
//!
//! The reason for this is that any of B's types could be composed of C's types,
//! any function in B could return a type from C, etc. To be able to guarantee
//! that we can always typecheck/translate any function, we have to have
//! complete knowledge of the whole ecosystem, not just our immediate
//! dependencies.
//!
//! So now as part of the "find a corresponding crate on the filesystem" step
//! above, this involves also finding all crates for *all upstream
//! dependencies*. This includes all dependencies transitively.
//!
//! ## Rlibs and Dylibs
//!
//! The compiler has two forms of intermediate dependencies. These are dubbed
//! rlibs and dylibs for the static and dynamic variants, respectively. An rlib
//! is a rustc-defined file format (currently just an ar archive) while a dylib
//! is a platform-defined dynamic library. Each library has a metadata somewhere
//! inside of it.
//!
//! When translating a crate name to a crate on the filesystem, we all of a
//! sudden need to take into account both rlibs and dylibs! Linkage later on may
//! use either one of these files, as each has their pros/cons. The job of crate
//! loading is to discover what's possible by finding all candidates.
//!
//! Most parts of this loading systems keep the dylib/rlib as just separate
//! variables.
//!
//! ## Where to look?
//!
//! We can't exactly scan your whole hard drive when looking for dependencies,
//! so we need to places to look. Currently the compiler will implicitly add the
//! target lib search path ($prefix/lib/rustlib/$target/lib) to any compilation,
//! and otherwise all -L flags are added to the search paths.
//!
//! ## What criterion to select on?
//!
//! This a pretty tricky area of loading crates. Given a file, how do we know
//! whether it's the right crate? Currently, the rules look along these lines:
//!
//! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
//! filename have the right prefix/suffix?
//! 2. Does the filename have the right prefix for the crate name being queried?
//! This is filtering for files like `libfoo*.rlib` and such.
//! 3. Is the file an actual rust library? This is done by loading the metadata
//! from the library and making sure it's actually there.
//! 4. Does the name in the metadata agree with the name of the library?
//! 5. Does the target in the metadata agree with the current target?
//! 6. Does the SVH match? (more on this later)
//!
//! If the file answers `yes` to all these questions, then the file is
//! considered as being *candidate* for being accepted. It is illegal to have
//! more than two candidates as the compiler has no method by which to resolve
//! this conflict. Additionally, rlib/dylib candidates are considered
//! separately.
//!
//! After all this has happened, we have 1 or two files as candidates. These
//! represent the rlib/dylib file found for a library, and they're returned as
//! being found.
//!
//! ### What about versions?
//!
//! A lot of effort has been put forth to remove versioning from the compiler.
//! There have been forays in the past to have versioning baked in, but it was
//! largely always deemed insufficient to the point that it was recognized that
//! it's probably something the compiler shouldn't do anyway due to its
//! complicated nature and the state of the half-baked solutions.
//!
//! With a departure from versioning, the primary criterion for loading crates
//! is just the name of a crate. If we stopped here, it would imply that you
//! could never link two crates of the same name from different sources
//! together, which is clearly a bad state to be in.
//!
//! To resolve this problem, we come to the next section!
//!
//! # Expert Mode
//!
//! A number of flags have been added to the compiler to solve the "version
//! problem" in the previous section, as well as generally enabling more
//! powerful usage of the crate loading system of the compiler. The goal of
//! these flags and options are to enable third-party tools to drive the
//! compiler with prior knowledge about how the world should look.
//!
//! ## The `--extern` flag
//!
//! The compiler accepts a flag of this form a number of times:
//!
//! ```text
//! --extern crate-name=path/to/the/crate.rlib
//! ```
//!
//! This flag is basically the following letter to the compiler:
//!
//! > Dear rustc,
//! >
//! > When you are attempting to load the immediate dependency `crate-name`, I
//! > would like you too assume that the library is located at
//! > `path/to/the/crate.rlib`, and look nowhere else. Also, please do not
//! > assume that the path I specified has the name `crate-name`.
//!
//! This flag basically overrides most matching logic except for validating that
//! the file is indeed a rust library. The same `crate-name` can be specified
//! twice to specify the rlib/dylib pair.
//!
//! ## Enabling "multiple versions"
//!
//! This basically boils down to the ability to specify arbitrary packages to
//! the compiler. For example, if crate A wanted to use Bv1 and Bv2, then it
//! would look something like:
//!
//! ```ignore
//! extern crate b1;
//! extern crate b2;
//!
//! fn main() {}
//! ```
//!
//! and the compiler would be invoked as:
//!
//! ```text
//! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
//! ```
//!
//! In this scenario there are two crates named `b` and the compiler must be
//! manually driven to be informed where each crate is.
//!
//! ## Frobbing symbols
//!
//! One of the immediate problems with linking the same library together twice
//! in the same problem is dealing with duplicate symbols. The primary way to
//! deal with this in rustc is to add hashes to the end of each symbol.
//!
//! In order to force hashes to change between versions of a library, if
//! desired, the compiler exposes an option `-C metadata=foo`, which is used to
//! initially seed each symbol hash. The string `foo` is prepended to each
//! string-to-hash to ensure that symbols change over time.
//!
//! ## Loading transitive dependencies
//!
//! Dealing with same-named-but-distinct crates is not just a local problem, but
//! one that also needs to be dealt with for transitive dependencies. Note that
//! in the letter above `--extern` flags only apply to the *local* set of
//! dependencies, not the upstream transitive dependencies. Consider this
//! dependency graph:
//!
//! ```text
//! A.1 A.2
//! | |
//! | |
//! B C
//! \ /
//! \ /
//! D
//! ```
//!
//! In this scenario, when we compile `D`, we need to be able to distinctly
//! resolve `A.1` and `A.2`, but an `--extern` flag cannot apply to these
//! transitive dependencies.
//!
//! Note that the key idea here is that `B` and `C` are both *already compiled*.
//! That is, they have already resolved their dependencies. Due to unrelated
//! technical reasons, when a library is compiled, it is only compatible with
//! the *exact same* version of the upstream libraries it was compiled against.
//! We use the "Strict Version Hash" to identify the exact copy of an upstream
//! library.
//!
//! With this knowledge, we know that `B` and `C` will depend on `A` with
//! different SVH values, so we crawl the normal `-L` paths looking for
//! `liba*.rlib` and filter based on the contained SVH.
//!
//! In the end, this ends up not needing `--extern` to specify upstream
//! transitive dependencies.
//!
//! # Wrapping up
//!
//! That's the general overview of loading crates in the compiler, but it's by
//! no means all of the necessary details. Take a look at the rest of
//! metadata::loader or metadata::creader for all the juicy details!
use back::archive::{METADATA_FILENAME};
use back::svh::Svh;
use session::Session;
use llvm;
use llvm::{False, ObjectFile, mk_section_iter};
use llvm::archive_ro::ArchiveRO;
use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
use metadata::decoder;
use metadata::encoder;
use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
use syntax::codemap::Span;
use syntax::diagnostic::SpanHandler;
use util::fs;
use rustc_back::target::Target;
use std::ffi::CString;
use std::cmp;
use std::collections::{HashMap, HashSet};
use std::io::fs::PathExtensions;
use std::io;
use std::ptr;
use std::slice;
use std::time::Duration;
use flate;
pub struct CrateMismatch {
path: Path,
got: String,
}
pub struct Context<'a> {
pub sess: &'a Session,
pub span: Span,
pub ident: &'a str,
pub crate_name: &'a str,
pub hash: Option<&'a Svh>,
pub target: &'a Target,
pub triple: &'a str,
pub filesearch: FileSearch<'a>,
pub root: &'a Option<CratePaths>,
pub rejected_via_hash: Vec<CrateMismatch>,
pub rejected_via_triple: Vec<CrateMismatch>,
pub should_match_name: bool,
}
pub struct Library {
pub dylib: Option<Path>,
pub rlib: Option<Path>,
pub metadata: MetadataBlob,
}
pub struct ArchiveMetadata {
_archive: ArchiveRO,
data: *const [u8],
}
pub struct CratePaths {
pub ident: String,
pub dylib: Option<Path>,
pub rlib: Option<Path>,
}
impl CratePaths {
fn paths(&self) -> Vec<Path> { loop { } }
}
impl <'a> Context<'a> {
pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
loop { }
}
pub fn load_library_crate(&mut self) -> Library { loop { } }
pub fn report_load_errs(&mut self) { loop { } }
fn find_library_crate(&mut self) -> Option<Library> { loop { } }
fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
slot: &mut Option<MetadataBlob>) -> Option<Path> {
loop { }
}
fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path)
-> bool {
loop { }
}
fn dylibname(&self) -> (String, String) { loop { } }
fn find_commandline_library(&mut self) -> Option<Library> {
loop { }
}
}
pub fn note_crate_name(diag: &SpanHandler, name: &str) { loop { } }
impl ArchiveMetadata {
fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> { loop { } }
pub fn as_slice<'a>(&'a self) -> &'a [u8] { loop { } }
}
fn get_metadata_section(is_osx: bool, filename: &Path)
-> Result<MetadataBlob, String> {
loop { }
}
fn get_metadata_section_imp(is_osx: bool, filename: &Path)
-> Result<MetadataBlob, String> {
loop { }
}
pub fn meta_section_name(is_osx: bool) -> &'static str { loop { } }
pub fn read_meta_section_name(is_osx: bool) -> &'static str {
loop { }
}
pub fn list_file_metadata(is_osx: bool, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> {
loop { }
}
}
pub mod filesearch {
#![allow(non_camel_case_types)]
pub use self::FileMatch::*;
use std::collections::HashSet;
use std::io::fs::PathExtensions;
use std::io::fs;
use std::os;
use util::fs as myfs;
use session::search_paths::{SearchPaths, PathKind};
#[derive(Copy)]
pub enum FileMatch { FileMatches, FileDoesntMatch, }
pub struct FileSearch<'a> {
pub sysroot: &'a Path,
pub search_paths: &'a SearchPaths,
pub triple: &'a str,
pub kind: PathKind,
}
impl <'a> FileSearch<'a> {
pub fn for_each_lib_search_path<F>(&self, mut f: F) where
F: FnMut(&Path) -> FileMatch {
loop { }
}
pub fn get_lib_path(&self) -> Path { loop { } }
pub fn search<F>(&self, mut pick: F) where F: FnMut(&Path) ->
FileMatch {
loop { }
}
pub fn new(sysroot: &'a Path, triple: &'a str,
search_paths: &'a SearchPaths, kind: PathKind)
-> FileSearch<'a> {
loop { }
}
pub fn get_dylib_search_paths(&self) -> Vec<Path> { loop { } }
pub fn get_tools_search_paths(&self) -> Vec<Path> { loop { } }
}
pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str)
-> Path {
loop { }
}
fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> Path {
loop { }
}
fn make_rustpkg_lib_path(sysroot: &Path, dir: &Path, triple: &str)
-> Path {
loop { }
}
pub fn get_or_default_sysroot() -> Path { loop { } }
#[cfg(windows)]
static PATH_ENTRY_SEPARATOR: &'static str = ";";
#[cfg(not(windows))]
static PATH_ENTRY_SEPARATOR: &'static str = ":";
/// Returns RUST_PATH as a string, without default paths added
pub fn get_rust_path() -> Option<String> { loop { } }
/// Returns the value of RUST_PATH, as a list
/// of Paths. Includes default entries for, if they exist:
/// $HOME/.rust
/// DIR/.rust for any DIR that's the current working directory
/// or an ancestor of it
pub fn rust_path() -> Vec<Path> { loop { } }
#[cfg(unix)]
fn find_libdir(sysroot: &Path) -> String { loop { } }
#[cfg(windows)]
fn find_libdir(_sysroot: &Path) -> String { loop { } }
pub fn rustlibdir() -> String { loop { } }
}
}
pub mod session {
use lint;
use metadata::cstore::CStore;
use metadata::filesearch;
use session::search_paths::PathKind;
use util::nodemap::NodeMap;
use regex::Regex;
use syntax::ast::NodeId;
use syntax::codemap::Span;
use syntax::diagnostic::{self, Emitter};
use syntax::diagnostics;
use syntax::feature_gate;
use syntax::parse;
use syntax::parse::token;
use syntax::parse::ParseSess;
use syntax::{ast, codemap};
use rustc_back::target::Target;
use std::os;
use std::cell::{Cell, RefCell};
pub mod config {
//! Contains infrastructure for configuring the compiler, including parsing
//! command line options.
pub use self::EntryFnType::*;
pub use self::CrateType::*;
pub use self::Passes::*;
pub use self::OptLevel::*;
pub use self::OutputType::*;
pub use self::DebugInfoLevel::*;
use session::{early_error, early_warn, Session};
use session::search_paths::SearchPaths;
use rustc_back::target::Target;
use lint;
use metadata::cstore;
use syntax::ast;
use syntax::ast::{IntTy, UintTy};
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::{ColorConfig, Auto, Always, Never,
SpanHandler};
use syntax::parse;
use syntax::parse::token::InternedString;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use getopts;
use std::fmt;
use llvm;
pub struct Config {
pub target: Target,
pub int_type: IntTy,
pub uint_type: UintTy,
}
#[derive(Clone, Copy, PartialEq)]
pub enum OptLevel { No, Less, Default, Aggressive, }
#[derive(Clone, Copy, PartialEq)]
pub enum DebugInfoLevel {
NoDebugInfo,
LimitedDebugInfo,
FullDebugInfo,
}
#[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
pub enum OutputType {
OutputTypeBitcode,
OutputTypeAssembly,
OutputTypeLlvmAssembly,
OutputTypeObject,
OutputTypeExe,
OutputTypeDepInfo,
}
#[derive(Clone)]
pub struct Options {
pub crate_types: Vec<CrateType>,
pub gc: bool,
pub optimize: OptLevel,
pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool,
pub output_types: Vec<OutputType>,
pub search_paths: SearchPaths,
pub libs: Vec<(String, cstore::NativeLibraryKind)>,
pub maybe_sysroot: Option<Path>,
pub target_triple: String,
pub cfg: ast::CrateConfig,
pub test: bool,
pub parse_only: bool,
pub no_trans: bool,
pub no_analysis: bool,
pub debugging_opts: DebuggingOptions,
/// Whether to write dependency files. It's (enabled, optional filename).
pub write_dependency_info: (bool, Option<Path>),
pub prints: Vec<PrintRequest>,
pub cg: CodegenOptions,
pub color: ColorConfig,
pub show_span: Option<String>,
pub externs: HashMap<String, Vec<String>>,
pub crate_name: Option<String>,
/// An optional name to use as the crate for std during std injection,
/// written `extern crate std = "name"`. Default to "std". Used by
/// out-of-tree drivers.
pub alt_std_name: Option<String>,
/// Indicates how the compiler should treat unstable features
pub unstable_features: UnstableFeatures,
}
#[derive(Clone, Copy)]
pub enum UnstableFeatures {
/// Hard errors for unstable features are active, as on
/// beta/stable channels.
Disallow,
/// Use the default lint levels
Default,
/// Errors are bypassed for bootstrapping. This is required any time
/// during the build that feature-related lints are set to warn or above
/// because the build turns on warnings-as-errors and uses lots of unstable
/// features. As a result, this this is always required for building Rust
/// itself.
Cheat,
}
#[derive(Clone, PartialEq, Eq)]
#[allow(missing_copy_implementations)]
pub enum PrintRequest { FileNames, Sysroot, CrateName, }
pub enum Input {
/// Load source from file
File(Path),
/// The string is the source
Str(String),
}
impl Input {
pub fn filestem(&self) -> String { loop { } }
}
#[derive(Clone)]
pub struct OutputFilenames {
pub out_directory: Path,
pub out_filestem: String,
pub single_output_file: Option<Path>,
pub extra: String,
}
impl OutputFilenames {
pub fn path(&self, flavor: OutputType) -> Path { loop { } }
pub fn temp_path(&self, flavor: OutputType) -> Path { loop { } }
pub fn with_extension(&self, extension: &str) -> Path {
loop { }
}
pub fn filestem(&self) -> String { loop { } }
}
pub fn host_triple() -> &'static str { loop { } }
/// Some reasonable defaults
pub fn basic_options() -> Options { loop { } }
#[derive(Copy, PartialEq)]
pub enum EntryFnType { EntryMain, EntryStart, EntryNone, }
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash)]
pub enum CrateType {
CrateTypeExecutable,
CrateTypeDylib,
CrateTypeRlib,
CrateTypeStaticlib,
}
#[derive(Clone)]
pub enum Passes { SomePasses(Vec<String>), AllPasses, }
impl Passes {
pub fn is_empty(&self) -> bool { loop { } }
}
/// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
/// at once. The goal of this macro is to define an interface that can be
/// programmatically used by the option parser in order to initialize the struct
/// without hardcoding field names all over the place.
///
/// The goal is to invoke this macro once with the correct fields, and then this
/// macro generates all necessary code. The main gotcha of this macro is the
/// cgsetters module which is a bunch of generated code to parse an option into
/// its respective field in the struct. There are a few hand-written parsers for
/// parsing specific types of values in this module.
macro_rules! options((
$ struct_name : ident , $ setter_name : ident , $
defaultfn : ident , $ buildfn : ident , $ prefix
: expr , $ outputname : expr , $ stat : ident , $
mod_desc : ident , $ mod_set : ident , $ (
$ opt : ident : $ t : ty = (
$ init : expr , $ parse : ident , $ desc : expr )
) , * , ) => (
# [ derive ( Clone ) ] # [
allow ( missing_copy_implementations ) ] pub
struct $ struct_name { $ ( pub $ opt : $ t ) , *
} pub fn $ defaultfn ( ) -> $ struct_name {
$ struct_name { $ ( $ opt : $ init ) , * } } pub
fn $ buildfn ( matches : & getopts :: Matches )
-> $ struct_name {
let mut op = $ defaultfn ( ) ; for option in
matches . opt_strs ( $ prefix ) . into_iter ( )
{
let mut iter = option . splitn ( 1 , '=' ) ; let
key = iter . next ( ) . unwrap ( ) ; let value
= iter . next ( ) ; let option_to_lookup = key .
replace ( "-" , "_" ) ; let mut found = false ;
for & ( candidate , setter , opt_type_desc , _ )
in $ stat . iter ( ) {
if option_to_lookup != candidate { continue } if
! setter ( & mut op , value ) {
match ( value , opt_type_desc ) {
( Some ( .. ) , None ) => {
early_error (
& format ! (
"{} option `{}` takes no \
value"
, $ outputname , key ) [ ] ) } (
None , Some ( type_desc ) ) => {
early_error (
& format ! (
"{0} option `{1}` requires \
{2} ({3} {1}=<value>)"
, $ outputname , key , type_desc , $ prefix ) [
] ) } ( Some ( value ) , Some ( type_desc ) ) =>
{
early_error (
& format ! (
"incorrect value `{}` for {} \
option `{}` - {} was expected"
, value , $ outputname , key , type_desc ) [ ] )
} ( None , None ) => unreachable ! ( ) } } found
= true ; break ; } if ! found {
early_error (
& format ! ( "unknown codegen option: `{}`" , key
) [ ] ) ; } } return op ; } pub type $
setter_name = fn (
& mut $ struct_name , v : Option < & str > ) ->
bool ; pub const $ stat : & 'static [
(
& 'static str , $ setter_name , Option < &
'static str > , & 'static str ) ] = & [
$ (
(
stringify ! ( $ opt ) , $ mod_set :: $ opt , $
mod_desc :: $ parse , $ desc ) ) , * ] ; # [
allow ( non_upper_case_globals , dead_code ) ]
mod $ mod_desc {
pub const parse_bool : Option < & 'static str > =
None ; pub const parse_opt_bool : Option < &
'static str > = None ; pub const parse_string :
Option < & 'static str > = Some ( "a string" ) ;
pub const parse_opt_string : Option < & 'static
str > = Some ( "a string" ) ; pub const
parse_list : Option < & 'static str > = Some (
"a space-separated list of strings" ) ; pub const
parse_opt_list : Option < & 'static str > = Some
( "a space-separated list of strings" ) ; pub
const parse_uint : Option < & 'static str > =
Some ( "a number" ) ; pub const parse_passes :
Option < & 'static str > = Some (
"a space-separated list of passes, or `all`" ) ;
pub const parse_opt_uint : Option < & 'static str
> = Some ( "a number" ) ; } # [
allow ( dead_code ) ] mod $ mod_set {
use super::{
$ struct_name , Passes , SomePasses , AllPasses }
; $ (
pub fn $ opt (
cg : & mut $ struct_name , v : Option < & str > )
-> bool { $ parse ( & mut cg . $ opt , v ) } ) *
fn parse_bool (
slot : & mut bool , v : Option < & str > ) ->
bool {
match v {
Some ( .. ) => false , None => {
* slot = true ; true } } } fn parse_opt_bool (
slot : & mut Option < bool > , v : Option < & str
> ) -> bool {
match v {
Some ( .. ) => false , None => {
* slot = Some ( true ) ; true } } } fn
parse_opt_string (
slot : & mut Option < String > , v : Option < &
str > ) -> bool {
match v {
Some ( s ) => {
* slot = Some ( s . to_string ( ) ) ; true } ,
None => false , } } fn parse_string (
slot : & mut String , v : Option < & str > ) ->
bool {
match v {
Some ( s ) => {
* slot = s . to_string ( ) ; true } , None =>
false , } } fn parse_list (
slot : & mut Vec < String > , v : Option < & str
> ) -> bool {
match v {
Some ( s ) => {
for s in s . words ( ) {
slot . push ( s . to_string ( ) ) ; } true } ,
None => false , } } fn parse_opt_list (
slot : & mut Option < Vec < String >> , v :
Option < & str > ) -> bool {
match v {
Some ( s ) => {
let v = s . words ( ) . map (
| s | s . to_string ( ) ) . collect ( ) ; *
slot = Some ( v ) ; true } , None => false , } }
fn parse_uint (
slot : & mut uint , v : Option < & str > ) ->
bool {
match v . and_then ( | s | s . parse ( ) ) {
Some ( i ) => { * slot = i ; true } , None =>
false } } fn parse_opt_uint (
slot : & mut Option < uint > , v : Option < & str
> ) -> bool {
match v {
Some ( s ) => {
* slot = s . parse ( ) ; slot . is_some ( ) }
None => { * slot = None ; true } } } fn
parse_passes (
slot : & mut Passes , v : Option < & str > ) ->
bool {
match v {
Some ( "all" ) => { * slot = AllPasses ; true } v
=> {
let mut passes = vec ! ( ) ; if parse_list (
& mut passes , v ) {
* slot = SomePasses ( passes ) ; true } else {
false } } } } } ));
options! (CodegenOptions , CodegenSetter , basic_codegen_options ,
build_codegen_options , "C" , "codegen" , CG_OPTIONS ,
cg_type_desc , cgsetters , ar : Option < String > = (
None , parse_opt_string , "tool to assemble archives with" )
, linker : Option < String > = (
None , parse_opt_string ,
"system linker to link outputs with" ) , link_args : Option
< Vec < String >> = (
None , parse_opt_list ,
"extra arguments to pass to the linker (space separated)" )
, lto : bool = (
false , parse_bool , "perform LLVM link-time optimizations"
) , target_cpu : Option < String > = (
None , parse_opt_string ,
"select target processor (llc -mcpu=help for details)" ) ,
target_feature : String = (
"" . to_string ( ) , parse_string ,
"target specific attributes (llc -mattr=help for details)" )
, passes : Vec < String > = (
Vec :: new ( ) , parse_list ,
"a list of extra LLVM passes to run (space separated)" ) ,
llvm_args : Vec < String > = (
Vec :: new ( ) , parse_list ,
"a list of arguments to pass to llvm (space separated)" ) ,
save_temps : bool = (
false , parse_bool ,
"save all temporary output files during compilation" ) ,
rpath : bool = (
false , parse_bool , "set rpath values in libs/exes" ) ,
no_prepopulate_passes : bool = (
false , parse_bool ,
"don't pre-populate the pass manager with a list of passes"
) , no_vectorize_loops : bool = (
false , parse_bool ,
"don't run the loop vectorization optimization passes" ) ,
no_vectorize_slp : bool = (
false , parse_bool ,
"don't run LLVM's SLP vectorization pass" ) , soft_float :
bool = (
false , parse_bool ,
"generate software floating point library calls" ) ,
prefer_dynamic : bool = (
false , parse_bool ,
"prefer dynamic linking to static linking" ) ,
no_integrated_as : bool = (
false , parse_bool ,
"use an external assembler rather than LLVM's integrated one"
) , no_redzone : Option < bool > = (
None , parse_opt_bool , "disable the use of the redzone" ) ,
relocation_model : Option < String > = (
None , parse_opt_string ,
"choose the relocation model to use (llc -relocation-model for details)"
) , code_model : Option < String > = (
None , parse_opt_string ,
"choose the code model to use (llc -code-model for details)"
) , metadata : Vec < String > = (
Vec :: new ( ) , parse_list ,
"metadata to mangle symbol names with" ) , extra_filename :
String = (
"" . to_string ( ) , parse_string ,
"extra data to put in each output filename" ) ,
codegen_units : uint = (
1 , parse_uint ,
"divide crate into N units to optimize in parallel" ) ,
remark : Passes = (
SomePasses ( Vec :: new ( ) ) , parse_passes ,
"print remarks for these optimization passes (space separated, or \"all\")"
) , no_stack_check : bool = (
false , parse_bool ,
"disable checks for stack exhaustion (a memory-safety hazard!)"
) , debuginfo : Option < uint > = (
None , parse_opt_uint ,
"debug info emission level, 0 = no debug info, 1 = line tables only, \
2 = full debug info with variable and type information"
) , opt_level : Option < uint > = (
None , parse_opt_uint , "Optimize with possible levels 0-3"
) ,);
options! (DebuggingOptions , DebuggingSetter , basic_debugging_options
, build_debugging_options , "Z" , "debugging" , DB_OPTIONS ,
db_type_desc , dbsetters , verbose : bool = (
false , parse_bool ,
"in general, enable more debug printouts" ) , time_passes :
bool = (
false , parse_bool , "measure time of each rustc pass" ) ,
count_llvm_insns : bool = (
false , parse_bool , "count where LLVM instrs originate" ) ,
time_llvm_passes : bool = (
false , parse_bool , "measure time of each LLVM pass" ) ,
trans_stats : bool = (
false , parse_bool , "gather trans statistics" ) ,
asm_comments : bool = (
false , parse_bool ,
"generate comments into the assembly (may change behavior)"
) , no_verify : bool = (
false , parse_bool , "skip LLVM verification" ) ,
borrowck_stats : bool = (
false , parse_bool , "gather borrowck statistics" ) ,
no_landing_pads : bool = (
false , parse_bool , "omit landing pads for unwinding" ) ,
debug_llvm : bool = (
false , parse_bool , "enable debug output from LLVM" ) ,
count_type_sizes : bool = (
false , parse_bool , "count the sizes of aggregate types" )
, meta_stats : bool = (
false , parse_bool , "gather metadata statistics" ) ,
print_link_args : bool = (
false , parse_bool ,
"Print the arguments passed to the linker" ) , gc : bool = (
false , parse_bool ,
"Garbage collect shared data (experimental)" ) ,
print_llvm_passes : bool = (
false , parse_bool ,
"Prints the llvm optimization passes being run" ) , ast_json
: bool = (
false , parse_bool , "Print the AST as JSON and halt" ) ,
ast_json_noexpand : bool = (
false , parse_bool ,
"Print the pre-expansion AST as JSON and halt" ) , ls : bool
= (
false , parse_bool ,
"List the symbols defined by a library crate" ) ,
save_analysis : bool = (
false , parse_bool ,
"Write syntax and type analysis information in addition to normal output"
) , print_move_fragments : bool = (
false , parse_bool ,
"Print out move-fragment data for every fn" ) ,
flowgraph_print_loans : bool = (
false , parse_bool ,
"Include loan analysis data in --pretty flowgraph output" )
, flowgraph_print_moves : bool = (
false , parse_bool ,
"Include move analysis data in --pretty flowgraph output" )
, flowgraph_print_assigns : bool = (
false , parse_bool ,
"Include assignment analysis data in --pretty flowgraph output"
) , flowgraph_print_all : bool = (
false , parse_bool ,
"Include all dataflow analysis data in --pretty flowgraph output"
) , print_region_graph : bool = (
false , parse_bool ,
"Prints region inference graph. \
Use with RUST_REGION_GRAPH=help for more info"
) , parse_only : bool = (
false , parse_bool ,
"Parse only; do not compile, assemble, or link" ) , no_trans
: bool = (
false , parse_bool ,
"Run all passes except translation; no output" ) ,
no_analysis : bool = (
false , parse_bool ,
"Parse and expand the source, but run no analysis" ) ,
extra_plugins : Vec < String > = (
Vec :: new ( ) , parse_list , "load extra plugins" ) ,
unstable_options : bool = (
false , parse_bool ,
"Adds unstable command line options to rustc interface" ) ,
print_enum_sizes : bool = (
false , parse_bool ,
"Print the size of enums and their variants" ) ,);
pub fn default_lib_output() -> CrateType { loop { } }
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
loop { }
}
pub fn append_configuration(cfg: &mut ast::CrateConfig,
name: InternedString) {
loop { }
}
pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
loop { }
}
pub fn build_target_config(opts: &Options, sp: &SpanHandler)
-> Config {
loop { }
}
/// Returns the "short" subset of the stable rustc command line options.
pub fn short_optgroups() -> Vec<getopts::OptGroup> { loop { } }
/// Returns all of the stable rustc command line options.
pub fn optgroups() -> Vec<getopts::OptGroup> { loop { } }
#[derive(Copy, Clone, PartialEq, Eq, Show)]
pub enum OptionStability { Stable, Unstable, }
#[derive(Clone, PartialEq, Eq)]
pub struct RustcOptGroup {
pub opt_group: getopts::OptGroup,
pub stability: OptionStability,
}
impl RustcOptGroup {
pub fn is_stable(&self) -> bool { loop { } }
fn stable(g: getopts::OptGroup) -> RustcOptGroup { loop { } }
fn unstable(g: getopts::OptGroup) -> RustcOptGroup { loop { } }
}
mod opt {
#![allow(dead_code)]
use getopts;
use super::RustcOptGroup;
type R = RustcOptGroup;
type S<'a> = &'a str;
fn stable(g: getopts::OptGroup) -> R { loop { } }
fn unstable(g: getopts::OptGroup) -> R { loop { } }
pub fn opt(a: S, b: S, c: S, d: S) -> R { loop { } }
pub fn multi(a: S, b: S, c: S, d: S) -> R { loop { } }
pub fn flag(a: S, b: S, c: S) -> R { loop { } }
pub fn flagopt(a: S, b: S, c: S, d: S) -> R { loop { } }
pub fn opt_u(a: S, b: S, c: S, d: S) -> R { loop { } }
pub fn multi_u(a: S, b: S, c: S, d: S) -> R { loop { } }
pub fn flag_u(a: S, b: S, c: S) -> R { loop { } }
pub fn flagopt_u(a: S, b: S, c: S, d: S) -> R { loop { } }
}
/// Returns the "short" subset of the rustc command line options,
/// including metadata for each option, such as whether the option is
/// part of the stable long-term interface for rustc.
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> { loop { } }
/// Returns all rustc command line options, including metadata for
/// each option, such as whether the option is part of the stable
/// long-term interface for rustc.
pub fn rustc_optgroups() -> Vec<RustcOptGroup> { loop { } }
pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> ast::CrateConfig {
loop { }
}
pub fn build_session_options(matches: &getopts::Matches) -> Options {
loop { }
}
pub fn parse_crate_types_from_list(list_list: Vec<String>)
-> Result<Vec<CrateType>, String> {
loop { }
}
impl fmt::Show for CrateType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { loop { } }
}
#[cfg(test)]
mod test {
use session::config::{build_configuration, optgroups,
build_session_options};
use session::build_session;
use getopts::getopts;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostics;
#[test]
fn test_switch_implies_cfg_test() { loop { } }
#[test]
fn test_switch_implies_cfg_test_unless_cfg_test() { loop { } }
#[test]
fn test_can_print_warnings() { loop { } }
}
}
pub mod search_paths {
use std::slice;
#[derive(Clone)]
pub struct SearchPaths {
paths: Vec<(PathKind, Path)>,
}
pub struct Iter<'a> {
kind: PathKind,
iter: slice::Iter<'a, (PathKind, Path)>,
}
#[derive(Eq, PartialEq, Clone, Copy)]
pub enum PathKind { Native, Crate, Dependency, All, }
impl SearchPaths {
pub fn new() -> SearchPaths { loop { } }
pub fn add_path(&mut self, path: &str) { loop { } }
pub fn iter(&self, kind: PathKind) -> Iter { loop { } }
}
impl <'a> Iterator for Iter<'a> {type
Item
=
&'a Path;
fn next(&mut self) -> Option<&'a Path> { loop { } }
}
}
pub struct Session {
pub target: config::Config,
pub host: Target,
pub opts: config::Options,
pub cstore: CStore,
pub parse_sess: ParseSess,
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
pub entry_type: Cell<Option<config::EntryFnType>>,
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
pub default_sysroot: Option<Path>,
pub local_crate_source_file: Option<Path>,
pub working_dir: Path,
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span,
String)>>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
pub crate_metadata: RefCell<Vec<String>>,
pub features: RefCell<feature_gate::Features>,
/// The maximum recursion limit for potentially infinitely recursive
/// operations such as auto-dereference and monomorphization.
pub recursion_limit: Cell<uint>,
pub can_print_warnings: bool,
}
impl Session {
pub fn span_fatal(&self, sp: Span, msg: &str) -> ! { loop { } }
pub fn fatal(&self, msg: &str) -> ! { loop { } }
pub fn span_err(&self, sp: Span, msg: &str) { loop { } }
pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
loop { }
}
pub fn err(&self, msg: &str) { loop { } }
pub fn err_count(&self) -> uint { loop { } }
pub fn has_errors(&self) -> bool { loop { } }
pub fn abort_if_errors(&self) { loop { } }
pub fn span_warn(&self, sp: Span, msg: &str) { loop { } }
pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
loop { }
}
pub fn warn(&self, msg: &str) { loop { } }
pub fn opt_span_warn(&self, opt_sp: Option<Span>, msg: &str) {
loop { }
}
pub fn span_note(&self, sp: Span, msg: &str) { loop { } }
pub fn span_end_note(&self, sp: Span, msg: &str) { loop { } }
pub fn span_help(&self, sp: Span, msg: &str) { loop { } }
pub fn fileline_note(&self, sp: Span, msg: &str) { loop { } }
pub fn note(&self, msg: &str) { loop { } }
pub fn help(&self, msg: &str) { loop { } }
pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! {
loop { }
}
pub fn span_bug(&self, sp: Span, msg: &str) -> ! { loop { } }
pub fn bug(&self, msg: &str) -> ! { loop { } }
pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { loop { } }
pub fn unimpl(&self, msg: &str) -> ! { loop { } }
pub fn add_lint(&self, lint: &'static lint::Lint, id: ast::NodeId,
sp: Span, msg: String) {
loop { }
}
pub fn next_node_id(&self) -> ast::NodeId { loop { } }
pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
loop { }
}
pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler {
loop { }
}
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap { loop { } }
pub fn impossible_case(&self, sp: Span, msg: &str) -> ! { loop { } }
pub fn verbose(&self) -> bool { loop { } }
pub fn time_passes(&self) -> bool { loop { } }
pub fn count_llvm_insns(&self) -> bool { loop { } }
pub fn count_type_sizes(&self) -> bool { loop { } }
pub fn time_llvm_passes(&self) -> bool { loop { } }
pub fn trans_stats(&self) -> bool { loop { } }
pub fn meta_stats(&self) -> bool { loop { } }
pub fn asm_comments(&self) -> bool { loop { } }
pub fn no_verify(&self) -> bool { loop { } }
pub fn borrowck_stats(&self) -> bool { loop { } }
pub fn print_llvm_passes(&self) -> bool { loop { } }
pub fn lto(&self) -> bool { loop { } }
pub fn no_landing_pads(&self) -> bool { loop { } }
pub fn unstable_options(&self) -> bool { loop { } }
pub fn print_enum_sizes(&self) -> bool { loop { } }
pub fn sysroot<'a>(&'a self) -> &'a Path { loop { } }
pub fn target_filesearch(&self, kind: PathKind)
-> filesearch::FileSearch {
loop { }
}
pub fn host_filesearch(&self, kind: PathKind)
-> filesearch::FileSearch {
loop { }
}
}
pub fn build_session(sopts: config::Options,
local_crate_source_file: Option<Path>,
registry: diagnostics::registry::Registry)
-> Session {
loop { }
}
pub fn build_session_(sopts: config::Options,
local_crate_source_file: Option<Path>,
span_diagnostic: diagnostic::SpanHandler)
-> Session {
loop { }
}
pub fn expect<T, M>(sess: &Session, opt: Option<T>, msg: M) -> T where
M: FnOnce() -> String {
loop { }
}
pub fn early_error(msg: &str) -> ! { loop { } }
pub fn early_warn(msg: &str) { loop { } }
}
pub mod plugin {
//! Infrastructure for compiler plugins.
//!
//! Plugins are Rust libraries which extend the behavior of `rustc`
//! in various ways.
//!
//! Plugin authors will use the `Registry` type re-exported by
//! this module, along with its methods. The rest of the module
//! is for use by `rustc` itself.
//!
//! To define a plugin, build a dylib crate with a
//! `#[plugin_registrar]` function:
//!
//! ```rust,ignore
//! #![crate_name = "myplugin"]
//! #![crate_type = "dylib"]
//! #![feature(plugin_registrar)]
//!
//! extern crate rustc;
//!
//! use rustc::plugin::Registry;
//!
//! #[plugin_registrar]
//! pub fn plugin_registrar(reg: &mut Registry) {
//! reg.register_macro("mymacro", expand_mymacro);
//! }
//!
//! fn expand_mymacro(...) { // details elided
//! ```
//!
//! WARNING: We currently don't check that the registrar function
//! has the appropriate type!
//!
//! To use a plugin while compiling another crate:
//!
//! ```rust
//! #![feature(plugin)]
//!
//! #[plugin]
//! extern crate myplugin;
//! ```
//!
//! If you don't need the plugin crate available at runtime, use
//! `#[no_link]` as well.
//!
//! See [the compiler plugin guide](../../guide-plugin.html)
//! for more examples.
pub use self::registry::Registry;
pub mod registry {
//! Used by plugin crates to tell `rustc` about the plugins they provide.
use lint::{LintPassObject, LintId, Lint};
use session::Session;
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension,
NormalTT};
use syntax::ext::base::{IdentTT, Decorator, Modifier, MacroRulesTT};
use syntax::ext::base::{MacroExpanderFn};
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::ast;
use std::collections::HashMap;
/// Structure used to register plugins.
///
/// A plugin registrar function takes an `&mut Registry` and should call
/// methods to register its plugins.
///
/// This struct has public fields and other methods for use by `rustc`
/// itself. They are not documented here, and plugin authors should
/// not use them.
pub struct Registry<'a> {
/// Compiler session. Useful if you want to emit diagnostic messages
/// from the plugin registrar.
pub sess: &'a Session,
#[doc(hidden)]
pub args_hidden: Option<P<ast::MetaItem>>,
#[doc(hidden)]
pub krate_span: Span,
#[doc(hidden)]
pub syntax_exts: Vec<NamedSyntaxExtension>,
#[doc(hidden)]
pub lint_passes: Vec<LintPassObject>,
#[doc(hidden)]
pub lint_groups: HashMap<&'static str, Vec<LintId>>,
}
impl <'a> Registry<'a> {
#[doc(hidden)]
pub fn new(sess: &'a Session, krate: &ast::Crate)
-> Registry<'a> {
loop { }
}
/// Get the `#[plugin]` attribute used to load this plugin.
///
/// This gives access to arguments passed via `#[plugin=...]` or
/// `#[plugin(...)]`.
pub fn args<'b>(&'b self) -> &'b P<ast::MetaItem> { loop { } }
/// Register a syntax extension of any kind.
///
/// This is the most general hook into `libsyntax`'s expansion behavior.
pub fn register_syntax_extension(&mut self, name: ast::Name,
extension: SyntaxExtension) {
loop { }
}
/// Register a macro of the usual kind.
///
/// This is a convenience wrapper for `register_syntax_extension`.
/// It builds for you a `NormalTT` that calls `expander`,
/// and also takes care of interning the macro's name.
pub fn register_macro(&mut self, name: &str,
expander: MacroExpanderFn) {
loop { }
}
/// Register a compiler lint pass.
pub fn register_lint_pass(&mut self, lint_pass: LintPassObject) {
loop { }
}
/// Register a lint group.
pub fn register_lint_group(&mut self, name: &'static str,
to: Vec<&'static Lint>) {
loop { }
}
}
}
pub mod load {
//! Used by `rustc` when loading a plugin, or a crate with exported macros.
use session::Session;
use metadata::creader::{CrateOrString, CrateReader};
use plugin::registry::Registry;
use std::mem;
use std::os;
use std::dynamic_lib::DynamicLibrary;
use std::collections::HashSet;
use syntax::ast;
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::visit;
use syntax::visit::Visitor;
use syntax::attr::AttrMetaMethods;
/// Pointer to a registrar function.
pub type PluginRegistrarFun = fn(&mut Registry);
pub struct PluginRegistrar {
pub fun: PluginRegistrarFun,
pub args: P<ast::MetaItem>,
}
/// Information about loaded plugins.
pub struct Plugins {
/// Imported macros.
pub macros: Vec<ast::MacroDef>,
/// Registrars, as function pointers.
pub registrars: Vec<PluginRegistrar>,
}
pub struct PluginLoader<'a> {
sess: &'a Session,
span_whitelist: HashSet<Span>,
reader: CrateReader<'a>,
pub plugins: Plugins,
}
impl <'a> PluginLoader<'a> {
fn new(sess: &'a Session) -> PluginLoader<'a> { loop { } }
}
/// Read plugin metadata and dynamically load registrar functions.
pub fn load_plugins(sess: &Session, krate: &ast::Crate,
addl_plugins: Option<Vec<String>>) -> Plugins {
loop { }
}
impl <'a, 'v> Visitor<'v> for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem) { loop { } }
fn visit_mac(&mut self, _: &ast::Mac) { loop { } }
}
impl <'a> PluginLoader<'a> {
pub fn load_plugin<'b>(&mut self, c: CrateOrString<'b>,
plugin_attr: Option<P<ast::MetaItem>>,
macro_selection:
Option<HashSet<token::InternedString>>,
reexport:
Option<HashSet<token::InternedString>>) {
loop { }
}
fn dylink_registrar<'b>(&mut self, c: CrateOrString<'b>,
path: Path, symbol: String)
-> PluginRegistrarFun {
loop { }
}
}
}
pub mod build {
//! Used by `rustc` when compiling a plugin crate.
use syntax::ast;
use syntax::attr;
use syntax::codemap::Span;
use syntax::diagnostic;
use syntax::visit;
use syntax::visit::Visitor;
struct RegistrarFinder {
registrars: Vec<(ast::NodeId, Span)>,
}
impl <'v> Visitor<'v> for RegistrarFinder {
fn visit_item(&mut self, item: &ast::Item) { loop { } }
}
/// Find the function marked with `#[plugin_registrar]`, if any.
pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
krate: &ast::Crate)
-> Option<ast::NodeId> {
loop { }
}
}
}
pub mod lint {
//! Lints, aka compiler warnings.
//!
//! A 'lint' check is a kind of miscellaneous constraint that a user _might_
//! want to enforce, but might reasonably want to permit as well, on a
//! module-by-module basis. They contrast with static constraints enforced by
//! other phases of the compiler, which are generally required to hold in order
//! to compile the program at all.
//!
//! Most lints can be written as `LintPass` instances. These run just before
//! translation to LLVM bytecode. The `LintPass`es built into rustc are defined
//! within `builtin.rs`, which has further comments on how to add such a lint.
//! rustc can also load user-defined lint plugins via the plugin mechanism.
//!
//! Some of rustc's lints are defined elsewhere in the compiler and work by
//! calling `add_lint()` on the overall `Session` object. This works when
//! it happens before the main lint pass, which emits the lints stored by
//! `add_lint()`. To emit lints after the main lint pass (from trans, for
//! example) requires more effort. See `emit_lint` and `GatherNodeLevels`
//! in `context.rs`.
pub use self::Level::*;
pub use self::LintSource::*;
use std::hash;
use std::ascii::AsciiExt;
use syntax::codemap::Span;
use syntax::visit::FnKind;
use syntax::ast;
pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate,
gather_attrs};
/// Specification of a single lint.
#[derive(Copy, Show)]
pub struct Lint {
/// A string identifier for the lint.
///
/// This identifies the lint in attributes and in command-line arguments.
/// In those contexts it is always lowercase, but this field is compared
/// in a way which is case-insensitive for ASCII characters. This allows
/// `declare_lint!()` invocations to follow the convention of upper-case
/// statics without repeating the name.
///
/// The name is written with underscores, e.g. "unused_imports".
/// On the command line, underscores become dashes.
pub name: &'static str,
/// Default level for the lint.
pub default_level: Level,
/// Description of the lint or the issue it detects.
///
/// e.g. "imports that are never used"
pub desc: &'static str,
}
impl Lint {
/// Get the lint's name, with ASCII letters converted to lowercase.
pub fn name_lower(&self) -> String { loop { } }
}
/// Build a `Lint` initializer.
#[macro_export]
macro_rules! lint_initializer((
$ name : ident , $ level : ident , $ desc :
expr ) => (
:: rustc :: lint :: Lint {
name : stringify ! ( $ name ) ,
default_level : :: rustc :: lint :: $ level
, desc : $ desc , } ));
/// Declare a static item of type `&'static Lint`.
#[macro_export]
macro_rules! declare_lint((
pub $ name : ident , $ level : ident , $ desc :
expr ) => (
pub static $ name : & 'static :: rustc :: lint
:: Lint = & lint_initializer ! (
$ name , $ level , $ desc ) ; ) ; (
$ name : ident , $ level : ident , $ desc : expr
) => (
static $ name : & 'static :: rustc :: lint ::
Lint = & lint_initializer ! (
$ name , $ level , $ desc ) ; ) ;);
/// Declare a static `LintArray` and return it as an expression.
#[macro_export]
macro_rules! lint_array(( $ ( $ lint : expr ) , * ) => (
{
# [ allow ( non_upper_case_globals ) ] static
array : LintArray = & [ $ ( & $ lint ) , * ] ;
array } ));
pub type LintArray = &'static [&'static &'static Lint];
/// Trait for types providing lint checks.
///
/// Each `check` method checks a single syntax node, and should not
/// invoke methods recursively (unlike `Visitor`). By default they
/// do nothing.
pub trait LintPass {
/// Get descriptions of the lints this `LintPass` object can emit.
///
/// NB: there is no enforcement that the object only emits lints it registered.
/// And some `rustc` internal `LintPass`es register lints to be emitted by other
/// parts of the compiler. If you want enforced access restrictions for your
/// `Lint`, make it a private `static` item in its own module.
fn get_lints(&self) -> LintArray;
fn check_crate(&mut self, _: &Context, _: &ast::Crate) { loop { } }
fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) {
loop { }
}
fn check_mod(&mut self, _: &Context, _: &ast::Mod, _: Span,
_: ast::NodeId) {
loop { }
}
fn check_view_item(&mut self, _: &Context, _: &ast::ViewItem) {
loop { }
}
fn check_foreign_item(&mut self, _: &Context, _: &ast::ForeignItem) {
loop { }
}
fn check_item(&mut self, _: &Context, _: &ast::Item) { loop { } }
fn check_local(&mut self, _: &Context, _: &ast::Local) { loop { } }
fn check_block(&mut self, _: &Context, _: &ast::Block) { loop { } }
fn check_stmt(&mut self, _: &Context, _: &ast::Stmt) { loop { } }
fn check_arm(&mut self, _: &Context, _: &ast::Arm) { loop { } }
fn check_pat(&mut self, _: &Context, _: &ast::Pat) { loop { } }
fn check_decl(&mut self, _: &Context, _: &ast::Decl) { loop { } }
fn check_expr(&mut self, _: &Context, _: &ast::Expr) { loop { } }
fn check_expr_post(&mut self, _: &Context, _: &ast::Expr) {
loop { }
}
fn check_ty(&mut self, _: &Context, _: &ast::Ty) { loop { } }
fn check_generics(&mut self, _: &Context, _: &ast::Generics) {
loop { }
}
fn check_fn(&mut self, _: &Context, _: FnKind, _: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId) {
loop { }
}
fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) {
loop { }
}
fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) {
loop { }
}
fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef,
_: ast::Ident, _: &ast::Generics,
_: ast::NodeId) {
loop { }
}
fn check_struct_def_post(&mut self, _: &Context, _: &ast::StructDef,
_: ast::Ident, _: &ast::Generics,
_: ast::NodeId) {
loop { }
}
fn check_struct_field(&mut self, _: &Context, _: &ast::StructField) {
loop { }
}
fn check_variant(&mut self, _: &Context, _: &ast::Variant,
_: &ast::Generics) {
loop { }
}
fn check_variant_post(&mut self, _: &Context, _: &ast::Variant,
_: &ast::Generics) {
loop { }
}
fn check_opt_lifetime_ref(&mut self, _: &Context, _: Span,
_: &Option<ast::Lifetime>) {
loop { }
}
fn check_lifetime_ref(&mut self, _: &Context, _: &ast::Lifetime) {
loop { }
}
fn check_lifetime_def(&mut self, _: &Context, _: &ast::LifetimeDef) {
loop { }
}
fn check_explicit_self(&mut self, _: &Context,
_: &ast::ExplicitSelf) {
loop { }
}
fn check_mac(&mut self, _: &Context, _: &ast::Mac) { loop { } }
fn check_path(&mut self, _: &Context, _: &ast::Path, _: ast::NodeId) {
loop { }
}
fn check_attribute(&mut self, _: &Context, _: &ast::Attribute) {
loop { }
}
/// Called when entering a syntax node that can have lint attributes such
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
fn enter_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) {
loop { }
}
/// Counterpart to `enter_lint_attrs`.
fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) {
loop { }
}
}
/// A lint pass boxed up as a trait object.
pub type LintPassObject = Box<LintPass+ 'static>;
/// Identifies a lint known to the compiler.
#[derive(Clone, Copy)]
pub struct LintId {
lint: &'static Lint,
}
impl PartialEq for LintId {
fn eq(&self, other: &LintId) -> bool { loop { } }
}
impl Eq for LintId { }
impl <S: hash::Writer + hash::Hasher> hash::Hash<S> for LintId {
fn hash(&self, state: &mut S) { loop { } }
}
impl LintId {
/// Get the `LintId` for a `Lint`.
pub fn of(lint: &'static Lint) -> LintId { loop { } }
/// Get the name of the lint.
pub fn as_str(&self) -> String { loop { } }
}
/// Setting for how to handle a lint.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Show)]
pub enum Level { Allow, Warn, Deny, Forbid, }
impl Level {
/// Convert a level to a lower-case string.
pub fn as_str(self) -> &'static str { loop { } }
/// Convert a lower-case string to a level.
pub fn from_str(x: &str) -> Option<Level> { loop { } }
}
/// How a lint level was set.
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum LintSource {
/// Lint is at the default level as declared
/// in rustc or a plugin.
Default,
/// Lint level was set by an attribute.
Node(Span),
/// Lint level was set by a command-line flag.
CommandLine,
/// Lint level was set by the release channel.
ReleaseChannel,
}
pub type LevelSource = (Level, LintSource);
pub mod builtin {
//! Lints built in to rustc.
//!
//! This is a sibling of `lint::context` in order to ensure that
//! lints implemented here use the same public API as lint plugins.
//!
//! To add a new lint to rustc, declare it here using `declare_lint!()`.
//! Then add code to emit the new lint in the appropriate circumstances.
//! You can do that in an existing `LintPass` if it makes sense, or in
//! a new `LintPass`, or using `Session::add_lint` elsewhere in the
//! compiler. Only do the latter if the check can't be written cleanly
//! as a `LintPass`.
//!
//! If you define a new `LintPass`, you will also need to add it to the
//! `add_builtin!` or `add_builtin_with_new!` invocation in `context.rs`.
//! Use the former for unit-like structs and the latter for structs with
//! a `pub fn new()`.
use self::MethodContext::*;
use metadata::csearch;
use middle::def::*;
use middle::subst::Substs;
use middle::ty::{self, Ty};
use middle::{def, pat_util, stability};
use middle::const_eval::{eval_const_expr_partial, const_int,
const_uint};
use util::ppaux::{ty_to_string};
use util::nodemap::{FnvHashMap, NodeSet};
use lint::{Context, LintPass, LintArray, Lint};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::num::SignedInt;
use std::{cmp, slice};
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::{abi, ast, ast_map};
use syntax::ast_util::is_shift_binop;
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::parse::token;
use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32,
TyI64, TyU64};
use syntax::ast_util;
use syntax::ptr::P;
use syntax::visit::{self, Visitor};
declare_lint! (WHILE_TRUE , Warn ,
"suggest using `loop { }` instead of `while true { }`");
#[derive(Copy)]
pub struct WhileTrue;
impl LintPass for WhileTrue {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (UNUSED_TYPECASTS , Allow ,
"detects unnecessary type casts that can be removed");
#[derive(Copy)]
pub struct UnusedCasts;
impl LintPass for UnusedCasts {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (UNSIGNED_NEGATION , Warn ,
"using an unary minus operator on unsigned type");
declare_lint! (UNUSED_COMPARISONS , Warn ,
"comparisons made useless by limits of the types involved");
declare_lint! (OVERFLOWING_LITERALS , Warn ,
"literal out of range for its type");
declare_lint! (EXCEEDING_BITSHIFTS , Deny ,
"shift exceeds the type's number of bits");
#[derive(Copy)]
pub struct TypeLimits {
/// Id of the last visited negated expression
negated_expr_id: ast::NodeId,
}
impl TypeLimits {
pub fn new() -> TypeLimits { loop { } }
}
impl LintPass for TypeLimits {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (IMPROPER_CTYPES , Warn ,
"proper use of libc types in foreign modules");
struct ImproperCTypesVisitor<'a, 'tcx:'a> {
cx: &'a Context<'a, 'tcx>,
}
impl <'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
fn check_def(&mut self, sp: Span, ty_id: ast::NodeId,
path_id: ast::NodeId) {
loop { }
}
}
impl <'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) { loop { } }
}
#[derive(Copy)]
pub struct ImproperCTypes;
impl LintPass for ImproperCTypes {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
}
declare_lint! (BOX_POINTERS , Allow ,
"use of owned (Box type) heap memory");
#[derive(Copy)]
pub struct BoxPointers;
impl BoxPointers {
fn check_heap_type<'a,
'tcx>(&self, cx: &Context<'a, 'tcx>,
span: Span, ty: Ty<'tcx>) {
loop { }
}
}
impl LintPass for BoxPointers {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (RAW_POINTER_DERIVE , Warn ,
"uses of #[derive] with raw pointers are rarely correct");
struct RawPtrDeriveVisitor<'a, 'tcx:'a> {
cx: &'a Context<'a, 'tcx>,
}
impl <'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) { loop { } }
fn visit_expr(&mut self, _: &ast::Expr) { loop { } }
fn visit_block(&mut self, _: &ast::Block) { loop { } }
}
pub struct RawPointerDerive {
checked_raw_pointers: NodeSet,
}
impl RawPointerDerive {
pub fn new() -> RawPointerDerive { loop { } }
}
impl LintPass for RawPointerDerive {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
loop { }
}
}
declare_lint! (UNUSED_ATTRIBUTES , Warn ,
"detects attributes that were not used by the compiler");
#[derive(Copy)]
pub struct UnusedAttributes;
impl LintPass for UnusedAttributes {
fn get_lints(&self) -> LintArray { loop { } }
fn check_attribute(&mut self, cx: &Context,
attr: &ast::Attribute) {
loop { }
}
}
declare_lint! (pub PATH_STATEMENTS , Warn ,
"path statements with no effect");
#[derive(Copy)]
pub struct PathStatements;
impl LintPass for PathStatements {
fn get_lints(&self) -> LintArray { loop { } }
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
loop { }
}
}
declare_lint! (pub UNUSED_MUST_USE , Warn ,
"unused result of a type flagged as #[must_use]");
declare_lint! (pub UNUSED_RESULTS , Allow ,
"unused result of an expression in a statement");
#[derive(Copy)]
pub struct UnusedResults;
impl LintPass for UnusedResults {
fn get_lints(&self) -> LintArray { loop { } }
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
loop { }
}
}
declare_lint! (pub NON_CAMEL_CASE_TYPES , Warn ,
"types, variants, traits and type parameters should have camel case names");
#[derive(Copy)]
pub struct NonCamelCaseTypes;
impl NonCamelCaseTypes {
fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident,
span: Span) {
loop { }
}
}
impl LintPass for NonCamelCaseTypes {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
fn check_generics(&mut self, cx: &Context, it: &ast::Generics) {
loop { }
}
}
#[derive(PartialEq)]
enum MethodContext { TraitDefaultImpl, TraitImpl, PlainImpl, }
fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
loop { }
}
declare_lint! (pub NON_SNAKE_CASE , Warn ,
"methods, functions, lifetime parameters and modules should have snake case names");
#[derive(Copy)]
pub struct NonSnakeCase;
impl NonSnakeCase {
fn check_snake_case(&self, cx: &Context, sort: &str,
ident: ast::Ident, span: Span) {
loop { }
}
}
impl LintPass for NonSnakeCase {
fn get_lints(&self) -> LintArray { loop { } }
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind,
_: &ast::FnDecl, _: &ast::Block, span: Span,
_: ast::NodeId) {
loop { }
}
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
fn check_ty_method(&mut self, cx: &Context, t: &ast::TypeMethod) {
loop { }
}
fn check_lifetime_def(&mut self, cx: &Context,
t: &ast::LifetimeDef) {
loop { }
}
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { loop { } }
fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
_: ast::Ident, _: &ast::Generics,
_: ast::NodeId) {
loop { }
}
}
declare_lint! (pub NON_UPPER_CASE_GLOBALS , Warn ,
"static constants should have uppercase identifiers");
#[derive(Copy)]
pub struct NonUpperCaseGlobals;
impl LintPass for NonUpperCaseGlobals {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { loop { } }
}
declare_lint! (UNUSED_PARENS , Warn ,
"`if`, `match`, `while` and `return` do not need parentheses");
#[derive(Copy)]
pub struct UnusedParens;
impl UnusedParens {
fn check_unused_parens_core(&self, cx: &Context,
value: &ast::Expr, msg: &str,
struct_lit_needs_parens: bool) {
loop { }
}
}
impl LintPass for UnusedParens {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
loop { }
}
}
declare_lint! (UNUSED_IMPORT_BRACES , Allow ,
"unnecessary braces around an imported item");
#[derive(Copy)]
pub struct UnusedImportBraces;
impl LintPass for UnusedImportBraces {
fn get_lints(&self) -> LintArray { loop { } }
fn check_view_item(&mut self, cx: &Context,
view_item: &ast::ViewItem) {
loop { }
}
}
declare_lint! (NON_SHORTHAND_FIELD_PATTERNS , Warn ,
"using `Struct { x: x }` instead of `Struct { x }`");
#[derive(Copy)]
pub struct NonShorthandFieldPatterns;
impl LintPass for NonShorthandFieldPatterns {
fn get_lints(&self) -> LintArray { loop { } }
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
loop { }
}
}
declare_lint! (pub UNUSED_UNSAFE , Warn ,
"unnecessary use of an `unsafe` block");
#[derive(Copy)]
pub struct UnusedUnsafe;
impl LintPass for UnusedUnsafe {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (UNSAFE_BLOCKS , Allow , "usage of an `unsafe` block");
#[derive(Copy)]
pub struct UnsafeBlocks;
impl LintPass for UnsafeBlocks {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (pub UNUSED_MUT , Warn ,
"detect mut variables which don't need to be mutable");
#[derive(Copy)]
pub struct UnusedMut;
impl UnusedMut {
fn check_unused_mut_pat(&self, cx: &Context,
pats: &[P<ast::Pat>]) {
loop { }
}
}
impl LintPass for UnusedMut {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
loop { }
}
fn check_fn(&mut self, cx: &Context, _: visit::FnKind,
decl: &ast::FnDecl, _: &ast::Block, _: Span,
_: ast::NodeId) {
loop { }
}
}
declare_lint! (UNUSED_ALLOCATION , Warn ,
"detects unnecessary allocations that can be eliminated");
#[derive(Copy)]
pub struct UnusedAllocation;
impl LintPass for UnusedAllocation {
fn get_lints(&self) -> LintArray { loop { } }
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
}
declare_lint! (MISSING_DOCS , Allow ,
"detects missing documentation for public members");
pub struct MissingDoc {
/// Stack of IDs of struct definitions.
struct_def_stack: Vec<ast::NodeId>,
/// True if inside variant definition
in_variant: bool,
/// Stack of whether #[doc(hidden)] is set
/// at each level which has lint attributes.
doc_hidden_stack: Vec<bool>,
}
impl MissingDoc {
pub fn new() -> MissingDoc { loop { } }
fn doc_hidden(&self) -> bool { loop { } }
fn check_missing_docs_attrs(&self, cx: &Context,
id: Option<ast::NodeId>,
attrs: &[ast::Attribute], sp: Span,
desc: &'static str) {
loop { }
}
}
impl LintPass for MissingDoc {
fn get_lints(&self) -> LintArray { loop { } }
fn enter_lint_attrs(&mut self, _: &Context,
attrs: &[ast::Attribute]) {
loop { }
}
fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) {
loop { }
}
fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef,
_: ast::Ident, _: &ast::Generics,
id: ast::NodeId) {
loop { }
}
fn check_struct_def_post(&mut self, _: &Context,
_: &ast::StructDef, _: ast::Ident,
_: &ast::Generics, id: ast::NodeId) {
loop { }
}
fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
loop { }
}
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind,
_: &ast::FnDecl, _: &ast::Block, _: Span,
_: ast::NodeId) {
loop { }
}
fn check_ty_method(&mut self, cx: &Context,
tm: &ast::TypeMethod) {
loop { }
}
fn check_struct_field(&mut self, cx: &Context,
sf: &ast::StructField) {
loop { }
}
fn check_variant(&mut self, cx: &Context, v: &ast::Variant,
_: &ast::Generics) {
loop { }
}
fn check_variant_post(&mut self, _: &Context, _: &ast::Variant,
_: &ast::Generics) {
loop { }
}
}
#[derive(Copy)]
pub struct MissingCopyImplementations;
impl LintPass for MissingCopyImplementations {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
loop { }
}
}
declare_lint! (DEPRECATED , Warn ,
"detects use of #[deprecated] items");
declare_lint! (UNSTABLE , Warn ,
"detects use of #[unstable] items (incl. items with no stability attribute)");
/// Checks for use of items with `#[deprecated]`, `#[unstable]` and
/// `#[unstable]` attributes, or no stability attribute.
#[derive(Copy)]
pub struct Stability {
this_crate_staged: bool,
}
impl Stability {
pub fn new() -> Stability { loop { } }
fn lint(&self, cx: &Context, id: ast::DefId, span: Span) {
loop { }
}
fn is_internal(&self, cx: &Context, span: Span) -> bool {
loop { }
}
}
impl LintPass for Stability {
fn get_lints(&self) -> LintArray { loop { } }
fn check_crate(&mut self, _: &Context, c: &ast::Crate) {
loop { }
}
fn check_view_item(&mut self, cx: &Context,
item: &ast::ViewItem) {
loop { }
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
loop { }
}
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
loop { }
}
}
declare_lint! (pub UNUSED_IMPORTS , Warn ,
"imports that are never used");
declare_lint! (pub UNUSED_EXTERN_CRATES , Allow ,
"extern crates that are never used");
declare_lint! (pub UNUSED_QUALIFICATIONS , Allow ,
"detects unnecessarily qualified names");
declare_lint! (pub UNKNOWN_LINTS , Warn ,
"unrecognized lint attribute");
declare_lint! (pub UNUSED_VARIABLES , Warn ,
"detect variables which are not used in any way");
declare_lint! (pub UNUSED_ASSIGNMENTS , Warn ,
"detect assignments that will never be read");
declare_lint! (pub DEAD_CODE , Warn ,
"detect unused, unexported items");
declare_lint! (pub UNREACHABLE_CODE , Warn ,
"detects unreachable code paths");
declare_lint! (pub WARNINGS , Warn ,
"mass-change the level for lints which produce warnings");
declare_lint! (pub UNKNOWN_FEATURES , Deny ,
"unknown features found in crate-level #[feature] directives");
declare_lint! (pub UNKNOWN_CRATE_TYPES , Deny ,
"unknown crate type found in #[crate_type] directive");
declare_lint! (pub VARIANT_SIZE_DIFFERENCES , Allow ,
"detects enums with widely varying variant sizes");
declare_lint! (pub FAT_PTR_TRANSMUTES , Allow ,
"detects transmutes of fat pointers");
declare_lint! (pub MISSING_COPY_IMPLEMENTATIONS , Warn ,
"detects potentially-forgotten implementations of `Copy`");
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy)]
pub struct HardwiredLints;
impl LintPass for HardwiredLints {
fn get_lints(&self) -> LintArray { loop { } }
}
/// Forbids using the `#[feature(...)]` attribute
#[derive(Copy)]
pub struct UnstableFeatures;
declare_lint! (UNSTABLE_FEATURES , Allow ,
"enabling unstable features");
impl LintPass for UnstableFeatures {
fn get_lints(&self) -> LintArray { loop { } }
fn check_attribute(&mut self, ctx: &Context,
attr: &ast::Attribute) {
loop { }
}
}
}
mod context {
//! Implementation of lint checking.
//!
//! The lint checking is mostly consolidated into one pass which runs just
//! before translation to LLVM bytecode. Throughout compilation, lint warnings
//! can be added via the `add_lint` method on the Session structure. This
//! requires a span and an id of the node that the lint is being added to. The
//! lint isn't actually emitted at that time because it is unknown what the
//! actual lint level at that location is.
//!
//! To actually emit lint warnings/errors, a separate pass is used just before
//! translation. A context keeps track of the current state of all lint levels.
//! Upon entering a node of the ast which can modify the lint settings, the
//! previous lint state is pushed onto a stack and the ast is then recursed
//! upon. As the ast is traversed, this keeps track of the current lint level
//! for all lint attributes.
use self::TargetLint::*;
use middle::privacy::ExportedItems;
use middle::ty::{self, Ty};
use session::{early_error, Session};
use session::config::UnstableFeatures;
use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass,
LintPassObject};
use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid,
ReleaseChannel};
use lint::builtin;
use util::nodemap::FnvHashMap;
use std::cell::RefCell;
use std::mem;
use syntax::ast_util::IdVisitingOperation;
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::codemap::Span;
use syntax::visit::{Visitor, FnKind};
use syntax::parse::token::InternedString;
use syntax::{ast, ast_util, visit};
/// Information about the registered lints.
///
/// This is basically the subset of `Context` that we can
/// build early in the compile pipeline.
pub struct LintStore {
/// Registered lints. The bool is true if the lint was
/// added by a plugin.
lints: Vec<(&'static Lint, bool)>,
/// Trait objects for each lint pass.
/// This is only `None` while iterating over the objects. See the definition
/// of run_lints.
passes: Option<Vec<LintPassObject>>,
/// Lints indexed by name.
by_name: FnvHashMap<String, TargetLint>,
/// Current levels of each lint, and where they were set.
levels: FnvHashMap<LintId, LevelSource>,
/// Map of registered lint groups to what lints they expand to. The bool
/// is true if the lint group was added by a plugin.
lint_groups: FnvHashMap<&'static str, (Vec<LintId>, bool)>,
}
/// The targed of the `by_name` map, which accounts for renaming/deprecation.
enum TargetLint {
/// A direct lint target
Id(LintId),
/// Temporary renaming, used for easing migration pain; see #16545
Renamed(String, LintId),
}
impl LintStore {
fn get_level_source(&self, lint: LintId) -> LevelSource {
loop { }
}
fn set_level(&mut self, lint: LintId, lvlsrc: LevelSource) {
loop { }
}
pub fn new() -> LintStore { loop { } }
pub fn get_lints<'t>(&'t self) -> &'t [(&'static Lint, bool)] {
loop { }
}
pub fn get_lint_groups<'t>(&'t self)
-> Vec<(&'static str, Vec<LintId>, bool)> {
loop { }
}
pub fn register_pass(&mut self, sess: Option<&Session>,
from_plugin: bool, pass: LintPassObject) {
loop { }
}
pub fn register_group(&mut self, sess: Option<&Session>,
from_plugin: bool, name: &'static str,
to: Vec<LintId>) {
loop { }
}
fn register_renamed(&mut self, old_name: &str, new_name: &str) {
loop { }
}
pub fn register_builtin(&mut self, sess: Option<&Session>) {
loop { }
}
#[allow(unused_variables)]
fn find_lint(&self, lint_name: &str, sess: &Session,
span: Option<Span>) -> Option<LintId> {
loop { }
}
pub fn process_command_line(&mut self, sess: &Session) {
loop { }
}
fn maybe_stage_features(&mut self, sess: &Session) { loop { } }
}
/// Context for lint checking.
pub struct Context<'a, 'tcx:'a> {
/// Type context we're checking in.
pub tcx: &'a ty::ctxt<'tcx>,
/// The crate being checked.
pub krate: &'a ast::Crate,
/// Items exported from the crate being checked.
pub exported_items: &'a ExportedItems,
/// The store of registered lints.
lints: LintStore,
/// When recursing into an attributed node of the ast which modifies lint
/// levels, this stack keeps track of the previous lint levels of whatever
/// was modified.
level_stack: Vec<(LintId, LevelSource)>,
/// Level of lints for certain NodeIds, stored here because the body of
/// the lint needs to run in trans.
node_levels: RefCell<FnvHashMap<(ast::NodeId, LintId),
LevelSource>>,
}
/// Convenience macro for calling a `LintPass` method on every pass in the context.
macro_rules! run_lints((
$ cx : expr , $ f : ident , $ ( $ args : expr )
, * ) => (
{
let mut passes = $ cx . lints . passes . take (
) . unwrap ( ) ; for obj in passes . iter_mut
( ) { obj . $ f ( $ cx , $ ( $ args ) , * ) ;
} $ cx . lints . passes = Some ( passes ) ; }
));
/// Parse the lint attributes into a vector, with `Err`s for malformed lint
/// attributes. Writing this as an iterator is an enormous mess.
pub fn gather_attrs(attrs: &[ast::Attribute])
-> Vec<Result<(InternedString, Level, Span), Span>> {
loop { }
}
/// Emit a lint as a warning or an error (or not at all)
/// according to `level`.
///
/// This lives outside of `Context` so it can be used by checks
/// in trans that run after the main lint pass is finished. Most
/// lints elsewhere in the compiler should call
/// `Session::add_lint()` instead.
pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
lvlsrc: LevelSource, span: Option<Span>,
msg: &str) {
loop { }
}
impl <'a, 'tcx> Context<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>, krate: &'a ast::Crate,
exported_items: &'a ExportedItems) -> Context<'a, 'tcx> {
loop { }
}
/// Get the overall compiler `Session` object.
pub fn sess(&'a self) -> &'a Session { loop { } }
/// Get the level of `lint` at the current position of the lint
/// traversal.
pub fn current_level(&self, lint: &'static Lint) -> Level {
loop { }
}
fn lookup_and_emit(&self, lint: &'static Lint, span: Option<Span>,
msg: &str) {
loop { }
}
/// Emit a lint at the appropriate level, with no associated span.
pub fn lint(&self, lint: &'static Lint, msg: &str) { loop { } }
/// Emit a lint at the appropriate level, for a particular span.
pub fn span_lint(&self, lint: &'static Lint, span: Span,
msg: &str) {
loop { }
}
/// Merge the lints specified by any lint attributes into the
/// current lint context, call the provided function, then reset the
/// lints in effect to their previous state.
fn with_lint_attrs<F>(&mut self, attrs: &[ast::Attribute], f: F)
where F: FnOnce(&mut Context) {
loop { }
}
fn visit_ids<F>(&mut self, f: F) where
F: FnOnce(&mut ast_util::IdVisitor<Context>) {
loop { }
}
}
impl <'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
fn visit_item(&mut self, it: &ast::Item) { loop { } }
fn visit_foreign_item(&mut self, it: &ast::ForeignItem) {
loop { }
}
fn visit_view_item(&mut self, i: &ast::ViewItem) { loop { } }
fn visit_pat(&mut self, p: &ast::Pat) { loop { } }
fn visit_expr(&mut self, e: &ast::Expr) { loop { } }
fn visit_stmt(&mut self, s: &ast::Stmt) { loop { } }
fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v ast::FnDecl,
body: &'v ast::Block, span: Span, id: ast::NodeId) {
loop { }
}
fn visit_ty_method(&mut self, t: &ast::TypeMethod) { loop { } }
fn visit_struct_def(&mut self, s: &ast::StructDef,
ident: ast::Ident, g: &ast::Generics,
id: ast::NodeId) {
loop { }
}
fn visit_struct_field(&mut self, s: &ast::StructField) {
loop { }
}
fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
loop { }
}
fn visit_ty(&mut self, t: &ast::Ty) { loop { } }
fn visit_ident(&mut self, sp: Span, id: ast::Ident) { loop { } }
fn visit_mod(&mut self, m: &ast::Mod, s: Span, n: ast::NodeId) {
loop { }
}
fn visit_local(&mut self, l: &ast::Local) { loop { } }
fn visit_block(&mut self, b: &ast::Block) { loop { } }
fn visit_arm(&mut self, a: &ast::Arm) { loop { } }
fn visit_decl(&mut self, d: &ast::Decl) { loop { } }
fn visit_expr_post(&mut self, e: &ast::Expr) { loop { } }
fn visit_generics(&mut self, g: &ast::Generics) { loop { } }
fn visit_trait_item(&mut self, m: &ast::TraitItem) { loop { } }
fn visit_opt_lifetime_ref(&mut self, sp: Span,
lt: &Option<ast::Lifetime>) {
loop { }
}
fn visit_lifetime_ref(&mut self, lt: &ast::Lifetime) { loop { } }
fn visit_lifetime_def(&mut self, lt: &ast::LifetimeDef) {
loop { }
}
fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf) {
loop { }
}
fn visit_mac(&mut self, mac: &ast::Mac) { loop { } }
fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
loop { }
}
fn visit_attribute(&mut self, attr: &ast::Attribute) { loop { } }
}
impl <'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> {
fn visit_id(&mut self, id: ast::NodeId) { loop { } }
}
struct GatherNodeLevels;
impl LintPass for GatherNodeLevels {
fn get_lints(&self) -> LintArray { loop { } }
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
loop { }
}
}
/// Perform lint checking on a crate.
///
/// Consumes the `lint_store` field of the `Session`.
pub fn check_crate(tcx: &ty::ctxt, exported_items: &ExportedItems) {
loop { }
}
}
}
pub mod util {
pub use rustc_back::fs;
pub use rustc_back::sha2;
pub mod common {
#![allow(non_camel_case_types)]
use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::fmt::Show;
use std::hash::{Hash, Hasher};
use std::iter::repeat;
use std::time::Duration;
use std::collections::hash_state::HashState;
use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;
#[derive(Clone, Copy, Show)]
pub struct ErrorReported;
pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
F: FnOnce(U) -> T {
loop { }
}
pub fn indent<R, F>(op: F) -> R where R: Show, F: FnOnce() -> R {
loop { }
}
pub struct Indenter {
_cannot_construct_outside_of_this_module: (),
}
impl Drop for Indenter {
fn drop(&mut self) { loop { } }
}
pub fn indenter() -> Indenter { loop { } }
struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
p: P,
flag: bool,
}
impl <'v, P> Visitor<'v> for LoopQueryVisitor<P> where
P: FnMut(&ast::Expr_) -> bool {
fn visit_expr(&mut self, e: &ast::Expr) { loop { } }
}
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where
P: FnMut(&ast::Expr_) -> bool {
loop { }
}
struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
p: P,
flag: bool,
}
impl <'v, P> Visitor<'v> for BlockQueryVisitor<P> where
P: FnMut(&ast::Expr) -> bool {
fn visit_expr(&mut self, e: &ast::Expr) { loop { } }
}
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where
P: FnMut(&ast::Expr) -> bool {
loop { }
}
/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`. The graph is defined by
/// the `edges_map`, which maps from a node `S` to a list of its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is typically invoked on
/// very small graphs. If the graphs become larger, a more efficient graph representation and
/// algorithm would probably be advised.
pub fn can_reach<T,
S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
destination: T) -> bool where S: HashState,
<S as HashState>::Hasher: Hasher<Output = u64>,
T: Hash<<S as HashState>::Hasher> + Eq + Clone {
loop { }
}
/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
/// cache: &RefCell<M>,
/// f: &|&: T| -> U
/// ) -> impl |&: T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Example
/// ```
/// struct Context {
/// cache: RefCell<HashMap<uint, uint>>
/// }
///
/// fn factorial(ctxt: &Context, n: uint) -> uint {
/// memoized(&ctxt.cache, n, |n| match n {
/// 0 | 1 => n,
/// _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
/// })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S,
F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F)
-> U where T: Clone + Hash<<S as HashState>::Hasher> + Eq, U: Clone,
S: HashState, <S as HashState>::Hasher: Hasher<Output = u64>,
F: FnOnce(T) -> U {
loop { }
}
}
pub mod ppaux {
use middle::def;
use middle::subst::{VecPerParamSpace, Subst};
use middle::subst;
use middle::ty::{BoundRegion, BrAnon, BrNamed};
use middle::ty::{ReEarlyBound, BrFresh, ctxt};
use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
use middle::ty::{ReSkolemized, ReVar, BrEnv};
use middle::ty::{mt, Ty, ParamTy};
use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
use middle::ty::{ty_unboxed_closure};
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
use middle::ty;
use middle::ty_fold::TypeFoldable;
use std::collections::HashMap;
use std::collections::hash_state::HashState;
use std::hash::{Hash, Hasher};
use std::rc::Rc;
use syntax::abi;
use syntax::ast_map;
use syntax::codemap::{Span, Pos};
use syntax::parse::token;
use syntax::print::pprust;
use syntax::ptr::P;
use syntax::{ast, ast_util};
use syntax::owned_slice::OwnedSlice;
/// Produces a string suitable for debugging output.
pub trait Repr<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String;
}
/// Produces a string suitable for showing to the user.
pub trait UserString<'tcx>: Repr<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String;
}
pub fn note_and_explain_region(cx: &ctxt, prefix: &str,
region: ty::Region, suffix: &str)
-> Option<Span> {
loop { }
}
/// When a free region is associated with `item`, how should we describe the item in the error
/// message.
fn item_scope_tag(item: &ast::Item) -> &'static str { loop { } }
pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
-> (String, Option<Span>) {
loop { }
}
pub fn bound_region_ptr_to_string(cx: &ctxt, br: BoundRegion)
-> String {
loop { }
}
pub fn bound_region_to_string(cx: &ctxt, prefix: &str, space: bool,
br: BoundRegion) -> String {
loop { }
}
pub fn region_ptr_to_string(cx: &ctxt, region: Region) -> String {
loop { }
}
pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool,
region: Region) -> String {
loop { }
}
pub fn mutability_to_string(m: ast::Mutability) -> String {
loop { }
}
pub fn mt_to_string<'tcx>(cx: &ctxt<'tcx>, m: &mt<'tcx>) -> String {
loop { }
}
pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
loop { }
}
pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
F: FnMut(&T) -> String {
loop { }
}
pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>)
-> String {
loop { }
}
pub fn explicit_self_category_to_str(category:
&ty::ExplicitSelfCategory)
-> &'static str {
loop { }
}
pub fn parameterized<'tcx>(cx: &ctxt<'tcx>, base: &str,
substs: &subst::Substs<'tcx>,
generics: &ty::Generics<'tcx>,
did: ast::DefId) -> String {
loop { }
}
pub fn ty_to_short_str<'tcx>(cx: &ctxt<'tcx>, typ: Ty<'tcx>)
-> String {
loop { }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for Option<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for P<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>, U: Repr<'tcx>> Repr<'tcx> for Result<T, U>
{
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for () {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'a, 'tcx, T: ?Sized + Repr<'tcx>> Repr<'tcx> for &'a T {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for Rc<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for Box<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
fn repr_vec<'tcx, T: Repr<'tcx>>(tcx: &ctxt<'tcx>, v: &[T])
-> String {
loop { }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for [T] {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for Vec<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: UserString<'tcx>> UserString<'tcx> for Vec<T> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for def::Def {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TypeParameterDef<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::RegionParameterDef {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TyS<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::mt<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for subst::Substs<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for subst::VecPerParamSpace<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::ItemSubsts<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for subst::RegionSubsts {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::BuiltinBounds {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::ExistentialBounds<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::ParamBounds<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::TraitItem {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Expr {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Path {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ast::Path {
fn user_string(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Ty {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Item {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Lifetime {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Stmt {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Pat {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::BoundRegion {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::Region {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::Region {
fn user_string(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::FreeRegion {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::DefId {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TypeScheme<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::Generics<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::GenericBounds<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::ItemVariances {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::Variance {
fn repr(&self, _: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::Method<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Name {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ast::Name {
fn user_string(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Ident {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::ExplicitSelf_ {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Visibility {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::BareFnTy<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::FnSig<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::FnOutput<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::MethodCallee<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::MethodOrigin<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::MethodParam<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::MethodObject<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TraitStore {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::BuiltinBound {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::BuiltinBound {
fn user_string(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for Span {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx, A: UserString<'tcx>> UserString<'tcx> for Rc<A> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::ParamBounds<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::ExistentialBounds<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::BuiltinBounds {
fn user_string(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx, T> UserString<'tcx> for ty::Binder<T> where
T: UserString<'tcx> + TypeFoldable<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for Ty<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ast::Ident {
fn user_string(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for abi::Abi {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for abi::Abi {
fn user_string(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::UpvarId {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::Mutability {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::BorrowKind {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::UpvarBorrow {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::IntVid {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::FloatVid {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::RegionVid {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TyVid {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::IntVarValue {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::IntTy {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::UintTy {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ast::FloatTy {
fn repr(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::ExplicitSelfCategory {
fn repr(&self, _: &ctxt) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ParamTy {
fn user_string(&self, _tcx: &ctxt) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ParamTy {
fn repr(&self, tcx: &ctxt) -> String { loop { } }
}
impl <'tcx, A: Repr<'tcx>, B: Repr<'tcx>> Repr<'tcx> for (A, B) {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T: Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S> where
K: Hash<<S as HashState>::Hasher> + Eq + Repr<'tcx>, V: Repr<'tcx>,
S: HashState, <S as HashState>::Hasher: Hasher<Output = u64> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T, U> Repr<'tcx> for ty::OutlivesPredicate<T, U> where
T: Repr<'tcx> + TypeFoldable<'tcx>, U: Repr<'tcx> +
TypeFoldable<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx, T, U> UserString<'tcx> for ty::OutlivesPredicate<T, U>
where T: UserString<'tcx> + TypeFoldable<'tcx>, U: UserString<'tcx> +
TypeFoldable<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::EquatePredicate<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::EquatePredicate<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::TraitPredicate<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::TraitPredicate<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::ProjectionPredicate<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> Repr<'tcx> for ty::ProjectionTy<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::ProjectionTy<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
impl <'tcx> UserString<'tcx> for ty::Predicate<'tcx> {
fn user_string(&self, tcx: &ctxt<'tcx>) -> String { loop { } }
}
}
pub mod nodemap {
//! An efficient hash map for node IDs
#![allow(non_snake_case)]
use std::collections::hash_state::{DefaultState};
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::hash::{Hasher, Writer};
use syntax::ast;
pub type FnvHashMap<K, V> = HashMap<K, V, DefaultState<FnvHasher>>;
pub type FnvHashSet<V> = HashSet<V, DefaultState<FnvHasher>>;
pub type NodeMap<T> = FnvHashMap<ast::NodeId, T>;
pub type DefIdMap<T> = FnvHashMap<ast::DefId, T>;
pub type NodeSet = FnvHashSet<ast::NodeId>;
pub type DefIdSet = FnvHashSet<ast::DefId>;
pub mod FnvHashMap {
use std::hash::Hash;
use std::default::Default;
pub fn new<K: Hash<super::FnvHasher> + Eq, V>()
-> super::FnvHashMap<K, V> {
loop { }
}
}
pub mod FnvHashSet {
use std::hash::Hash;
use std::default::Default;
pub fn new<V: Hash<super::FnvHasher> + Eq>()
-> super::FnvHashSet<V> {
loop { }
}
}
pub mod NodeMap {
pub fn new<T>() -> super::NodeMap<T> { loop { } }
}
pub mod DefIdMap {
pub fn new<T>() -> super::DefIdMap<T> { loop { } }
}
pub mod NodeSet {
pub fn new() -> super::NodeSet { loop { } }
}
pub mod DefIdSet {
pub fn new() -> super::DefIdSet { loop { } }
}
/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
/// want. In the compiler we're not really worried about DOS attempts, so we
/// just default to a non-cryptographic hash.
///
/// This uses FNV hashing, as described here:
/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
#[allow(missing_copy_implementations)]
pub struct FnvHasher(u64);
impl Default for FnvHasher {
fn default() -> FnvHasher { loop { } }
}
impl Hasher for FnvHasher {type
Output
=
u64;
fn reset(&mut self) { loop { } }
fn finish(&self) -> u64 { loop { } }
}
impl Writer for FnvHasher {
fn write(&mut self, bytes: &[u8]) { loop { } }
}
}
pub mod snapshot_vec {
//! A utility class for implementing "snapshottable" things; a snapshottable data structure permits
//! you to take a snapshot (via `start_snapshot`) and then, after making some changes, elect either
//! to rollback to the start of the snapshot or commit those changes.
//!
//! This vector is intended to be used as part of an abstraction, not serve as a complete
//! abstraction on its own. As such, while it will roll back most changes on its own, it also
//! supports a `get_mut` operation that gives you an arbitrary mutable pointer into the vector. To
//! ensure that any changes you make this with this pointer are rolled back, you must invoke
//! `record` to record any changes you make and also supplying a delegate capable of reversing
//! those changes.
use self::UndoLog::*;
use std::mem;
#[derive(PartialEq)]
pub enum UndoLog<T, U> {
/// Indicates where a snapshot started.
OpenSnapshot,
/// Indicates a snapshot that has been committed.
CommittedSnapshot,
/// New variable with given index was created.
NewElem(uint),
/// Variable with given index was changed *from* the given value.
SetElem(uint, T),
/// Extensible set of actions
Other(U),
}
pub struct SnapshotVec<T, U, D> {
values: Vec<T>,
undo_log: Vec<UndoLog<T, U>>,
delegate: D,
}
#[allow(missing_copy_implementations)]
pub struct Snapshot {
length: uint,
}
pub trait SnapshotVecDelegate<T, U> {
fn reverse(&mut self, values: &mut Vec<T>, action: U);
}
impl <T, U, D: SnapshotVecDelegate<T, U>> SnapshotVec<T, U, D> {
pub fn new(delegate: D) -> SnapshotVec<T, U, D> { loop { } }
fn in_snapshot(&self) -> bool { loop { } }
pub fn record(&mut self, action: U) { loop { } }
pub fn push(&mut self, elem: T) -> uint { loop { } }
pub fn get<'a>(&'a self, index: uint) -> &'a T { loop { } }
/// Returns a mutable pointer into the vec; whatever changes you make here cannot be undone
/// automatically, so you should be sure call `record()` with some sort of suitable undo
/// action.
pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T {
loop { }
}
/// Updates the element at the given index. The old value will saved (and perhaps restored) if
/// a snapshot is active.
pub fn set(&mut self, index: uint, new_elem: T) { loop { } }
pub fn start_snapshot(&mut self) -> Snapshot { loop { } }
pub fn actions_since_snapshot(&self, snapshot: &Snapshot)
-> &[UndoLog<T, U>] {
loop { }
}
fn assert_open_snapshot(&self, snapshot: &Snapshot) { loop { } }
pub fn rollback_to(&mut self, snapshot: Snapshot) { loop { } }
/// Commits all changes since the last snapshot. Of course, they
/// can still be undone if there is a snapshot further out.
pub fn commit(&mut self, snapshot: Snapshot) { loop { } }
}
}
pub mod lev_distance {
use std::cmp;
pub fn lev_distance(me: &str, t: &str) -> uint { loop { } }
#[test]
fn test_lev_distance() { loop { } }
}
}
pub mod lib {
pub use llvm;
}
__build_diagnostic_array! (DIAGNOSTICS);
#[doc(hidden)]
mod rustc {
pub use lint;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment