The current example does not illustrate threaded behavior imo.
check_lines,
breakpoint_lines
} = parse_debugger_commands(testfile, "gdb");
- let mut cmds = commands.connect("\n");
+ let mut cmds = commands.join("\n");
// compile test file (it should have 'compile-flags:-g' in the header)
let compiler_run_result = compile_test(config, props, testfile);
split_maybe_args(options).into_iter()
.filter(|x| !options_to_remove.contains(x))
.collect::<Vec<String>>()
- .connect(" ");
+ .join(" ");
Some(new_options)
}
// Linux and mac don't require adjusting the library search path
if cfg!(unix) {
- format!("{} {}", prog, args.connect(" "))
+ format!("{} {}", prog, args.join(" "))
} else {
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
// for diagnostic purposes
format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
}
- format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
+ format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.join(" "))
}
}
#[stable(feature = "rust1", since = "1.0.0")]
fn concat(&self) -> Self::Output;
+ /// Flattens a slice of `T` into a single value `Self::Output`, placing a
+ /// given separator between each.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(["hello", "world"].join(" "), "hello world");
+ /// ```
+ #[stable(feature = "rename_connect_to_join", since = "1.3.0")]
+ fn join(&self, sep: &T) -> Self::Output;
+
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
/// given separator between each.
///
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[deprecated(since = "1.3.0", reason = "renamed to join")]
fn connect(&self, sep: &T) -> Self::Output;
}
result
}
- fn connect(&self, sep: &T) -> Vec<T> {
+ fn join(&self, sep: &T) -> Vec<T> {
let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
let mut result = Vec::with_capacity(size + self.len());
let mut first = true;
}
result
}
+
+ fn connect(&self, sep: &T) -> Vec<T> {
+ self.join(sep)
+ }
}
/// An iterator that yields the element swaps needed to produce
result
}
- fn connect(&self, sep: &str) -> String {
+ fn join(&self, sep: &str) -> String {
if self.is_empty() {
return String::new();
}
}
result
}
+
+ fn connect(&self, sep: &str) -> String {
+ self.join(sep)
+ }
}
// Helper functions used for Unicode normalization
assert_eq!(d, [1, 2, 3]);
let v: &[&[_]] = &[&[1], &[2, 3]];
- assert_eq!(v.connect(&0), [1, 0, 2, 3]);
+ assert_eq!(v.join(&0), [1, 0, 2, 3]);
let v: &[&[_]] = &[&[1], &[2], &[3]];
- assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
+ assert_eq!(v.join(&0), [1, 0, 2, 0, 3]);
}
#[test]
-fn test_connect() {
+fn test_join() {
let v: [Vec<i32>; 0] = [];
- assert_eq!(v.connect(&0), []);
- assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]);
- assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]);
+ assert_eq!(v.join(&0), []);
+ assert_eq!([vec![1], vec![2, 3]].join(&0), [1, 0, 2, 3]);
+ assert_eq!([vec![1], vec![2], vec![3]].join(&0), [1, 0, 2, 0, 3]);
let v: [&[_]; 2] = [&[1], &[2, 3]];
- assert_eq!(v.connect(&0), [1, 0, 2, 3]);
+ assert_eq!(v.join(&0), [1, 0, 2, 3]);
let v: [&[_]; 3] = [&[1], &[2], &[3]];
- assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
+ assert_eq!(v.join(&0), [1, 0, 2, 0, 3]);
}
#[test]
}
#[bench]
- fn connect(b: &mut Bencher) {
+ fn join(b: &mut Bencher) {
let xss: Vec<Vec<i32>> =
(0..100).map(|i| (0..i).collect()).collect();
b.iter(|| {
- xss.connect(&0)
+ xss.join(&0)
});
}
test_concat!("abc", ["", "a", "bc"]);
}
-macro_rules! test_connect {
+macro_rules! test_join {
($expected: expr, $string: expr, $delim: expr) => {
{
- let s = $string.connect($delim);
+ let s = $string.join($delim);
assert_eq!($expected, s);
}
}
}
#[test]
-fn test_connect_for_different_types() {
- test_connect!("a-b", ["a", "b"], "-");
+fn test_join_for_different_types() {
+ test_join!("a-b", ["a", "b"], "-");
let hyphen = "-".to_string();
- test_connect!("a-b", [s("a"), s("b")], &*hyphen);
- test_connect!("a-b", vec!["a", "b"], &*hyphen);
- test_connect!("a-b", &*vec!["a", "b"], "-");
- test_connect!("a-b", vec![s("a"), s("b")], "-");
+ test_join!("a-b", [s("a"), s("b")], &*hyphen);
+ test_join!("a-b", vec!["a", "b"], &*hyphen);
+ test_join!("a-b", &*vec!["a", "b"], "-");
+ test_join!("a-b", vec![s("a"), s("b")], "-");
}
#[test]
-fn test_connect_for_different_lengths() {
+fn test_join_for_different_lengths() {
let empty: &[&str] = &[];
- test_connect!("", empty, "-");
- test_connect!("a", ["a"], "-");
- test_connect!("a-b", ["a", "b"], "-");
- test_connect!("-a-bc", ["", "a", "bc"], "-");
+ test_join!("", empty, "-");
+ test_join!("a", ["a"], "-");
+ test_join!("a-b", ["a", "b"], "-");
+ test_join!("-a-bc", ["", "a", "bc"], "-");
}
#[test]
}
#[bench]
- fn bench_connect(b: &mut Bencher) {
+ fn bench_join(b: &mut Bencher) {
let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
let sep = "→";
let v = vec![s, s, s, s, s, s, s, s, s, s];
b.iter(|| {
- assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
+ assert_eq!(v.join(sep).len(), s.len() * 10 + sep.len() * 9);
})
}
}
}
- /// Wrapping (modular) division. Computes `floor(self / other)`,
+ /// Wrapping (modular) division. Computes `self / other`,
/// wrapping around at the boundary of the type.
///
/// The only case where such wrapping can occur is when one
/// negative minimal value for the type); this is equivalent
/// to `-MIN`, a positive value that is too large to represent
/// in the type. In such a case, this function returns `MIN`
- /// itself..
+ /// itself.
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
pub fn wrapping_div(self, rhs: Self) -> Self {
}
}
- /// Wrapping (modular) division. Computes `floor(self / other)`,
+ /// Wrapping (modular) division. Computes `self / other`,
/// wrapping around at the boundary of the type.
///
/// The only case where such wrapping can occur is when one
/// negative minimal value for the type); this is equivalent
/// to `-MIN`, a positive value that is too large to represent
/// in the type. In such a case, this function returns `MIN`
- /// itself..
+ /// itself.
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[inline(always)]
pub fn wrapping_div(self, rhs: Self) -> Self {
fn div(self, rhs: RHS) -> Self::Output;
}
-macro_rules! div_impl {
+macro_rules! div_impl_integer {
($($t:ty)*) => ($(
+ /// This operation rounds towards zero, truncating any
+ /// fractional part of the exact result.
#[stable(feature = "rust1", since = "1.0.0")]
impl Div for $t {
type Output = $t;
)*)
}
-div_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
+div_impl_integer! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
+
+macro_rules! div_impl_float {
+ ($($t:ty)*) => ($(
+ #[stable(feature = "rust1", since = "1.0.0")]
+ impl Div for $t {
+ type Output = $t;
+
+ #[inline]
+ fn div(self, other: $t) -> $t { self / other }
+ }
+
+ forward_ref_binop! { impl Div, div for $t, $t }
+ )*)
+}
+
+div_impl_float! { f32 f64 }
/// The `Rem` trait is used to specify the functionality of `%`.
///
macro_rules! rem_impl {
($($t:ty)*) => ($(
+ /// This operation satisfies `n % d == n - (n / d) * d`. The
+ /// result has the same sign as the left operand.
#[stable(feature = "rust1", since = "1.0.0")]
impl Rem for $t {
type Output = $t;
// FIXME: #5516 should be graphemes not codepoints
// wrapped description
- row.push_str(&desc_rows.connect(&desc_sep[..]));
+ row.push_str(&desc_rows.join(&desc_sep[..]));
row
});
format!("{}\n\nOptions:\n{}\n", brief,
- rows.collect::<Vec<String>>().connect("\n"))
+ rows.collect::<Vec<String>>().join("\n"))
}
fn format_option(opt: &OptGroup) -> String {
line.push_str(&opts.iter()
.map(format_option)
.collect::<Vec<String>>()
- .connect(" ")[..]);
+ .join(" ")[..]);
line
}
pub fn get_struct_fields(cstore: &cstore::CStore,
def: ast::DefId)
- -> Vec<ty::field_ty> {
+ -> Vec<ty::FieldTy> {
let cdata = cstore.get_crate_data(def.krate);
decoder::get_struct_fields(cstore.intr.clone(), &*cdata, def.node)
}
}
pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId)
- -> Vec<ty::field_ty> {
+ -> Vec<ty::FieldTy> {
let data = cdata.data();
let item = lookup_item(id, data);
reader::tagged_docs(item, tag_item_field).filter_map(|an_item| {
let did = item_def_id(an_item, cdata);
let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
let origin_id = translated_def_id(cdata, tagdoc);
- Some(ty::field_ty {
+ Some(ty::FieldTy {
name: name,
id: did,
vis: struct_field_family_to_visibility(f),
let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
let f = item_family(an_item);
let origin_id = translated_def_id(cdata, tagdoc);
- ty::field_ty {
+ ty::FieldTy {
name: special_idents::unnamed_field.name,
id: did,
vis: struct_field_family_to_visibility(f),
}
fn encode_struct_fields(rbml_w: &mut Encoder,
- fields: &[ty::field_ty],
+ fields: &[ty::FieldTy],
origin: DefId) {
for f in fields {
if f.name == special_idents::unnamed_field.name {
/* Returns an index of items in this class */
fn encode_info_for_struct(ecx: &EncodeContext,
rbml_w: &mut Encoder,
- fields: &[ty::field_ty],
+ fields: &[ty::FieldTy],
global_index: &mut Vec<entry<i64>>)
-> Vec<entry<i64>> {
/* Each class has its own index, since different classes
cstore::RequireStatic => "s",
})).to_string())
}).collect::<Vec<String>>();
- rbml_w.wr_tagged_str(tag, &s.connect(","));
+ rbml_w.wr_tagged_str(tag, &s.join(","));
}
None => {
rbml_w.wr_tagged_str(tag, "");
assert_eq!(next(st), ':');
let len = parse_hex(st);
assert_eq!(next(st), '#');
- let key = ty::creader_cache_key {cnum: st.krate,
+ let key = ty::CReaderCacheKey {cnum: st.krate,
pos: pos,
len: len };
}
}
-fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::mt<'tcx> where
+fn parse_mt_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> ty::TypeAndMut<'tcx> where
F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
let m = parse_mutability(st);
- ty::mt { ty: parse_ty_(st, conv), mutbl: m }
+ ty::TypeAndMut { ty: parse_ty_(st, conv), mutbl: m }
}
fn parse_def_<F>(st: &mut PState, source: DefIdSource, conv: &mut F) -> ast::DefId where
}
fn enc_mt<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
- mt: ty::mt<'tcx>) {
+ mt: ty::TypeAndMut<'tcx>) {
enc_mutability(w, mt.mutbl);
enc_ty(w, cx, mt.ty);
}
/// Function Pointers
FnPtr,
/// Raw pointers
- Ptr(&'tcx ty::mt<'tcx>),
+ Ptr(&'tcx ty::TypeAndMut<'tcx>),
/// References
- RPtr(&'tcx ty::mt<'tcx>),
+ RPtr(&'tcx ty::TypeAndMut<'tcx>),
}
/// Cast Kind. See RFC 401 (or librustc_typeck/check/cast.rs)
}
}
- ty::TyRef(_, ty::mt { ty, mutbl }) => {
+ ty::TyRef(_, ty::TypeAndMut { ty, mutbl }) => {
match ty.sty {
ty::TyArray(_, n) => match ctor {
&Single => {
ty::TyBool =>
[true, false].iter().map(|b| ConstantValue(ConstVal::Bool(*b))).collect(),
- ty::TyRef(_, ty::mt { ty, .. }) => match ty.sty {
+ ty::TyRef(_, ty::TypeAndMut { ty, .. }) => match ty.sty {
ty::TySlice(_) =>
range_inclusive(0, max_slice_length).map(|length| Slice(length)).collect(),
_ => vec!(Single)
match ty.sty {
ty::TyTuple(ref fs) => fs.len(),
ty::TyBox(_) => 1,
- ty::TyRef(_, ty::mt { ty, .. }) => match ty.sty {
+ ty::TyRef(_, ty::TypeAndMut { ty, .. }) => match ty.sty {
ty::TySlice(_) => match *ctor {
Slice(length) => length,
ConstantValue(_) => 0,
// are properly handled.
self.walk_expr(with_expr);
- fn contains_field_named(field: &ty::field,
+ fn contains_field_named(field: &ty::Field,
fields: &Vec<ast::Field>)
-> bool
{
}
ty::TyBox(_) => {
// treat like we would treat `Box`
- let def_id = tcx.lang_items.owned_box().unwrap();
- Some(StructSimplifiedType(def_id))
+ match tcx.lang_items.require_owned_box() {
+ Ok(def_id) => Some(StructSimplifiedType(def_id)),
+ Err(msg) => tcx.sess.fatal(&msg),
+ }
}
ty::TyClosure(def_id, _) => {
Some(ClosureSimplifiedType(def_id))
ty::TyArray(t, _) |
ty::TySlice(t) |
- ty::TyRawPtr(ty::mt { ty: t, .. }) |
+ ty::TyRawPtr(ty::TypeAndMut { ty: t, .. }) |
ty::TyBox(t) => {
self.accumulate_from_ty(t)
}
use middle::ty::{TyVar};
use middle::ty::{IntType, UintType};
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, TypeError};
use middle::ty_fold;
use middle::ty_fold::{TypeFolder, TypeFoldable};
use middle::ty_relate::{self, Relate, RelateResult, TypeRelation};
// All other cases of inference are errors
(&ty::TyInfer(_), _) |
(_, &ty::TyInfer(_)) => {
- Err(ty::terr_sorts(ty_relate::expected_found(relation, &a, &b)))
+ Err(TypeError::Sorts(ty_relate::expected_found(relation, &a, &b)))
}
};
let u = ty.fold_with(&mut generalize);
if generalize.cycle_detected {
- Err(ty::terr_cyclic_ty)
+ Err(TypeError::CyclicTy)
} else {
Ok(u)
}
pub trait RelateResultCompare<'tcx, T> {
fn compare<F>(&self, t: T, f: F) -> RelateResult<'tcx, T> where
- F: FnOnce() -> ty::type_err<'tcx>;
+ F: FnOnce() -> ty::TypeError<'tcx>;
}
impl<'tcx, T:Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'tcx, T> {
fn compare<F>(&self, t: T, f: F) -> RelateResult<'tcx, T> where
- F: FnOnce() -> ty::type_err<'tcx>,
+ F: FnOnce() -> ty::TypeError<'tcx>,
{
self.clone().and_then(|s| {
if s == t {
}
fn int_unification_error<'tcx>(a_is_expected: bool, v: (ty::IntVarValue, ty::IntVarValue))
- -> ty::type_err<'tcx>
+ -> ty::TypeError<'tcx>
{
let (a, b) = v;
- ty::terr_int_mismatch(ty_relate::expected_found_bool(a_is_expected, &a, &b))
+ TypeError::IntMismatch(ty_relate::expected_found_bool(a_is_expected, &a, &b))
}
fn float_unification_error<'tcx>(a_is_expected: bool,
v: (ast::FloatTy, ast::FloatTy))
- -> ty::type_err<'tcx>
+ -> ty::TypeError<'tcx>
{
let (a, b) = v;
- ty::terr_float_mismatch(ty_relate::expected_found_bool(a_is_expected, &a, &b))
+ TypeError::FloatMismatch(ty_relate::expected_found_bool(a_is_expected, &a, &b))
}
use middle::infer;
use middle::region;
use middle::subst;
-use middle::ty::{self, Ty, HasTypeFlags};
+use middle::ty::{self, Ty, TypeError, HasTypeFlags};
use middle::ty::{Region, ReFree};
use std::cell::{Cell, RefCell};
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_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::TypeError<'tcx>);
fn report_and_explain_type_error(&self,
trace: TypeTrace<'tcx>,
- terr: &ty::type_err<'tcx>);
+ terr: &ty::TypeError<'tcx>);
fn values_str(&self, values: &ValuePairs<'tcx>) -> Option<String>;
fn expected_found_str<T: fmt::Display + Resolvable<'tcx> + HasTypeFlags>(
&self,
- exp_found: &ty::expected_found<T>)
+ exp_found: &ty::ExpectedFound<T>)
-> Option<String>;
fn report_concrete_failure(&self,
fn report_processed_errors(&self,
var_origin: &[RegionVariableOrigin],
- trace_origin: &[(TypeTrace<'tcx>, ty::type_err<'tcx>)],
+ trace_origin: &[(TypeTrace<'tcx>, ty::TypeError<'tcx>)],
same_regions: &[SameRegions]);
fn give_suggestion(&self, same_regions: &[SameRegions]);
match free_regions_from_same_fn(self.tcx, sub, sup) {
Some(ref same_frs) if trace.is_some() => {
let trace = trace.unwrap();
- let terr = ty::terr_regions_does_not_outlive(sup,
- sub);
+ let terr = TypeError::RegionsDoesNotOutlive(sup,
+ sub);
trace_origins.push((trace, terr));
append_to_same_regions(&mut same_regions, same_frs);
}
}
}
- fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::type_err<'tcx>) {
+ fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::TypeError<'tcx>) {
let expected_found_str = match self.values_str(&trace.values) {
Some(v) => v,
None => {
fn report_and_explain_type_error(&self,
trace: TypeTrace<'tcx>,
- terr: &ty::type_err<'tcx>) {
+ terr: &ty::TypeError<'tcx>) {
let span = trace.origin.span();
self.report_type_error(trace, terr);
self.tcx.note_and_explain_type_err(terr, span);
fn expected_found_str<T: fmt::Display + Resolvable<'tcx> + HasTypeFlags>(
&self,
- exp_found: &ty::expected_found<T>)
+ exp_found: &ty::ExpectedFound<T>)
-> Option<String>
{
let expected = exp_found.expected.resolve(self);
match origin {
infer::Subtype(trace) |
infer::DefaultExistentialBound(trace) => {
- let terr = ty::terr_regions_does_not_outlive(sup, sub);
+ let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
self.report_and_explain_type_error(trace, &terr);
}
infer::Reborrow(span) => {
fn report_processed_errors(&self,
var_origins: &[RegionVariableOrigin],
- trace_origins: &[(TypeTrace<'tcx>, ty::type_err<'tcx>)],
+ trace_origins: &[(TypeTrace<'tcx>, ty::TypeError<'tcx>)],
same_regions: &[SameRegions]) {
for vo in var_origins {
self.report_inference_failure(vo.clone());
use super::combine::CombineFields;
use middle::subst;
-use middle::ty::{self, Binder};
+use middle::ty::{self, TypeError, Binder};
use middle::ty_fold::{self, TypeFoldable};
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
use syntax::codemap::Span;
Err((skol_br, tainted_region)) => {
if self.a_is_expected {
debug!("Not as polymorphic!");
- return Err(ty::terr_regions_insufficiently_polymorphic(skol_br,
+ return Err(TypeError::RegionsInsufficientlyPolymorphic(skol_br,
tainted_region));
} else {
debug!("Overly polymorphic!");
- return Err(ty::terr_regions_overly_polymorphic(skol_br,
+ return Err(TypeError::RegionsOverlyPolymorphic(skol_br,
tainted_region));
}
}
//! See the Book for more information.
-#![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::traits::{self, FulfillmentContext, Normalized,
SelectionContext, ObligationCause};
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
-use middle::ty::{self, Ty, HasTypeFlags};
+use middle::ty::{self, Ty, TypeError, HasTypeFlags};
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
use rustc_data_structures::unify::{self, UnificationTable};
pub type Bound<T> = Option<T>;
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
-pub type fres<T> = Result<T, fixup_err>; // "fixup result"
+pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
pub struct InferCtxt<'a, 'tcx: 'a> {
pub tcx: &'a ty::ctxt<'tcx>,
/// See `error_reporting.rs` for more details
#[derive(Clone, Debug)]
pub enum ValuePairs<'tcx> {
- Types(ty::expected_found<Ty<'tcx>>),
- TraitRefs(ty::expected_found<ty::TraitRef<'tcx>>),
- PolyTraitRefs(ty::expected_found<ty::PolyTraitRef<'tcx>>),
+ Types(ty::ExpectedFound<Ty<'tcx>>),
+ TraitRefs(ty::ExpectedFound<ty::TraitRef<'tcx>>),
+ PolyTraitRefs(ty::ExpectedFound<ty::PolyTraitRef<'tcx>>),
}
/// The trace designates the path through inference that we took to
}
#[derive(Copy, Clone, Debug)]
-pub enum fixup_err {
- unresolved_int_ty(IntVid),
- unresolved_float_ty(FloatVid),
- unresolved_ty(TyVid)
+pub enum FixupError {
+ UnresolvedIntTy(IntVid),
+ UnresolvedFloatTy(FloatVid),
+ UnresolvedTy(TyVid)
}
-pub fn fixup_err_to_string(f: fixup_err) -> String {
+pub fn fixup_err_to_string(f: FixupError) -> String {
+ use self::FixupError::*;
+
match f {
- unresolved_int_ty(_) => {
+ UnresolvedIntTy(_) => {
"cannot determine the type of this integer; add a suffix to \
specify the type explicitly".to_string()
}
- unresolved_float_ty(_) => {
+ UnresolvedFloatTy(_) => {
"cannot determine the type of this number; add a suffix to specify \
the type explicitly".to_string()
}
- unresolved_ty(_) => "unconstrained type".to_string(),
+ UnresolvedTy(_) => "unconstrained type".to_string(),
}
}
fn expected_found<T>(a_is_expected: bool,
a: T,
b: T)
- -> ty::expected_found<T>
+ -> ty::ExpectedFound<T>
{
if a_is_expected {
- ty::expected_found {expected: a, found: b}
+ ty::ExpectedFound {expected: a, found: b}
} else {
- ty::expected_found {expected: b, found: a}
+ ty::ExpectedFound {expected: b, found: a}
}
}
match higher_ranked::leak_check(self, skol_map, snapshot) {
Ok(()) => Ok(()),
- Err((br, r)) => Err(ty::terr_regions_insufficiently_polymorphic(br, r))
+ Err((br, r)) => Err(TypeError::RegionsInsufficientlyPolymorphic(br, r))
}
}
pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
- format!("({})", tstrs.connect(", "))
+ format!("({})", tstrs.join(", "))
}
pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) }
}
- pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> fres<T> {
+ pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> FixupResult<T> {
/*!
* Attempts to resolve all type/region variables in
* `value`. Region inference must have been run already (e.g.,
sp: Span,
mk_msg: M,
actual_ty: String,
- err: Option<&ty::type_err<'tcx>>) where
+ err: Option<&ty::TypeError<'tcx>>) where
M: FnOnce(Option<String>, String) -> String,
{
self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
mk_msg: M,
expected_ty: Option<Ty<'tcx>>,
actual_ty: String,
- err: Option<&ty::type_err<'tcx>>) where
+ err: Option<&ty::TypeError<'tcx>>) where
M: FnOnce(Option<String>, String) -> String,
{
debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
sp: Span,
mk_msg: M,
actual_ty: Ty<'tcx>,
- err: Option<&ty::type_err<'tcx>>) where
+ err: Option<&ty::TypeError<'tcx>>) where
M: FnOnce(String) -> String,
{
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
span: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
- err: &ty::type_err<'tcx>) {
+ err: &ty::TypeError<'tcx>) {
let trace = TypeTrace {
origin: Misc(span),
- values: Types(ty::expected_found {
+ values: Types(ty::ExpectedFound {
expected: expected,
found: actual
})
pub fn dummy(tcx: &ty::ctxt<'tcx>) -> TypeTrace<'tcx> {
TypeTrace {
origin: Misc(codemap::DUMMY_SP),
- values: Types(ty::expected_found {
+ values: Types(ty::ExpectedFound {
expected: tcx.types.err,
found: tcx.types.err,
})
use rustc_data_structures::graph::{self, Direction, NodeIndex};
use middle::free_region::FreeRegionMap;
use middle::region;
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, TypeError};
use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
/// should put a lifetime. In those cases we process and put those errors
/// into `ProcessedErrors` before we do any reporting.
ProcessedErrors(Vec<RegionVariableOrigin>,
- Vec<(TypeTrace<'tcx>, ty::type_err<'tcx>)>,
+ Vec<(TypeTrace<'tcx>, ty::TypeError<'tcx>)>,
Vec<SameRegions>),
}
if self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id) == fr_scope {
Ok(s)
} else {
- Err(ty::terr_regions_no_overlap(b, a))
+ Err(TypeError::RegionsNoOverlap(b, a))
}
}
if a == b {
Ok(a)
} else {
- Err(ty::terr_regions_no_overlap(b, a))
+ Err(TypeError::RegionsNoOverlap(b, a))
}
}
}
} else if r_id == scope_b {
Ok(ReScope(scope_a))
} else {
- Err(ty::terr_regions_no_overlap(region_a, region_b))
+ Err(TypeError::RegionsNoOverlap(region_a, region_b))
}
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use super::{InferCtxt, fixup_err, fres, unresolved_ty, unresolved_int_ty, unresolved_float_ty};
+use super::{InferCtxt, FixupError, FixupResult};
use middle::ty::{self, Ty, HasTypeFlags};
use middle::ty_fold::{self, TypeFoldable};
/// 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>
+pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a,'tcx>, value: &T) -> FixupResult<T>
where T : TypeFoldable<'tcx>
{
let mut full_resolver = FullTypeResolver { infcx: infcx, err: None };
// `err` field is not enforcable otherwise.
struct FullTypeResolver<'a, 'tcx:'a> {
infcx: &'a InferCtxt<'a, 'tcx>,
- err: Option<fixup_err>,
+ err: Option<FixupError>,
}
impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
let t = self.infcx.shallow_resolve(t);
match t.sty {
ty::TyInfer(ty::TyVar(vid)) => {
- self.err = Some(unresolved_ty(vid));
+ self.err = Some(FixupError::UnresolvedTy(vid));
self.tcx().types.err
}
ty::TyInfer(ty::IntVar(vid)) => {
- self.err = Some(unresolved_int_ty(vid));
+ self.err = Some(FixupError::UnresolvedIntTy(vid));
self.tcx().types.err
}
ty::TyInfer(ty::FloatVar(vid)) => {
- self.err = Some(unresolved_float_ty(vid));
+ self.err = Some(FixupError::UnresolvedFloatTy(vid));
self.tcx().types.err
}
ty::TyInfer(_) => {
}
}
+ pub fn require_owned_box(&self) -> Result<ast::DefId, String> {
+ self.require(OwnedBoxLangItem)
+ }
+
pub fn from_builtin_kind(&self, bound: ty::BuiltinBound)
-> Result<ast::DefId, String>
{
fn element_kind(t: Ty) -> ElementKind {
match t.sty {
- ty::TyRef(_, ty::mt{ty, ..}) |
+ ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
ty::TyBox(ty) => match ty.sty {
ty::TySlice(_) => VecElement,
_ => OtherElement
Unimplemented,
OutputTypeParameterMismatch(ty::PolyTraitRef<'tcx>,
ty::PolyTraitRef<'tcx>,
- ty::type_err<'tcx>),
+ ty::TypeError<'tcx>),
TraitNotObjectSafe(ast::DefId),
}
#[derive(Clone)]
pub struct MismatchedProjectionTypes<'tcx> {
- pub err: ty::type_err<'tcx>
+ pub err: ty::TypeError<'tcx>
}
#[derive(PartialEq, Eq, Debug)]
}
}
- ty::TyRef(_, ty::mt { ty: _, mutbl }) => {
+ ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl }) => {
// &mut T or &T
match bound {
ty::BoundCopy => {
Some(vec![referent_ty])
}
- ty::TyRawPtr(ty::mt { ty: element_ty, ..}) |
- ty::TyRef(_, ty::mt { ty: element_ty, ..}) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) |
+ ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => {
Some(vec![element_ty])
},
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// FIXME: (@jroesch) @eddyb should remove this when he renames ctxt
#![allow(non_camel_case_types)]
-pub use self::terr_vstore_kind::*;
-pub use self::type_err::*;
pub use self::InferTy::*;
pub use self::InferRegion::*;
pub use self::ImplOrTraitItemId::*;
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct field<'tcx> {
+pub struct Field<'tcx> {
pub name: ast::Name,
- pub mt: mt<'tcx>
+ pub mt: TypeAndMut<'tcx>
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub struct mt<'tcx> {
+pub struct TypeAndMut<'tcx> {
pub ty: Ty<'tcx>,
pub mutbl: ast::Mutability,
}
#[derive(Clone, Copy, Debug)]
-pub struct field_ty {
+pub struct FieldTy {
pub name: Name,
pub id: DefId,
pub vis: ast::Visibility,
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct creader_cache_key {
+pub struct CReaderCacheKey {
pub cnum: CrateNum,
pub pos: usize,
pub len: usize
pub map: ast_map::Map<'tcx>,
pub freevars: RefCell<FreevarMap>,
pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
- pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
+ pub rcache: RefCell<FnvHashMap<CReaderCacheKey, Ty<'tcx>>>,
pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'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>>>>,
+ pub struct_fields: RefCell<DefIdMap<Rc<Vec<FieldTy>>>>,
/// Maps from def-id of a type or region parameter to its
/// (inferred) variance.
TySlice(Ty<'tcx>),
/// A raw pointer. Written as `*mut T` or `*const T`
- TyRawPtr(mt<'tcx>),
+ TyRawPtr(TypeAndMut<'tcx>),
/// A reference; a pointer with an associated lifetime. Written as
/// `&a mut T` or `&'a T`.
- TyRef(&'tcx Region, mt<'tcx>),
+ TyRef(&'tcx Region, TypeAndMut<'tcx>),
/// If the def-id is Some(_), then this is the type of a specific
/// fn item. Otherwise, if None(_), it a fn pointer type.
}
#[derive(Clone, Copy, Debug)]
-pub enum terr_vstore_kind {
- terr_vec,
- terr_str,
- terr_fn,
- terr_trait
-}
-
-#[derive(Clone, Copy, Debug)]
-pub struct expected_found<T> {
+pub struct ExpectedFound<T> {
pub expected: T,
pub found: T
}
// Data structures used in type unification
#[derive(Clone, Copy, Debug)]
-pub enum type_err<'tcx> {
- terr_mismatch,
- terr_unsafety_mismatch(expected_found<ast::Unsafety>),
- terr_abi_mismatch(expected_found<abi::Abi>),
- terr_mutability,
- terr_box_mutability,
- terr_ptr_mutability,
- terr_ref_mutability,
- terr_vec_mutability,
- terr_tuple_size(expected_found<usize>),
- terr_fixed_array_size(expected_found<usize>),
- terr_ty_param_size(expected_found<usize>),
- 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_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<usize>),
+pub enum TypeError<'tcx> {
+ Mismatch,
+ UnsafetyMismatch(ExpectedFound<ast::Unsafety>),
+ AbiMismatch(ExpectedFound<abi::Abi>),
+ Mutability,
+ BoxMutability,
+ PtrMutability,
+ RefMutability,
+ VecMutability,
+ TupleSize(ExpectedFound<usize>),
+ FixedArraySize(ExpectedFound<usize>),
+ TyParamSize(ExpectedFound<usize>),
+ ArgCount,
+ RegionsDoesNotOutlive(Region, Region),
+ RegionsNotSame(Region, Region),
+ RegionsNoOverlap(Region, Region),
+ RegionsInsufficientlyPolymorphic(BoundRegion, Region),
+ RegionsOverlyPolymorphic(BoundRegion, Region),
+ Sorts(ExpectedFound<Ty<'tcx>>),
+ IntegerAsChar,
+ IntMismatch(ExpectedFound<IntVarValue>),
+ FloatMismatch(ExpectedFound<ast::FloatTy>),
+ Traits(ExpectedFound<ast::DefId>),
+ BuiltinBoundsMismatch(ExpectedFound<BuiltinBounds>),
+ VariadicMismatch(ExpectedFound<bool>),
+ CyclicTy,
+ ConvergenceMismatch(ExpectedFound<bool>),
+ ProjectionNameMismatched(ExpectedFound<ast::Name>),
+ ProjectionBoundsLength(ExpectedFound<usize>),
}
/// Bounds suitable for an existentially quantified type parameter
self.mk_ty(TyBox(ty))
}
- pub fn mk_ptr(&self, tm: mt<'tcx>) -> Ty<'tcx> {
+ pub fn mk_ptr(&self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyRawPtr(tm))
}
- pub fn mk_ref(&self, r: &'tcx Region, tm: mt<'tcx>) -> Ty<'tcx> {
+ pub fn mk_ref(&self, r: &'tcx Region, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyRef(r, tm))
}
pub fn mk_mut_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
- self.mk_ref(r, mt {ty: ty, mutbl: ast::MutMutable})
+ self.mk_ref(r, TypeAndMut {ty: ty, mutbl: ast::MutMutable})
}
pub fn mk_imm_ref(&self, r: &'tcx Region, ty: Ty<'tcx>) -> Ty<'tcx> {
- self.mk_ref(r, mt {ty: ty, mutbl: ast::MutImmutable})
+ self.mk_ref(r, TypeAndMut {ty: ty, mutbl: ast::MutImmutable})
}
pub fn mk_mut_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
- self.mk_ptr(mt {ty: ty, mutbl: ast::MutMutable})
+ self.mk_ptr(TypeAndMut {ty: ty, mutbl: ast::MutMutable})
}
pub fn mk_imm_ptr(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
- self.mk_ptr(mt {ty: ty, mutbl: ast::MutImmutable})
+ self.mk_ptr(TypeAndMut {ty: ty, mutbl: ast::MutImmutable})
}
pub fn mk_nil_ptr(&self) -> Ty<'tcx> {
}
fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
- mt: mt<'tcx>,
+ mt: TypeAndMut<'tcx>,
cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
{
let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
// Fast-path for primitive types
let result = match self.sty {
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
- TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt {
+ TyRawPtr(..) | TyBareFn(..) | TyRef(_, TypeAndMut {
mutbl: ast::MutImmutable, ..
}) => Some(false),
- TyStr | TyBox(..) | TyRef(_, mt {
+ TyStr | TyBox(..) | TyRef(_, TypeAndMut {
mutbl: ast::MutMutable, ..
}) => Some(true),
//
// The parameter `explicit` indicates if this is an *explicit* dereference.
// Some types---notably unsafe ptrs---can only be dereferenced explicitly.
- pub fn builtin_deref(&self, explicit: bool) -> Option<mt<'tcx>> {
+ pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
match self.sty {
TyBox(ty) => {
- Some(mt {
+ Some(TypeAndMut {
ty: ty,
mutbl: ast::MutImmutable,
})
match autoref {
None => self,
Some(AutoPtr(r, m)) => {
- cx.mk_ref(r, mt { ty: self, mutbl: m })
+ cx.mk_ref(r, TypeAndMut { ty: self, mutbl: m })
}
Some(AutoUnsafe(m)) => {
- cx.mk_ptr(mt { ty: self, mutbl: m })
+ cx.mk_ptr(TypeAndMut { ty: self, mutbl: m })
}
}
}
fn sort_string(&self, cx: &ctxt) -> String {
+
match self.sty {
TyBool | TyChar | TyInt(_) |
TyUint(_) | TyFloat(_) | TyStr => self.to_string(),
/// 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.
-impl<'tcx> fmt::Display for type_err<'tcx> {
+impl<'tcx> fmt::Display for TypeError<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use self::TypeError::*;
+
match *self {
- terr_cyclic_ty => write!(f, "cyclic type of infinite size"),
- terr_mismatch => write!(f, "types differ"),
- terr_unsafety_mismatch(values) => {
+ CyclicTy => write!(f, "cyclic type of infinite size"),
+ Mismatch => write!(f, "types differ"),
+ UnsafetyMismatch(values) => {
write!(f, "expected {} fn, found {} fn",
values.expected,
values.found)
}
- terr_abi_mismatch(values) => {
+ AbiMismatch(values) => {
write!(f, "expected {} fn, found {} fn",
values.expected,
values.found)
}
- terr_mutability => write!(f, "values differ in mutability"),
- terr_box_mutability => {
+ Mutability => write!(f, "values differ in mutability"),
+ BoxMutability => {
write!(f, "boxed values differ in mutability")
}
- terr_vec_mutability => write!(f, "vectors differ in mutability"),
- terr_ptr_mutability => write!(f, "pointers differ in mutability"),
- terr_ref_mutability => write!(f, "references differ in mutability"),
- terr_ty_param_size(values) => {
+ VecMutability => write!(f, "vectors differ in mutability"),
+ PtrMutability => write!(f, "pointers differ in mutability"),
+ RefMutability => write!(f, "references differ in mutability"),
+ TyParamSize(values) => {
write!(f, "expected a type with {} type params, \
found one with {} type params",
values.expected,
values.found)
}
- terr_fixed_array_size(values) => {
+ FixedArraySize(values) => {
write!(f, "expected an array with a fixed size of {} elements, \
found one with {} elements",
values.expected,
values.found)
}
- terr_tuple_size(values) => {
+ TupleSize(values) => {
write!(f, "expected a tuple with {} elements, \
found one with {} elements",
values.expected,
values.found)
}
- terr_arg_count => {
+ ArgCount => {
write!(f, "incorrect number of function parameters")
}
- terr_regions_does_not_outlive(..) => {
+ RegionsDoesNotOutlive(..) => {
write!(f, "lifetime mismatch")
}
- terr_regions_not_same(..) => {
+ RegionsNotSame(..) => {
write!(f, "lifetimes are not the same")
}
- terr_regions_no_overlap(..) => {
+ RegionsNoOverlap(..) => {
write!(f, "lifetimes do not intersect")
}
- terr_regions_insufficiently_polymorphic(br, _) => {
+ RegionsInsufficientlyPolymorphic(br, _) => {
write!(f, "expected bound lifetime parameter {}, \
found concrete lifetime", br)
}
- terr_regions_overly_polymorphic(br, _) => {
+ RegionsOverlyPolymorphic(br, _) => {
write!(f, "expected concrete lifetime, \
found bound lifetime parameter {}", br)
}
- terr_sorts(values) => tls::with(|tcx| {
+ Sorts(values) => tls::with(|tcx| {
// A naive approach to making sure that we're not reporting silly errors such as:
// (expected closure, found closure).
let expected_str = values.expected.sort_string(tcx);
write!(f, "expected {}, found {}", expected_str, found_str)
}
}),
- terr_traits(values) => tls::with(|tcx| {
+ Traits(values) => tls::with(|tcx| {
write!(f, "expected trait `{}`, found trait `{}`",
tcx.item_path_str(values.expected),
tcx.item_path_str(values.found))
}),
- terr_builtin_bounds(values) => {
+ BuiltinBoundsMismatch(values) => {
if values.expected.is_empty() {
write!(f, "expected no bounds, found `{}`",
values.found)
values.found)
}
}
- terr_integer_as_char => {
+ IntegerAsChar => {
write!(f, "expected an integral type, found `char`")
}
- terr_int_mismatch(ref values) => {
+ IntMismatch(ref values) => {
write!(f, "expected `{:?}`, found `{:?}`",
values.expected,
values.found)
}
- terr_float_mismatch(ref values) => {
+ FloatMismatch(ref values) => {
write!(f, "expected `{:?}`, found `{:?}`",
values.expected,
values.found)
}
- terr_variadic_mismatch(ref values) => {
+ VariadicMismatch(ref values) => {
write!(f, "expected {} fn, found {} function",
if values.expected { "variadic" } else { "non-variadic" },
if values.found { "variadic" } else { "non-variadic" })
}
- terr_convergence_mismatch(ref values) => {
+ ConvergenceMismatch(ref values) => {
write!(f, "expected {} fn, found {} function",
if values.expected { "converging" } else { "diverging" },
if values.found { "converging" } else { "diverging" })
}
- terr_projection_name_mismatched(ref values) => {
+ ProjectionNameMismatched(ref values) => {
write!(f, "expected {}, found {}",
values.expected,
values.found)
}
- terr_projection_bounds_length(ref values) => {
+ ProjectionBoundsLength(ref values) => {
write!(f, "expected {} associated type bindings, found {}",
values.expected,
values.found)
}
}
- pub fn field_idx_strict(&self, name: ast::Name, fields: &[field])
+ pub fn field_idx_strict(&self, name: ast::Name, fields: &[Field<'tcx>])
-> usize {
let mut i = 0;
for f in fields { if f.name == name { return i; } i += 1; }
.collect::<Vec<String>>()));
}
- pub fn note_and_explain_type_err(&self, err: &type_err<'tcx>, sp: Span) {
+ pub fn note_and_explain_type_err(&self, err: &TypeError<'tcx>, sp: Span) {
+ use self::TypeError::*;
+
match *err {
- terr_regions_does_not_outlive(subregion, superregion) => {
+ RegionsDoesNotOutlive(subregion, superregion) => {
self.note_and_explain_region("", subregion, "...");
self.note_and_explain_region("...does not necessarily outlive ",
superregion, "");
}
- terr_regions_not_same(region1, region2) => {
+ RegionsNotSame(region1, region2) => {
self.note_and_explain_region("", region1, "...");
self.note_and_explain_region("...is not the same lifetime as ",
region2, "");
}
- terr_regions_no_overlap(region1, region2) => {
+ RegionsNoOverlap(region1, region2) => {
self.note_and_explain_region("", region1, "...");
self.note_and_explain_region("...does not overlap ",
region2, "");
}
- terr_regions_insufficiently_polymorphic(_, conc_region) => {
+ RegionsInsufficientlyPolymorphic(_, conc_region) => {
self.note_and_explain_region("concrete lifetime that was found is ",
conc_region, "");
}
- terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
+ RegionsOverlyPolymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
// don't bother to print out the message below for
// inference variables, it's not very illuminating.
}
- terr_regions_overly_polymorphic(_, conc_region) => {
+ RegionsOverlyPolymorphic(_, conc_region) => {
self.note_and_explain_region("expected concrete lifetime is ",
conc_region, "");
}
- terr_sorts(values) => {
+ Sorts(values) => {
let expected_str = values.expected.sort_string(self);
let found_str = values.found.sort_string(self);
if expected_str == found_str && expected_str == "closure" {
// Look up the list of field names and IDs for a given struct.
// Panics if the id is not bound to a struct.
- pub fn lookup_struct_fields(&self, did: ast::DefId) -> Vec<field_ty> {
+ pub fn lookup_struct_fields(&self, did: ast::DefId) -> Vec<FieldTy> {
if did.krate == ast::LOCAL_CRATE {
let struct_fields = self.struct_fields.borrow();
match struct_fields.get(&did) {
// Returns a list of fields corresponding to the struct's items. trans uses
// this. Takes a list of substs with which to instantiate field types.
pub fn struct_fields(&self, did: ast::DefId, substs: &Substs<'tcx>)
- -> Vec<field<'tcx>> {
+ -> Vec<Field<'tcx>> {
self.lookup_struct_fields(did).iter().map(|f| {
- field {
+ Field {
name: f.name,
- mt: mt {
+ mt: TypeAndMut {
ty: self.lookup_field_type(did, f.id, substs),
mutbl: MutImmutable
}
}
UpvarCapture::ByRef(borrow) => {
tcx.mk_ref(tcx.mk_region(borrow.region),
- ty::mt {
+ ty::TypeAndMut {
ty: freevar_ty,
mutbl: borrow.kind.to_mutbl_lossy(),
})
h.as_str().hash(state);
did.node.hash(state);
};
- let mt = |state: &mut SipHasher, mt: mt| {
+ let mt = |state: &mut SipHasher, mt: TypeAndMut| {
mt.mutbl.hash(state);
};
let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
}
}
-impl<'tcx> HasTypeFlags for field<'tcx> {
+impl<'tcx> HasTypeFlags for Field<'tcx> {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.mt.ty.has_type_flags(flags)
}
}
}
-impl<'tcx> fmt::Debug for field<'tcx> {
+impl<'tcx> fmt::Debug for Field<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "field({},{})", self.name, self.mt)
}
super_fold_ty(self, t)
}
- fn fold_mt(&mut self, t: &ty::mt<'tcx>) -> ty::mt<'tcx> {
+ fn fold_mt(&mut self, t: &ty::TypeAndMut<'tcx>) -> ty::TypeAndMut<'tcx> {
super_fold_mt(self, t)
}
}
}
-impl<'tcx> TypeFoldable<'tcx> for ty::mt<'tcx> {
- fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::mt<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
+ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::TypeAndMut<'tcx> {
folder.fold_mt(self)
}
}
}
}
-impl<'tcx> TypeFoldable<'tcx> for ty::field<'tcx> {
- fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::field<'tcx> {
- ty::field {
+impl<'tcx> TypeFoldable<'tcx> for ty::Field<'tcx> {
+ fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Field<'tcx> {
+ ty::Field {
name: self.name,
mt: self.mt.fold_with(folder),
}
}
pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
- mt: &ty::mt<'tcx>)
- -> ty::mt<'tcx> {
- ty::mt {ty: mt.ty.fold_with(this),
+ mt: &ty::TypeAndMut<'tcx>)
+ -> ty::TypeAndMut<'tcx> {
+ ty::TypeAndMut {ty: mt.ty.fold_with(this),
mutbl: mt.mutbl}
}
(&ty::TyInfer(_), _) |
(_, &ty::TyInfer(_)) => {
- Err(ty::terr_sorts(ty_relate::expected_found(self, &a, &b)))
+ Err(ty::TypeError::Sorts(ty_relate::expected_found(self, &a, &b)))
}
(&ty::TyError, _) | (_, &ty::TyError) => {
//! type equality, etc.
use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
-use middle::ty::{self, Ty};
+use middle::ty::{self, Ty, TypeError};
use middle::ty_fold::TypeFoldable;
use std::rc::Rc;
use syntax::abi;
use syntax::ast;
-pub type RelateResult<'tcx, T> = Result<T, ty::type_err<'tcx>>;
+pub type RelateResult<'tcx, T> = Result<T, ty::TypeError<'tcx>>;
#[derive(Clone, Debug)]
pub enum Cause {
///////////////////////////////////////////////////////////////////////////
// Relate impls
-impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::mt<'tcx> {
+impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::TypeAndMut<'tcx> {
fn relate<R>(relation: &mut R,
- a: &ty::mt<'tcx>,
- b: &ty::mt<'tcx>)
- -> RelateResult<'tcx, ty::mt<'tcx>>
+ a: &ty::TypeAndMut<'tcx>,
+ b: &ty::TypeAndMut<'tcx>)
+ -> RelateResult<'tcx, ty::TypeAndMut<'tcx>>
where R: TypeRelation<'a,'tcx>
{
debug!("{}.mts({:?}, {:?})",
a,
b);
if a.mutbl != b.mutbl {
- Err(ty::terr_mutability)
+ Err(TypeError::Mutability)
} else {
let mutbl = a.mutbl;
let variance = match mutbl {
ast::MutMutable => ty::Invariant,
};
let ty = try!(relation.relate_with_variance(variance, &a.ty, &b.ty));
- Ok(ty::mt {ty: ty, mutbl: mutbl})
+ Ok(ty::TypeAndMut {ty: ty, mutbl: mutbl})
}
}
}
where R: TypeRelation<'a,'tcx>
{
if a_tys.len() != b_tys.len() {
- return Err(ty::terr_ty_param_size(expected_found(relation,
+ return Err(TypeError::TyParamSize(expected_found(relation,
&a_tys.len(),
&b_tys.len())));
}
where R: TypeRelation<'a,'tcx>
{
if a.variadic != b.variadic {
- return Err(ty::terr_variadic_mismatch(
+ return Err(TypeError::VariadicMismatch(
expected_found(relation, &a.variadic, &b.variadic)));
}
(ty::FnDiverging, ty::FnDiverging) =>
Ok(ty::FnDiverging),
(a, b) =>
- Err(ty::terr_convergence_mismatch(
+ Err(TypeError::ConvergenceMismatch(
expected_found(relation, &(a != ty::FnDiverging), &(b != ty::FnDiverging)))),
});
where R: TypeRelation<'a,'tcx>
{
if a_args.len() != b_args.len() {
- return Err(ty::terr_arg_count);
+ return Err(TypeError::ArgCount);
}
a_args.iter().zip(b_args)
where R: TypeRelation<'a,'tcx>
{
if a != b {
- Err(ty::terr_unsafety_mismatch(expected_found(relation, a, b)))
+ Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b)))
} else {
Ok(*a)
}
if a == b {
Ok(*a)
} else {
- Err(ty::terr_abi_mismatch(expected_found(relation, a, b)))
+ Err(TypeError::AbiMismatch(expected_found(relation, a, b)))
}
}
}
where R: TypeRelation<'a,'tcx>
{
if a.item_name != b.item_name {
- Err(ty::terr_projection_name_mismatched(
+ Err(TypeError::ProjectionNameMismatched(
expected_found(relation, &a.item_name, &b.item_name)))
} else {
let trait_ref = try!(relation.relate(&a.trait_ref, &b.trait_ref));
// so we can just iterate through the lists pairwise, so long as they are the
// same length.
if a.len() != b.len() {
- Err(ty::terr_projection_bounds_length(expected_found(relation, &a.len(), &b.len())))
+ Err(TypeError::ProjectionBoundsLength(expected_found(relation, &a.len(), &b.len())))
} else {
a.iter().zip(b)
.map(|(a, b)| relation.relate(a, b))
// Two sets of builtin bounds are only relatable if they are
// precisely the same (but see the coercion code).
if a != b {
- Err(ty::terr_builtin_bounds(expected_found(relation, a, b)))
+ Err(TypeError::BuiltinBoundsMismatch(expected_found(relation, a, b)))
} else {
Ok(*a)
}
{
// Different traits cannot be related
if a.def_id != b.def_id {
- Err(ty::terr_traits(expected_found(relation, &a.def_id, &b.def_id)))
+ Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
} else {
let substs = try!(relate_item_substs(relation, a.def_id, a.substs, b.substs));
Ok(ty::TraitRef { def_id: a.def_id, substs: relation.tcx().mk_substs(substs) })
if sz_a == sz_b {
Ok(tcx.mk_array(t, sz_a))
} else {
- Err(ty::terr_fixed_array_size(expected_found(relation, &sz_a, &sz_b)))
+ Err(TypeError::FixedArraySize(expected_found(relation, &sz_a, &sz_b)))
}
}
.collect::<Result<_, _>>());
Ok(tcx.mk_tup(ts))
} else if !(as_.is_empty() || bs.is_empty()) {
- Err(ty::terr_tuple_size(
+ Err(TypeError::TupleSize(
expected_found(relation, &as_.len(), &bs.len())))
} else {
- Err(ty::terr_sorts(expected_found(relation, &a, &b)))
+ Err(TypeError::Sorts(expected_found(relation, &a, &b)))
}
}
_ =>
{
- Err(ty::terr_sorts(expected_found(relation, &a, &b)))
+ Err(TypeError::Sorts(expected_found(relation, &a, &b)))
}
}
}
pub fn expected_found<'a,'tcx:'a,R,T>(relation: &mut R,
a: &T,
b: &T)
- -> ty::expected_found<T>
+ -> ty::ExpectedFound<T>
where R: TypeRelation<'a,'tcx>, T: Clone
{
expected_found_bool(relation.a_is_expected(), a, b)
pub fn expected_found_bool<T>(a_is_expected: bool,
a: &T,
b: &T)
- -> ty::expected_found<T>
+ -> ty::ExpectedFound<T>
where T: Clone
{
let a = a.clone();
let b = b.clone();
if a_is_expected {
- ty::expected_found {expected: a, found: b}
+ ty::ExpectedFound {expected: a, found: b}
} else {
- ty::expected_found {expected: b, found: a}
+ ty::ExpectedFound {expected: b, found: a}
}
}
use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple};
use middle::ty::TyClosure;
use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
-use middle::ty::{self, mt, Ty, HasTypeFlags};
+use middle::ty::{self, TypeAndMut, Ty, HasTypeFlags};
use middle::ty_fold::{self, TypeFoldable};
use std::fmt;
}
}
-impl<'tcx> fmt::Display for ty::mt<'tcx> {
+impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}",
if self.mutbl == ast::MutMutable { "mut " } else { "" },
let mut file = try!(fs::File::create(&deps_filename));
for path in &out_filenames {
try!(write!(&mut file,
- "{}: {}\n\n", path.display(), files.connect(" ")));
+ "{}: {}\n\n", path.display(), files.join(" ")));
}
Ok(())
})();
for (name, to) in lints {
let name = name.to_lowercase().replace("_", "-");
let desc = to.into_iter().map(|x| x.as_str().replace("_", "-"))
- .collect::<Vec<String>>().connect(", ");
+ .collect::<Vec<String>>().join(", ");
println!(" {} {}",
padded(&name[..]), desc);
}
fn reconstructed_input(&self) -> String {
match *self {
ItemViaNode(node_id) => node_id.to_string(),
- ItemViaPath(ref parts) => parts.connect("::"),
+ ItemViaPath(ref parts) => parts.join("::"),
}
}
return match search_mod(self, &self.infcx.tcx.map.krate().module, 0, names) {
Some(id) => id,
None => {
- panic!("no item found: `{}`", names.connect("::"));
+ panic!("no item found: `{}`", names.join("::"));
}
};
}
words.push(buf);
}
- words.connect("_")
+ words.join("_")
}
fn check_snake_case(&self, cx: &Context, sort: &str, name: &str, span: Option<Span>) {
bcx.to_str(),
guard_expr,
m,
- vals.iter().map(|v| bcx.val_to_string(*v)).collect::<Vec<_>>().connect(", "));
+ vals.iter().map(|v| bcx.val_to_string(*v)).collect::<Vec<_>>().join(", "));
let _indenter = indenter();
let mut bcx = insert_lllocals(bcx, &data.bindings_map, None);
debug!("compile_submatch(bcx={}, m={:?}, vals=[{}])",
bcx.to_str(),
m,
- vals.iter().map(|v| bcx.val_to_string(*v)).collect::<Vec<_>>().connect(", "));
+ vals.iter().map(|v| bcx.val_to_string(*v)).collect::<Vec<_>>().join(", "));
let _indenter = indenter();
let _icx = push_ctxt("match::compile_submatch");
let mut bcx = bcx;
mut path: DiscrField) -> Option<DiscrField> {
match ty.sty {
// Fat &T/&mut T/Box<T> i.e. T is [T], str, or Trait
- ty::TyRef(_, ty::mt { ty, .. }) | ty::TyBox(ty) if !type_is_sized(tcx, ty) => {
+ ty::TyRef(_, ty::TypeAndMut { ty, .. }) | ty::TyBox(ty) if !type_is_sized(tcx, ty) => {
path.push(FAT_PTR_ADDR);
Some(path)
},
assert_eq!(nonzero_fields.len(), 1);
let nonzero_field = tcx.lookup_field_type(did, nonzero_fields[0].id, substs);
match nonzero_field.sty {
- ty::TyRawPtr(ty::mt { ty, .. }) if !type_is_sized(tcx, ty) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if !type_is_sized(tcx, ty) => {
path.push_all(&[0, FAT_PTR_ADDR]);
Some(path)
},
.chain(arch_clobbers.iter()
.map(|s| s.to_string()))
.collect::<Vec<String>>()
- .connect(",");
+ .join(",");
debug!("Asm Constraints: {}", &all_constraints[..]);
// We can also mark the return value as `dereferenceable` in certain cases
match ret_ty.sty {
// These are not really pointers but pairs, (pointer, len)
- ty::TyRef(_, ty::mt { ty: inner, .. })
+ ty::TyRef(_, ty::TypeAndMut { ty: inner, .. })
| ty::TyBox(inner) if common::type_is_sized(ccx.tcx(), inner) => {
let llret_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));
attrs.ret(llvm::DereferenceableAttribute(llret_sz));
terminate(cx, "Invoke");
debug!("Invoke({} with arguments ({}))",
cx.val_to_string(fn_),
- args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().connect(", "));
+ args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().join(", "));
debug_loc.apply(cx.fcx);
B(cx).invoke(fn_, args, then, catch, attributes)
}
args.iter()
.map(|&v| self.ccx.tn().val_to_string(v))
.collect::<Vec<String>>()
- .connect(", "));
+ .join(", "));
unsafe {
let v = llvm::LLVMBuildInvoke(self.llbuilder,
args.iter()
.map(|&v| self.ccx.tn().val_to_string(v))
.collect::<Vec<String>>()
- .connect(", "));
+ .join(", "));
unsafe {
let v = llvm::LLVMBuildCall(self.llbuilder, llfn, args.as_ptr(),
pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
match ty.sty {
- ty::TyRawPtr(ty::mt{ty, ..}) |
- ty::TyRef(_, ty::mt{ty, ..}) |
+ ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
+ ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
ty::TyBox(ty) => {
!type_is_sized(cx, ty)
}
let len = unsafe { llvm::LLVMConstIntGetZExtValue(len) as u64 };
let len = match bt.sty {
- ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) => match ty.sty {
+ ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) => match ty.sty {
ty::TyStr => {
assert!(len > 0);
len - 1
let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
unique_type_id.push_str(&inner_type_id[..]);
},
- ty::TyRawPtr(ty::mt { ty: inner_type, mutbl } ) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
unique_type_id.push('*');
if mutbl == ast::MutMutable {
unique_type_id.push_str("mut");
let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
unique_type_id.push_str(&inner_type_id[..]);
},
- ty::TyRef(_, ty::mt { ty: inner_type, mutbl }) => {
+ ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
unique_type_id.push('&');
if mutbl == ast::MutMutable {
unique_type_id.push_str("mut");
unique_type_id: UniqueTypeId,
span: Span)
-> MetadataCreationResult {
- let data_ptr_type = cx.tcx().mk_ptr(ty::mt {
+ let data_ptr_type = cx.tcx().mk_ptr(ty::TypeAndMut {
ty: element_type,
mutbl: ast::MutImmutable
});
trait_pointer_metadata(cx, t, None, unique_type_id),
false)
}
- ty::TyBox(ty) | ty::TyRawPtr(ty::mt{ty, ..}) | ty::TyRef(_, ty::mt{ty, ..}) => {
+ ty::TyBox(ty) |
+ ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
+ ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
match ty.sty {
ty::TySlice(typ) => {
vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
// Creates MemberDescriptions for the fields of a struct
struct StructMemberDescriptionFactory<'tcx> {
- fields: Vec<ty::field<'tcx>>,
+ fields: Vec<ty::Field<'tcx>>,
is_simd: bool,
span: Span,
}
let discrfield = discrfield.iter()
.skip(1)
.map(|x| x.to_string())
- .collect::<Vec<_>>().connect("$");
+ .collect::<Vec<_>>().join("$");
let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
discrfield,
null_variant_name);
push_debuginfo_type_name(cx, inner_type, true, output);
output.push('>');
},
- ty::TyRawPtr(ty::mt { ty: inner_type, mutbl } ) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
output.push('*');
match mutbl {
ast::MutImmutable => output.push_str("const "),
push_debuginfo_type_name(cx, inner_type, true, output);
},
- ty::TyRef(_, ty::mt { ty: inner_type, mutbl }) => {
+ ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
output.push('&');
if mutbl == ast::MutMutable {
output.push_str("mut ");
match (&source.ty.sty, &target.ty.sty) {
(&ty::TyBox(a), &ty::TyBox(b)) |
- (&ty::TyRef(_, ty::mt { ty: a, .. }), &ty::TyRef(_, ty::mt { ty: b, .. })) |
- (&ty::TyRef(_, ty::mt { ty: a, .. }), &ty::TyRawPtr(ty::mt { ty: b, .. })) |
- (&ty::TyRawPtr(ty::mt { ty: a, .. }), &ty::TyRawPtr(ty::mt { ty: b, .. })) => {
+ (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
+ &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) |
+ (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
+ &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) |
+ (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
+ &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
let (inner_source, inner_target) = (a, b);
let (base, old_info) = if !type_is_sized(bcx.tcx(), inner_source) {
base: &ast::Expr,
get_idx: F)
-> DatumBlock<'blk, 'tcx, Expr> where
- F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> usize,
+ F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::Field<'tcx>]) -> usize,
{
let mut bcx = bcx;
let _icx = push_ctxt("trans_rec_field");
node_id_opt: Option<ast::NodeId>,
op: F)
-> R where
- F: FnOnce(ty::Disr, &[ty::field<'tcx>]) -> R,
+ F: FnOnce(ty::Disr, &[ty::Field<'tcx>]) -> R,
{
match ty.sty {
ty::TyStruct(did, substs) => {
ty::TyTuple(ref v) => {
let fields: Vec<_> = v.iter().enumerate().map(|(i, &f)| {
- ty::field {
+ ty::Field {
name: token::intern(&i.to_string()),
- mt: ty::mt {
+ mt: ty::TypeAndMut {
ty: f,
mutbl: ast::MutImmutable
}
}
match (t_in.builtin_deref(true), t_out.builtin_deref(true)) {
- (Some(ty::mt{ ty: t_in, .. }), Some(ty::mt{ ty: t_out, .. })) => {
+ (Some(ty::TypeAndMut{ ty: t_in, .. }), Some(ty::TypeAndMut{ ty: t_out, .. })) => {
t_in == t_out
}
_ => {
}
}
- ty::TyRawPtr(ty::mt { ty: content_ty, .. }) |
- ty::TyRef(_, ty::mt { ty: content_ty, .. }) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: content_ty, .. }) |
+ ty::TyRef(_, ty::TypeAndMut { ty: content_ty, .. }) => {
if type_is_sized(bcx.tcx(), content_ty) {
let ptr = datum.to_llscalarish(bcx);
impl<T:LlvmRepr> LlvmRepr for [T] {
fn llrepr(&self, ccx: &CrateContext) -> String {
let reprs: Vec<String> = self.iter().map(|t| t.llrepr(ccx)).collect();
- format!("[{}]", reprs.connect(","))
+ format!("[{}]", reprs.join(","))
}
}
}
// Only used for pattern matching.
- ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) => {
+ ty::TyBox(ty) | ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
let inner = if type_is_sized(bcx.tcx(), ty) {
Load(bcx, llval)
} else {
pub fn types_to_str(&self, tys: &[Type]) -> String {
let strs: Vec<String> = tys.iter().map(|t| self.type_to_string(*t)).collect();
- format!("[{}]", strs.connect(","))
+ format!("[{}]", strs.join(","))
}
pub fn val_to_string(&self, val: ValueRef) -> String {
ty::TyUint(t) => Type::uint_from_ty(cx, t),
ty::TyFloat(t) => Type::float_from_ty(cx, t),
- ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) | ty::TyRawPtr(ty::mt{ty, ..}) => {
+ ty::TyBox(ty) |
+ ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
+ ty::TyRawPtr(ty::TypeAndMut{ty, ..}) => {
if type_is_sized(cx.tcx(), ty) {
Type::i8p(cx)
} else {
adt::incomplete_type_of(cx, &*repr, "closure")
}
- ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) | ty::TyRawPtr(ty::mt{ty, ..}) => {
+ ty::TyBox(ty) |
+ ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
+ ty::TyRawPtr(ty::TypeAndMut{ty, ..}) => {
if !type_is_sized(cx.tcx(), ty) {
if let ty::TyStr = ty.sty {
// This means we get a nicer name in the output (str is always
let tstr = if strings.is_empty() {
base
} else {
- format!("{}<{}>", base, strings.connect(", "))
+ format!("{}<{}>", base, strings.join(", "))
};
if did.krate == 0 {
}
}
ast::TyPtr(ref mt) => {
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: ast_ty_to_ty(this, rscope, &*mt.ty),
mutbl: mt.mutbl
})
rscope,
ty::ObjectLifetimeDefault::Specific(r));
let t = ast_ty_to_ty(this, rscope1, &*mt.ty);
- tcx.mk_ref(tcx.mk_region(r), ty::mt {ty: t, mutbl: mt.mutbl})
+ tcx.mk_ref(tcx.mk_region(r), ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
}
ast::TyTup(ref fields) => {
let flds = fields.iter()
ty::ByReferenceExplicitSelfCategory(region, mutability) => {
(Some(this.tcx().mk_ref(
this.tcx().mk_region(region),
- ty::mt {
+ ty::TypeAndMut {
ty: self_info.untransformed_self_ty,
mutbl: mutability
})),
// then `x` is assigned a value of type `&M T` where M is the mutability
// and T is the expected type.
let region_var = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
- let mt = ty::mt { ty: expected, mutbl: mutbl };
+ let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
let region_ty = tcx.mk_ref(tcx.mk_region(region_var), mt);
// `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
ast::PatRegion(ref inner, mutbl) => {
let inner_ty = fcx.infcx().next_ty_var();
- let mt = ty::mt { ty: inner_ty, mutbl: mutbl };
+ let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
let rptr_ty = tcx.mk_ref(tcx.mk_region(region), mt);
}),
_ => {
let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
- tcx.mk_ref(tcx.mk_region(region), ty::mt {
+ tcx.mk_ref(tcx.mk_region(region), ty::TypeAndMut {
ty: tcx.mk_slice(inner_ty),
mutbl: expected_ty.builtin_deref(true).map(|mt| mt.mutbl)
.unwrap_or(ast::MutImmutable)
let mutbl = expected_ty.builtin_deref(true)
.map_or(ast::MutImmutable, |mt| mt.mutbl);
- let slice_ty = tcx.mk_ref(tcx.mk_region(region), ty::mt {
+ let slice_ty = tcx.mk_ref(tcx.mk_region(region), ty::TypeAndMut {
ty: tcx.mk_slice(inner_ty),
mutbl: mutbl
});
pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
span: Span,
fields: &'tcx [Spanned<ast::FieldPat>],
- struct_fields: &[ty::field<'tcx>],
+ struct_fields: &[ty::Field<'tcx>],
struct_id: ast::DefId,
etc: bool) {
let tcx = pcx.fcx.ccx.tcx;
fn check_ptr_ptr_cast<'a>(&self,
fcx: &FnCtxt<'a, 'tcx>,
- m_expr: &'tcx ty::mt<'tcx>,
- m_cast: &'tcx ty::mt<'tcx>)
+ m_expr: &'tcx ty::TypeAndMut<'tcx>,
+ m_cast: &'tcx ty::TypeAndMut<'tcx>)
-> Result<CastKind, CastError>
{
debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}",
fn check_fptr_ptr_cast<'a>(&self,
fcx: &FnCtxt<'a, 'tcx>,
- m_cast: &'tcx ty::mt<'tcx>)
+ m_cast: &'tcx ty::TypeAndMut<'tcx>)
-> Result<CastKind, CastError>
{
// fptr-ptr cast. must be to sized ptr
fn check_ptr_addr_cast<'a>(&self,
fcx: &FnCtxt<'a, 'tcx>,
- m_expr: &'tcx ty::mt<'tcx>)
+ m_expr: &'tcx ty::TypeAndMut<'tcx>)
-> Result<CastKind, CastError>
{
// ptr-addr cast. must be from sized ptr
fn check_ref_cast<'a>(&self,
fcx: &FnCtxt<'a, 'tcx>,
- m_expr: &'tcx ty::mt<'tcx>,
- m_cast: &'tcx ty::mt<'tcx>)
+ m_expr: &'tcx ty::TypeAndMut<'tcx>,
+ m_cast: &'tcx ty::TypeAndMut<'tcx>)
-> Result<CastKind, CastError>
{
// array-ptr-cast.
fn check_addr_ptr_cast<'a>(&self,
fcx: &FnCtxt<'a, 'tcx>,
- m_cast: &'tcx ty::mt<'tcx>)
+ m_cast: &'tcx ty::TypeAndMut<'tcx>)
-> Result<CastKind, CastError>
{
// ptr-addr cast. pointer must be thin.
use middle::traits::{self, ObligationCause};
use middle::traits::{predicate_for_trait_def, report_selection_error};
use middle::ty::{AutoDerefRef, AdjustDerefRef};
-use middle::ty::{self, mt, Ty};
+use middle::ty::{self, TypeAndMut, Ty, TypeError};
use middle::ty_relate::RelateResult;
use util::common::indent;
return None;
}
let ty = self.tcx().mk_ref(r_borrow,
- mt {ty: inner_ty, mutbl: mutbl_b});
+ TypeAndMut {ty: inner_ty, mutbl: mutbl_b});
if let Err(err) = self.subtype(ty, b) {
if first_error.is_none() {
first_error = Some(err);
(u, cu)
} else {
debug!("Missing Unsize or CoerceUnsized traits");
- return Err(ty::terr_mismatch);
+ return Err(TypeError::Mismatch);
};
// Note, we want to avoid unnecessary unsizing. We don't want to coerce to
// Uncertain or unimplemented.
Ok(None) | Err(traits::Unimplemented) => {
debug!("coerce_unsized: early return - can't prove obligation");
- return Err(ty::terr_mismatch);
+ return Err(TypeError::Mismatch);
}
// Object safety violations or miscellaneous.
};
// Check that the types which they point at are compatible.
- let a_unsafe = self.tcx().mk_ptr(ty::mt{ mutbl: mutbl_b, ty: mt_a.ty });
+ let a_unsafe = self.tcx().mk_ptr(ty::TypeAndMut{ mutbl: mutbl_b, ty: mt_a.ty });
try!(self.subtype(a_unsafe, b));
try!(coerce_mutbls(mt_a.mutbl, mutbl_b));
(ast::MutMutable, ast::MutMutable) |
(ast::MutImmutable, ast::MutImmutable) |
(ast::MutMutable, ast::MutImmutable) => Ok(None),
- (ast::MutImmutable, ast::MutMutable) => Err(ty::terr_mutability)
+ (ast::MutImmutable, ast::MutMutable) => Err(TypeError::Mutability)
}
}
ty_a: Ty<'tcx>,
ty_b: Ty<'tcx>,
handle_err: F) where
- F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::type_err<'tcx>),
+ F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::TypeError<'tcx>),
{
// n.b.: order of actual, expected is reversed
match infer::mk_subty(fcx.infcx(), b_is_expected, infer::Misc(sp),
};
match sig.0.inputs[0].sty {
- ty::TyRef(_, ty::mt {
+ ty::TyRef(_, ty::TypeAndMut {
ty: _,
mutbl: ast::MutMutable,
}) => {}
// Trait method is fn(&self) or fn(&mut self), need an
// autoref. Pull the region etc out of the type of first argument.
match transformed_self_ty.sty {
- ty::TyRef(region, ty::mt { mutbl, ty: _ }) => {
+ ty::TyRef(region, ty::TypeAndMut { mutbl, ty: _ }) => {
fcx.write_adjustment(self_expr.id,
ty::AdjustDerefRef(ty::AutoDerefRef {
autoderefs: autoderefs,
let lang_def_id = self.tcx().lang_items.slice_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
}
- ty::TyRawPtr(ty::mt { ty: _, mutbl: ast::MutImmutable }) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: ast::MutImmutable }) => {
let lang_def_id = self.tcx().lang_items.const_ptr_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
}
- ty::TyRawPtr(ty::mt { ty: _, mutbl: ast::MutMutable }) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: ast::MutMutable }) => {
let lang_def_id = self.tcx().lang_items.mut_ptr_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
}
// Search through mutabilities in order to find one where pick works:
[ast::MutImmutable, ast::MutMutable].iter().filter_map(|&m| {
- let autoref_ty = tcx.mk_ref(region, ty::mt {
+ let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut {
ty: step.self_ty,
mutbl: m
});
p.self_ty(),
p))
.collect::<Vec<_>>()
- .connect(", ");
+ .join(", ");
cx.sess.fileline_note(
span,
&format!("the method `{}` exists but the \
"not all trait items implemented, missing: `{}`",
missing_items.iter()
.map(<ast::Name>::as_str)
- .collect::<Vec<_>>().connect("`, `"))
+ .collect::<Vec<_>>().join("`, `"))
}
if !invalidated_items.is_empty() {
invalidator.ident.as_str(),
invalidated_items.iter()
.map(<ast::Name>::as_str)
- .collect::<Vec<_>>().connect("`, `"))
+ .collect::<Vec<_>>().join("`, `"))
}
}
format!("cast to unsized type: `{}` as `{}`", actual, tstr)
}, t_expr, None);
match t_expr.sty {
- ty::TyRef(_, ty::mt { mutbl: mt, .. }) => {
+ ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
let mtstr = match mt {
ast::MutMutable => "mut ",
ast::MutImmutable => ""
origin: infer::TypeOrigin,
sub: Ty<'tcx>,
sup: Ty<'tcx>)
- -> Result<(), ty::type_err<'tcx>> {
+ -> Result<(), ty::TypeError<'tcx>> {
infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
}
origin: infer::TypeOrigin,
sub: Ty<'tcx>,
sup: Ty<'tcx>)
- -> Result<(), ty::type_err<'tcx>> {
+ -> Result<(), ty::TypeError<'tcx>> {
infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
}
sp: Span,
mk_msg: M,
actual_ty: Ty<'tcx>,
- err: Option<&ty::type_err<'tcx>>) where
+ err: Option<&ty::TypeError<'tcx>>) where
M: FnOnce(String) -> String,
{
self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
sp: Span,
e: Ty<'tcx>,
a: Ty<'tcx>,
- err: &ty::type_err<'tcx>) {
+ err: &ty::TypeError<'tcx>) {
self.infcx().report_mismatched_types(sp, e, a, err)
}
pub fn lookup_field_ty(&self,
span: Span,
class_id: ast::DefId,
- items: &[ty::field_ty],
+ items: &[ty::FieldTy],
fieldname: ast::Name,
substs: &subst::Substs<'tcx>)
-> Option<Ty<'tcx>>
pub fn lookup_tup_field_ty(&self,
span: Span,
class_id: ast::DefId,
- items: &[ty::field_ty],
+ items: &[ty::FieldTy],
idx: usize,
substs: &subst::Substs<'tcx>)
-> Option<Ty<'tcx>>
base_expr: Option<&ast::Expr>,
base_ty: Ty<'tcx>,
lvalue_pref: LvaluePreference)
- -> Option<ty::mt<'tcx>>
+ -> Option<ty::TypeAndMut<'tcx>>
{
// Try DerefMut first, if preferred.
let method = match (lvalue_pref, fcx.tcx().lang_items.deref_mut_trait()) {
fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
method_call: Option<MethodCall>,
method: Option<MethodCallee<'tcx>>)
- -> Option<ty::mt<'tcx>>
+ -> Option<ty::TypeAndMut<'tcx>>
{
match method {
Some(method) => {
class_id: ast::DefId,
node_id: ast::NodeId,
substitutions: &'tcx subst::Substs<'tcx>,
- field_types: &[ty::field_ty],
+ field_types: &[ty::FieldTy],
ast_fields: &'tcx [ast::Field],
check_completeness: bool,
enum_id_opt: Option<ast::DefId>) {
span_err!(tcx.sess, span, E0063,
"missing field{}: {}",
if missing_fields.len() == 1 {""} else {"s"},
- missing_fields.connect(", "));
+ missing_fields.join(", "));
}
}
hint,
lvalue_pref);
- let tm = ty::mt { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
+ let tm = ty::TypeAndMut { ty: fcx.expr_ty(&**oprnd), mutbl: mutbl };
let oprnd_t = if tm.ty.references_error() {
tcx.types.err
} else {
"offset" | "arith_offset" => {
(1,
vec!(
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutImmutable
}),
ccx.tcx.types.isize
),
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutImmutable
}))
"copy" | "copy_nonoverlapping" => {
(1,
vec!(
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutImmutable
}),
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutMutable
}),
"volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
(1,
vec!(
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutMutable
}),
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutImmutable
}),
"write_bytes" | "volatile_set_memory" => {
(1,
vec!(
- tcx.mk_ptr(ty::mt {
+ tcx.mk_ptr(ty::TypeAndMut {
ty: param(ccx, 0),
mutbl: ast::MutMutable
}),
reason: reason }
}
- fn report_error(&self, e: infer::fixup_err) {
+ fn report_error(&self, e: infer::FixupError) {
self.writeback_errors.set(true);
if !self.tcx.sess.has_errors() {
match self.reason {
let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env), true);
- let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
+ let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>, mt_b: ty::TypeAndMut<'tcx>,
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
if (mt_a.mutbl, mt_b.mutbl) == (ast::MutImmutable, ast::MutMutable) {
infcx.report_mismatched_types(span, mk_ptr(mt_b.ty),
- target, &ty::terr_mutability);
+ target, &ty::TypeError::Mutability);
}
(mt_a.ty, mt_b.ty, unsize_trait, None)
};
} else {
name.to_string()
}, a, b)
- }).collect::<Vec<_>>().connect(", "));
+ }).collect::<Vec<_>>().join(", "));
return;
}
self.check_def_id(item, data.principal_def_id());
}
ty::TyBox(..) => {
- self.check_def_id(item, self.tcx.lang_items.owned_box().unwrap());
+ match self.tcx.lang_items.require_owned_box() {
+ Ok(trait_id) => self.check_def_id(item, trait_id),
+ Err(msg) => self.tcx.sess.span_fatal(item.span, &msg),
+ }
}
ty::TyChar => {
self.check_primitive_impl(def_id,
"[T]",
item.span);
}
- ty::TyRawPtr(ty::mt { ty: _, mutbl: ast::MutImmutable }) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: ast::MutImmutable }) => {
self.check_primitive_impl(def_id,
self.tcx.lang_items.const_ptr_impl(),
"const_ptr",
"*const T",
item.span);
}
- ty::TyRawPtr(ty::mt { ty: _, mutbl: ast::MutMutable }) => {
+ ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: ast::MutMutable }) => {
self.check_primitive_impl(def_id,
self.tcx.lang_items.mut_ptr_impl(),
"mut_ptr",
struct_predicates: &ty::GenericPredicates<'tcx>,
v: &ast::StructField,
origin: ast::DefId)
- -> ty::field_ty
+ -> ty::FieldTy
{
let tt = ccx.icx(struct_predicates).to_ty(&ExplicitRscope, &*v.node.ty);
write_ty_to_tcx(ccx.tcx, v.node.id, tt);
match v.node.kind {
ast::NamedField(ident, visibility) => {
- ty::field_ty {
+ ty::FieldTy {
name: ident.name,
id: local_def(v.node.id),
vis: visibility,
}
}
ast::UnnamedField(visibility) => {
- ty::field_ty {
+ ty::FieldTy {
name: special_idents::unnamed_field.name,
id: local_def(v.node.id),
vis: visibility,
d => format!("{:?}", d),
})
.collect::<Vec<String>>()
- .connect(",");
+ .join(",");
tcx.sess.span_err(it.span, &object_lifetime_default_reprs);
}
/// appearing in a context with ambient variance `variance`
fn add_constraints_from_mt(&mut self,
generics: &ty::Generics<'tcx>,
- mt: &ty::mt<'tcx>,
+ mt: &ty::TypeAndMut<'tcx>,
variance: VarianceTermPtr<'a>) {
match mt.mutbl {
ast::MutMutable => {
}
}
-impl Clean<Item> for ty::field_ty {
+impl Clean<Item> for ty::FieldTy {
fn clean(&self, cx: &DocContext) -> Item {
use syntax::parse::token::special_idents::unnamed_field;
use rustc::metadata::csearch;
format!("{} {{ {}{} }}", path_to_string(name),
fields.iter().map(|&Spanned { node: ref fp, .. }|
format!("{}: {}", fp.ident.as_str(), name_from_pat(&*fp.pat)))
- .collect::<Vec<String>>().connect(", "),
+ .collect::<Vec<String>>().join(", "),
if etc { ", ..." } else { "" }
)
},
PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
- .collect::<Vec<String>>().connect(", ")),
+ .collect::<Vec<String>>().join(", ")),
PatBox(ref p) => name_from_pat(&**p),
PatRegion(ref p, _) => name_from_pat(&**p),
PatLit(..) => {
let begin = begin.iter().map(|p| name_from_pat(&**p));
let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter();
let end = end.iter().map(|p| name_from_pat(&**p));
- format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().connect(", "))
+ format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", "))
},
PatMac(..) => {
warn!("can't document the name of a function argument \
match href(did) {
Some((url, shortty, fqp)) => {
try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
- shortty, url, fqp.connect("::"), last.name));
+ shortty, url, fqp.join("::"), last.name));
}
_ => try!(write!(w, "{}", last.name)),
}
fn collapse_whitespace(s: &str) -> String {
s.split(|c: char| c.is_whitespace()).filter(|s| {
!s.is_empty()
- }).collect::<Vec<_>>().connect(" ")
+ }).collect::<Vec<_>>().join(" ")
}
thread_local!(static USED_HEADER_MAP: RefCell<HashMap<String, usize>> = {
let lines = origtext.lines().filter(|l| {
stripped_filtered_line(*l).is_none()
});
- let text = lines.collect::<Vec<&str>>().connect("\n");
+ let text = lines.collect::<Vec<&str>>().join("\n");
if rendered { return }
PLAYGROUND_KRATE.with(|krate| {
let mut s = String::new();
krate.borrow().as_ref().map(|krate| {
let test = origtext.lines().map(|l| {
stripped_filtered_line(l).unwrap_or(l)
- }).collect::<Vec<&str>>().connect("\n");
+ }).collect::<Vec<&str>>().join("\n");
let krate = krate.as_ref().map(|s| &**s);
let test = test::maketest(&test, krate, false,
&Default::default());
// Transform the contents of the header into a hyphenated string
let id = s.split_whitespace().map(|s| s.to_ascii_lowercase())
- .collect::<Vec<String>>().connect("-");
+ .collect::<Vec<String>>().join("-");
// This is a terrible hack working around how hoedown gives us rendered
// html for text rather than the raw text.
let lines = text.lines().map(|l| {
stripped_filtered_line(l).unwrap_or(l)
});
- let text = lines.collect::<Vec<&str>>().connect("\n");
+ let text = lines.collect::<Vec<&str>>().join("\n");
tests.add_test(text.to_string(),
block_info.should_panic, block_info.no_run,
block_info.ignore, block_info.test_harness);
let inputs: Vec<String> = self.inputs.iter().map(|ref t| {
format!("{}", t)
}).collect();
- try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.connect(",")));
+ try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.join(",")));
match self.output {
Some(ref t) => try!(write!(f, "{}", t)),
search_index.push(IndexItem {
ty: shortty(item),
name: item.name.clone().unwrap(),
- path: fqp[..fqp.len() - 1].connect("::"),
+ path: fqp[..fqp.len() - 1].join("::"),
desc: shorter(item.doc_value()),
parent: Some(did),
search_type: get_index_search_type(&item, parent_basename),
self.search_index.push(IndexItem {
ty: shortty(&item),
name: s.to_string(),
- path: path.connect("::").to_string(),
+ path: path.join("::").to_string(),
desc: shorter(item.doc_value()),
parent: parent,
search_type: get_index_search_type(&item, parent_basename),
*slot.borrow_mut() = cx.current.clone();
});
- let mut title = cx.current.connect("::");
+ let mut title = cx.current.join("::");
if pushname {
if !title.is_empty() {
title.push_str("::");
Some(format!("{root}src/{krate}/{path}.html#{href}",
root = self.cx.root_path,
krate = self.cx.layout.krate,
- path = path.connect("/"),
+ path = path.join("/"),
href = href))
// If this item is not part of the local crate, then things get a little
};
Some(format!("{root}{path}/{file}?gotosrc={goto}",
root = root,
- path = path[..path.len() - 1].connect("/"),
+ path = path[..path.len() - 1].join("/"),
file = item_path(self.item),
goto = self.item.def_id.node))
}
}
fn full_path(cx: &Context, item: &clean::Item) -> String {
- let mut s = cx.current.connect("::");
+ let mut s = cx.current.join("::");
s.push_str("::");
s.push_str(item.name.as_ref().unwrap());
return s
(*line).chars().any(|chr|{
!chr.is_whitespace()
})
- }).collect::<Vec<_>>().connect("\n"),
+ }).collect::<Vec<_>>().join("\n"),
None => "".to_string()
}
}
try!(write!(w, r#"<script type="text/javascript" async
src="{root_path}/implementors/{path}/{ty}.{name}.js">
</script>"#,
- root_path = vec![".."; cx.current.len()].connect("/"),
+ root_path = vec![".."; cx.current.len()].join("/"),
path = if ast_util::is_local(it.def_id) {
- cx.current.connect("/")
+ cx.current.join("/")
} else {
let path = &cache.external_paths[&it.def_id];
- path[..path.len() - 1].connect("/")
+ path[..path.len() - 1].join("/")
},
ty = shortty(it).to_static_str(),
name = *it.name.as_ref().unwrap()));
line[min_indent..].to_string()
}
}).collect::<Vec<_>>());
- unindented.connect("\n")
+ unindented.join("\n")
} else {
s.to_string()
}
let s = self.current_header.as_ref().map(|s| &**s).unwrap_or("");
format!("{}_{}", s, self.cnt)
} else {
- format!("{}_{}", self.names.connect("::"), self.cnt)
+ format!("{}_{}", self.names.join("::"), self.cnt)
};
self.cnt += 1;
let libs = self.libs.clone();
.iter()
.map(|&seg| format!("{:x}", seg))
.collect::<Vec<String>>()
- .connect(":")
+ .join(":")
}
write!(fmt, "{}::{}",
use cell::{Cell, UnsafeCell};
use intrinsics;
+ use ptr;
pub struct Key<T> {
inner: UnsafeCell<Option<T>>,
#[cfg(target_os = "linux")]
unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
use mem;
- use ptr;
use libc;
use sys_common::thread_local as os;
// destructor as running for this thread so calls to `get` will return
// `None`.
(*ptr).dtor_running.set(true);
- intrinsics::drop_in_place((*ptr).inner.get());
+
+ // The OSX implementation of TLS apparently had an odd aspect to it
+ // where the pointer we have may be overwritten while this destructor
+ // is running. Specifically if a TLS destructor re-accesses TLS it may
+ // trigger a re-initialization of all TLS variables, paving over at
+ // least some destroyed ones with initial values.
+ //
+ // This means that if we drop a TLS value in place on OSX that we could
+ // revert the value to its original state halfway through the
+ // destructor, which would be bad!
+ //
+ // Hence, we use `ptr::read` on OSX (to move to a "safe" location)
+ // instead of drop_in_place.
+ if cfg!(target_os = "macos") {
+ ptr::read((*ptr).inner.get());
+ } else {
+ intrinsics::drop_in_place((*ptr).inner.get());
+ }
}
}
// FIXME: Bad copies (#2543 -- same for everything else that says "bad")
idents.iter().map(|i| {
token::get_ident(*i).to_string()
- }).collect::<Vec<String>>().connect("::")
+ }).collect::<Vec<String>>().join("::")
}
pub fn local_def(id: NodeId) -> DefId {
.iter()
.map(|x| token::get_ident(*x).to_string())
.collect::<Vec<String>>()
- .connect("::");
+ .join("::");
base::MacEager::expr(cx.expr_str(
sp,
token::intern_and_get_ident(&string[..])))
token::get_ident(bind))).to_string()
}
_ => panic!()
- } }).collect::<Vec<String>>().connect(" or ");
+ } }).collect::<Vec<String>>().join(" or ");
return Error(sp, format!(
"local ambiguity: multiple parsing options: \
built-in NTs {} or {} other options.",
let lines = vertical_trim(lines);
let lines = horizontal_trim(lines);
- return lines.connect("\n");
+ return lines.join("\n");
}
panic!("not a doc-comment: {}", comment);
self.span_diagnostic.span_err(sp, m)
}
+ /// Suggest some help with a given span.
+ pub fn help_span(&self, sp: Span, m: &str) {
+ self.span_diagnostic.span_help(sp, m)
+ }
+
/// Report a fatal error spanning [`from_pos`, `to_pos`).
fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> ! {
self.fatal_span(codemap::mk_sp(from_pos, to_pos), m)
self.err_span(codemap::mk_sp(from_pos, to_pos), m)
}
+ /// Suggest some help spanning [`from_pos`, `to_pos`).
+ fn help_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
+ self.help_span(codemap::mk_sp(from_pos, to_pos), m)
+ }
+
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
/// escaped character to the error message
fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> ! {
return match e {
'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true,
'x' => self.scan_byte_escape(delim, !ascii_only),
- 'u' if self.curr_is('{') => {
- let valid = self.scan_unicode_escape(delim);
- if valid && ascii_only {
- self.err_span_(
- escaped_pos,
- self.last_pos,
+ 'u' => {
+ let valid = if self.curr_is('{') {
+ self.scan_unicode_escape(delim) && !ascii_only
+ } else {
+ self.err_span_(start, self.last_pos,
+ "incorrect unicode escape sequence");
+ self.help_span_(start, self.last_pos,
+ "format of unicode escape sequences is `\\u{…}`");
+ false
+ };
+ if ascii_only {
+ self.err_span_(start, self.last_pos,
"unicode escape sequences cannot be used as a byte or in \
a byte string"
);
- false
- } else {
- valid
}
+ valid
+
}
'\n' if delim == '"' => {
self.consume_whitespace();
if ascii_only { "unknown byte escape" }
else { "unknown character escape" },
c);
- let sp = codemap::mk_sp(escaped_pos, last_pos);
if e == '\r' {
- self.span_diagnostic.span_help(
- sp,
+ self.help_span_(escaped_pos, last_pos,
"this is an isolated carriage return; consider checking \
your editor and version control settings")
}
if (e == '{' || e == '}') && !ascii_only {
- self.span_diagnostic.span_help(
- sp,
+ self.help_span_(escaped_pos, last_pos,
"if used in a formatting string, \
curly braces are escaped with `{{` and `}}`")
}
valid = false;
}
- self.bump(); // past the ending }
-
if valid && (char::from_u32(accum_int).is_none() || count == 0) {
self.err_span_(start_bpos, self.last_pos, "illegal unicode character escape");
valid = false;
}
-
+ self.bump(); // past the ending }
valid
}
use ast::{Visibility, WhereClause};
use ast;
use ast_util::{self, AS_PREC, ident_to_path, operator_prec};
-use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp};
+use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
use diagnostic;
use ext::tt::macro_parser;
use parse;
t.is_plain_ident() || *t == token::Underscore
}
+/// Information about the path to a module.
+pub struct ModulePath {
+ pub name: String,
+ pub path_exists: bool,
+ pub result: Result<ModulePathSuccess, ModulePathError>,
+}
+
+pub struct ModulePathSuccess {
+ pub path: ::std::path::PathBuf,
+ pub owns_directory: bool,
+}
+
+pub struct ModulePathError {
+ pub err_msg: String,
+ pub help_msg: String,
+}
+
+
impl<'a> Parser<'a> {
pub fn new(sess: &'a ParseSess,
cfg: ast::CrateConfig,
self.mod_path_stack.pop().unwrap();
}
- /// Read a module from a source file.
- fn eval_src_mod(&mut self,
- id: ast::Ident,
- outer_attrs: &[ast::Attribute],
- id_sp: Span)
- -> PResult<(ast::Item_, Vec<ast::Attribute> )> {
+ pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
+ ::attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&*d))
+ }
+
+ /// Returns either a path to a module, or .
+ pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -> ModulePath
+ {
+ let mod_string = token::get_ident(id);
+ let mod_name = mod_string.to_string();
+ let default_path_str = format!("{}.rs", mod_name);
+ let secondary_path_str = format!("{}/mod.rs", mod_name);
+ let default_path = dir_path.join(&default_path_str);
+ let secondary_path = dir_path.join(&secondary_path_str);
+ let default_exists = codemap.file_exists(&default_path);
+ let secondary_exists = codemap.file_exists(&secondary_path);
+
+ let result = match (default_exists, secondary_exists) {
+ (true, false) => Ok(ModulePathSuccess { path: default_path, owns_directory: false }),
+ (false, true) => Ok(ModulePathSuccess { path: secondary_path, owns_directory: true }),
+ (false, false) => Err(ModulePathError {
+ err_msg: format!("file not found for module `{}`", mod_name),
+ help_msg: format!("name the file either {} or {} inside the directory {:?}",
+ default_path_str,
+ secondary_path_str,
+ dir_path.display()),
+ }),
+ (true, true) => Err(ModulePathError {
+ err_msg: format!("file for module `{}` found at both {} and {}",
+ mod_name,
+ default_path_str,
+ secondary_path_str),
+ help_msg: "delete or rename one of them to remove the ambiguity".to_owned(),
+ }),
+ };
+
+ ModulePath {
+ name: mod_name,
+ path_exists: default_exists || secondary_exists,
+ result: result,
+ }
+ }
+
+ fn submod_path(&mut self,
+ id: ast::Ident,
+ outer_attrs: &[ast::Attribute],
+ id_sp: Span) -> PResult<ModulePathSuccess> {
let mut prefix = PathBuf::from(&self.sess.codemap().span_to_filename(self.span));
prefix.pop();
let mut dir_path = prefix;
for part in &self.mod_path_stack {
dir_path.push(&**part);
}
- let mod_string = token::get_ident(id);
- let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
- outer_attrs, "path") {
- Some(d) => (dir_path.join(&*d), true),
- None => {
- let mod_name = mod_string.to_string();
- let default_path_str = format!("{}.rs", mod_name);
- let secondary_path_str = format!("{}/mod.rs", mod_name);
- let default_path = dir_path.join(&default_path_str[..]);
- let secondary_path = dir_path.join(&secondary_path_str[..]);
- let default_exists = self.sess.codemap().file_exists(&default_path);
- let secondary_exists = self.sess.codemap().file_exists(&secondary_path);
-
- if !self.owns_directory {
- self.span_err(id_sp,
- "cannot declare a new module at this location");
- let this_module = match self.mod_path_stack.last() {
- Some(name) => name.to_string(),
- None => self.root_module_name.as_ref().unwrap().clone(),
- };
- self.span_note(id_sp,
- &format!("maybe move this module `{0}` \
- to its own directory via \
- `{0}/mod.rs`",
- this_module));
- if default_exists || secondary_exists {
- self.span_note(id_sp,
- &format!("... or maybe `use` the module \
- `{}` instead of possibly \
- redeclaring it",
- mod_name));
- }
- self.abort_if_errors();
- }
- match (default_exists, secondary_exists) {
- (true, false) => (default_path, false),
- (false, true) => (secondary_path, true),
- (false, false) => {
- return Err(self.span_fatal_help(id_sp,
- &format!("file not found for module `{}`",
- mod_name),
- &format!("name the file either {} or {} inside \
- the directory {:?}",
- default_path_str,
- secondary_path_str,
- dir_path.display())));
- }
- (true, true) => {
- return Err(self.span_fatal_help(
- id_sp,
- &format!("file for module `{}` found at both {} \
- and {}",
- mod_name,
- default_path_str,
- secondary_path_str),
- "delete or rename one of them to remove the ambiguity"));
- }
- }
+ if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &dir_path) {
+ return Ok(ModulePathSuccess { path: p, owns_directory: true });
+ }
+
+ let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap());
+
+ if !self.owns_directory {
+ self.span_err(id_sp, "cannot declare a new module at this location");
+ let this_module = match self.mod_path_stack.last() {
+ Some(name) => name.to_string(),
+ None => self.root_module_name.as_ref().unwrap().clone(),
+ };
+ self.span_note(id_sp,
+ &format!("maybe move this module `{0}` to its own directory \
+ via `{0}/mod.rs`",
+ this_module));
+ if paths.path_exists {
+ self.span_note(id_sp,
+ &format!("... or maybe `use` the module `{}` instead \
+ of possibly redeclaring it",
+ paths.name));
}
- };
+ self.abort_if_errors();
+ }
+
+ match paths.result {
+ Ok(succ) => Ok(succ),
+ Err(err) => Err(self.span_fatal_help(id_sp, &err.err_msg, &err.help_msg)),
+ }
+ }
+
+ /// Read a module from a source file.
+ fn eval_src_mod(&mut self,
+ id: ast::Ident,
+ outer_attrs: &[ast::Attribute],
+ id_sp: Span)
+ -> PResult<(ast::Item_, Vec<ast::Attribute> )> {
+ let ModulePathSuccess { path, owns_directory } = try!(self.submod_path(id,
+ outer_attrs,
+ id_sp));
- self.eval_src_mod_from_path(file_path, owns_directory,
- mod_string.to_string(), id_sp)
+ self.eval_src_mod_from_path(path,
+ owns_directory,
+ token::get_ident(id).to_string(),
+ id_sp)
}
fn eval_src_mod_from_path(&mut self,
last_span,
&format!("illegal ABI: expected one of [{}], \
found `{}`",
- abi::all_names().connect(", "),
+ abi::all_names().join(", "),
the_string));
Ok(None)
}
.map(|(k,v)| format!("{}: {} (+/- {})", *k,
v.value, v.noise))
.collect();
- v.connect(", ")
+ v.join(", ")
}
}
sp: Span,
_: &[ast::TokenTree]) -> Box<MacResult+'cx> {
let args = self.args.iter().map(|i| pprust::meta_item_to_string(&*i))
- .collect::<Vec<_>>().connect(", ");
+ .collect::<Vec<_>>().join(", ");
let interned = token::intern_and_get_ident(&args[..]);
MacEager::expr(ecx.expr_str(sp, interned))
}
--- /dev/null
+// Copyright 2015 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.
+
+// Test that we don't ICE when we are missing the owned_box lang item.
+
+// error-pattern: requires `owned_box` lang_item
+
+#![no_std]
+#![feature(lang_items, no_std, box_syntax)]
+
+extern crate core;
+
+fn main() {
+ let x = box 1i32;
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
//~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
let _ = b'\u';
- //~^ ERROR unknown byte escape: u
+ //~^ ERROR incorrect unicode escape sequence
+ //~^^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
let _ = b'\x5';
//~^ ERROR numeric character escape is too short
let _ = b"\u{a4a4} \xf \u";
//~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
//~^^ ERROR illegal character in numeric character escape:
- //~^^^ ERROR unknown byte escape: u
+ //~^^^ ERROR incorrect unicode escape sequence
+ //~^^^^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
let _ = "\u{ffffff} \xf \u";
//~^ ERROR illegal unicode character escape
//~^^ ERROR illegal character in numeric character escape:
//~^^^ ERROR form of character escape may only be used with characters in the range [\x00-\x7f]
- //~^^^^ ERROR unknown character escape: u
+ //~^^^^ ERROR incorrect unicode escape sequence
}
--- /dev/null
+// Copyright 2015 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.
+
+thread_local!(static FOO: Foo = Foo);
+thread_local!(static BAR: Bar = Bar(1));
+thread_local!(static BAZ: Baz = Baz);
+
+struct Foo;
+struct Bar(i32);
+struct Baz;
+
+impl Drop for Foo {
+ fn drop(&mut self) {
+ BAR.with(|_| {});
+ }
+}
+
+impl Drop for Bar {
+ fn drop(&mut self) {
+ assert_eq!(self.0, 1);
+ self.0 = 2;
+ BAZ.with(|_| {});
+ assert_eq!(self.0, 2);
+ }
+}
+
+fn main() {
+ std::thread::spawn(|| {
+ FOO.with(|_| {});
+ }).join().unwrap();
+}
.collect::<Vec<String>>();
// Concatenate the lines together using a new-line.
- write!(f, "{}", lines.connect("\n"))
+ write!(f, "{}", lines.join("\n"))
}
}
self.iter()
.map(|e| e.to_string_())
.collect::<Vec<String>>()
- .connect(", "))
+ .join(", "))
}
}