Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
resolve: Bind primitive types to items in libcore
  • Loading branch information
petrochenkov committed Mar 21, 2016
commit 25271258814aaee3d37a9a52deffc7cc356da1f1
3 changes: 2 additions & 1 deletion src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#![feature(pattern)]
#![feature(placement_in)]
#![feature(placement_new_protocol)]
#![cfg_attr(not(stage0), feature(primitive_type))]
#![feature(shared)]
#![feature(slice_patterns)]
#![feature(staged_api)]
Expand All @@ -56,7 +57,6 @@
#![feature(unique)]
#![feature(unsafe_no_drop_flag)]
#![cfg_attr(test, feature(rand, test))]

#![no_std]

extern crate rustc_unicode;
Expand Down Expand Up @@ -99,6 +99,7 @@ pub mod fmt;
pub mod linked_list;
pub mod range;
pub mod slice;
#[cfg_attr(not(stage0), primitive_type)]
pub mod str;
pub mod string;
pub mod vec;
Expand Down
1 change: 0 additions & 1 deletion src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use num::flt2dec;
use ops::Deref;
use result;
use slice;
use str;

#[unstable(feature = "fmt_flags_align", issue = "27726")]
/// Possible alignments returned by `Formatter::align`
Expand Down
1 change: 0 additions & 1 deletion src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use prelude::v1::*;
use fmt;
use num::Zero;
use ops::{Div, Rem, Sub};
use str;
use slice;
use ptr;
use mem;
Expand Down
29 changes: 29 additions & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![cfg_attr(not(stage0), deny(warnings))]
// This is a temporary way to use libcore's prelude in libcore
#![cfg_attr(not(stage0), feature(primitive_type, local_prelude))]
#![cfg_attr(not(stage0), local_prelude)]

#![feature(allow_internal_unstable)]
#![feature(associated_type_defaults)]
Expand Down Expand Up @@ -93,19 +96,43 @@ mod int_macros;
#[macro_use]
mod uint_macros;

/// The boolean type.
#[cfg(not(stage0))]
#[stable(feature = "core_primitive_types", since = "1.9.0")]
#[allow(non_camel_case_types)]
#[primitive_type]
pub type bool = bool;

/// The boolean type.
#[cfg(stage0)]
#[stable(feature = "core_primitive_types", since = "1.9.0")]
pub mod bool {}

#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/isize.rs"] pub mod isize;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/i8.rs"] pub mod i8;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/i16.rs"] pub mod i16;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/i32.rs"] pub mod i32;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/i64.rs"] pub mod i64;

#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/usize.rs"] pub mod usize;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/u8.rs"] pub mod u8;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/u16.rs"] pub mod u16;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/u32.rs"] pub mod u32;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/u64.rs"] pub mod u64;

#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/f32.rs"] pub mod f32;
#[cfg_attr(not(stage0), primitive_type)]
#[path = "num/f64.rs"] pub mod f64;

#[macro_use]
Expand Down Expand Up @@ -138,6 +165,7 @@ pub mod any;
pub mod array;
pub mod sync;
pub mod cell;
#[cfg_attr(not(stage0), primitive_type)]
pub mod char;
pub mod panicking;
pub mod iter;
Expand All @@ -146,6 +174,7 @@ pub mod raw;
pub mod result;

pub mod slice;
#[cfg_attr(not(stage0), primitive_type)]
pub mod str;
pub mod hash;
pub mod fmt;
Expand Down
1 change: 0 additions & 1 deletion src/libcore/num/dec2flt/rawfp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
//! take the universally-correct slow path (Algorithm M) for very small and very large numbers.
//! That algorithm needs only next_float() which does handle subnormals and zeros.
use prelude::v1::*;
use u32;
use cmp::Ordering::{Less, Equal, Greater};
use ops::{Mul, Div, Neg};
use fmt::{Debug, LowerExp};
Expand Down
1 change: 0 additions & 1 deletion src/libcore/num/flt2dec/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

use prelude::v1::*;

use {f32, f64};
use num::{Float, FpCategory};

/// Decoded unsigned finite value, such that:
Expand Down
1 change: 0 additions & 1 deletion src/libcore/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ functions.
issue = "0")]

use prelude::v1::*;
use i16;
pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};

pub mod estimator;
Expand Down
5 changes: 5 additions & 0 deletions src/libcore/prelude/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//! same manner as the standard library's prelude.

#![stable(feature = "core_prelude", since = "1.4.0")]
#![cfg_attr(not(stage0), no_implicit_prelude)]

// Reexported core operators
#[stable(feature = "core_prelude", since = "1.4.0")]
Expand Down Expand Up @@ -51,3 +52,7 @@
#[doc(no_inline)] pub use str::StrExt;
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)] pub use char::CharExt;

#[stable(feature = "core_primitive_types", since = "1.9.0")]
#[doc(no_inline)] pub use {u8, u16, u32, u64, usize, i8, i16, i32, i64, isize,
f32, f64, bool, char, str};
1 change: 0 additions & 1 deletion src/libcore/str/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use prelude::v1::*;

use cmp;
use fmt;
use usize;

// Pattern

Expand Down
1 change: 1 addition & 0 deletions src/libcoretest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#![feature(libc)]
#![feature(nonzero)]
#![feature(peekable_is_empty)]
#![feature(primitive_type)]
#![feature(ptr_as_ref)]
#![feature(rand)]
#![feature(raw)]
Expand Down
2 changes: 1 addition & 1 deletion src/libcoretest/num/flt2dec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

use std::prelude::v1::*;
use std::{str, mem, i16, f32, f64, fmt};
use std::{mem, fmt};
use std::__rand as rand;
use rand::{Rand, XorShiftRng};
use rand::distributions::{IndependentSample, Range};
Expand Down
1 change: 0 additions & 1 deletion src/libcoretest/num/flt2dec/strategy/dragon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.

use std::prelude::v1::*;
use std::{i16, f64};
use super::super::*;
use core::num::flt2dec::*;
use core::num::bignum::Big32x40 as Big;
Expand Down
1 change: 1 addition & 0 deletions src/libcoretest/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ mod uint_macros;

mod u8;
mod u16;
#[primitive_type]
mod u32;
mod u64;

Expand Down
10 changes: 7 additions & 3 deletions src/librustc/middle/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,25 +121,29 @@ impl Def {
}
}

pub fn def_id(&self) -> DefId {
pub fn opt_def_id(&self) -> Option<DefId> {
match *self {
Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) |
Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) |
Def::TyParam(_, _, id, _) | Def::Struct(id) | Def::Trait(id) |
Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) |
Def::Local(id, _) | Def::Upvar(id, _, _, _) => {
id
Some(id)
}

Def::Label(..) |
Def::PrimTy(..) |
Def::SelfTy(..) |
Def::Err => {
panic!("attempted .def_id() on invalid def: {:?}", self)
None
}
}
}

pub fn def_id(&self) -> DefId {
self.opt_def_id().expect(&format!("attempted .def_id() on invalid def: {:?}", self))
}

pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> {
match *self {
Def::Variant(enum_id, var_id) => {
Expand Down
9 changes: 9 additions & 0 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
} else {
DefModifiers::empty()
} | DefModifiers::IMPORTABLE;
if item.attrs.iter().any(|attr| attr.name() == "primitive_type") {
if let Some(def_id) = self.ast_map.opt_local_def_id(item.id) {
self.resolver.primitive_type_items.insert(def_id);
}
}

match item.node {
ItemUse(ref view_path) => {
Expand Down Expand Up @@ -463,6 +468,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
if new_parent.is_normal() {
modifiers = modifiers | DefModifiers::IMPORTABLE;
}
if self.session.cstore.item_attrs(def.def_id()).
iter().any(|attr| attr.name() == "primitive_type") {
self.resolver.primitive_type_items.insert(def.def_id());
}

match def {
Def::Mod(_) | Def::ForeignMod(_) | Def::Enum(..) => {
Expand Down
73 changes: 32 additions & 41 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use rustc::middle::def_id::DefId;
use rustc::middle::pat_util::pat_bindings;
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, FnvHashMap};
use rustc::util::nodemap::{DefIdSet, NodeMap, FnvHashMap};

use syntax::ast::{self, FloatTy};
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
Expand Down Expand Up @@ -1082,6 +1082,7 @@ pub struct Resolver<'a, 'tcx: 'a> {
freevars_seen: NodeMap<NodeMap<usize>>,
export_map: ExportMap,
trait_map: TraitMap,
primitive_type_items: DefIdSet,

// Whether or not to print error messages. Can be set to true
// when getting additional info for error message suggestions,
Expand Down Expand Up @@ -1172,6 +1173,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
trait_map: NodeMap(),
used_imports: HashSet::new(),
used_crates: HashSet::new(),
primitive_type_items: DefIdSet(),

emit_errors: true,
make_glob_map: make_glob_map == MakeGlobMap::Yes,
Expand Down Expand Up @@ -2596,14 +2598,38 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolveAttempt(resolution)
}

/// Skips `path_depth` trailing segments, which is also reflected in the
/// returned value. See `middle::def::PathResolution` for more info.
pub fn resolve_path(&mut self,
id: NodeId,
path: &Path,
path_depth: usize,
namespace: Namespace)
-> Option<PathResolution> {
let resolution = self.resolve_path_noprim(id, path, path_depth, namespace);
// Check if the resolution is a #[primitive_type] item in type namespace,
// replace that item with a primitive type with the same name.
if let Some(PathResolution{base_def, ..}) = resolution {
if let Some(def_id) = base_def.opt_def_id() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to check for Def::Err explicitly instead of introducing the method opt_def_id.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Def::Err and Def::SelfTy, but anyway, def kind doesn't matter here, only the presence of def_id.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.

if namespace == TypeNS && self.primitive_type_items.contains(&def_id) {
let name = &path.segments[path.segments.len() - path_depth - 1]
.identifier.unhygienic_name;
if let Some(prim_ty) = self.primitive_type_table.primitive_types.get(name) {
return Some(PathResolution::new(Def::PrimTy(*prim_ty), path_depth))
}
}
}
}

resolution
}

/// Skips `path_depth` trailing segments, which is also reflected in the
/// returned value. See `middle::def::PathResolution` for more info.
pub fn resolve_path_noprim(&mut self,
id: NodeId,
path: &Path,
path_depth: usize,
namespace: Namespace)
-> Option<PathResolution> {
let span = path.span;
let segments = &path.segments[..path.segments.len() - path_depth];

Expand All @@ -2616,37 +2642,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {

// Try to find a path to an item in a module.
let last_ident = segments.last().unwrap().identifier;
// Resolve a single identifier with fallback to primitive types
let resolve_identifier_with_fallback = |this: &mut Self, record_used| {
let def = this.resolve_identifier(last_ident, namespace, record_used);
match def {
None | Some(LocalDef{def: Def::Mod(..), ..}) if namespace == TypeNS =>
this.primitive_type_table
.primitive_types
.get(&last_ident.unhygienic_name)
.map_or(def, |prim_ty| Some(LocalDef::from_def(Def::PrimTy(*prim_ty)))),
_ => def
}
};

if segments.len() == 1 {
// In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
// don't report an error right away, but try to fallback to a primitive type.
// So, we are still able to successfully resolve something like
//
// use std::u8; // bring module u8 in scope
// fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
// u8::max_value() // OK, resolves to associated function <u8>::max_value,
// // not to non-existent std::u8::max_value
// }
//
// Such behavior is required for backward compatibility.
// The same fallback is used when `a` resolves to nothing.
let unqualified_def = resolve_identifier_with_fallback(self, true);
let unqualified_def = self.resolve_identifier(last_ident, namespace, true);
return unqualified_def.and_then(|def| self.adjust_local_def(def, span)).map(mk_res);
}

let unqualified_def = resolve_identifier_with_fallback(self, false);
let unqualified_def = self.resolve_identifier(last_ident, namespace, false);
let def = self.resolve_module_relative_path(span, segments, namespace);
match (def, unqualified_def) {
(Some(d), Some(ref ud)) if d == ud.def => {
Expand Down Expand Up @@ -2932,17 +2933,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
span: Span,
name_path: &[ast::Name])
-> Option<Module<'a>> {
let last_name = name_path.last().unwrap();

if name_path.len() == 1 {
match this.primitive_type_table.primitive_types.get(last_name) {
Some(_) => None,
None => this.current_module.resolve_name(*last_name, TypeNS, true).success()
.and_then(NameBinding::module)
}
} else {
this.resolve_module_path(&name_path, UseLexicalScope, span).success()
}
this.resolve_module_path(&name_path, UseLexicalScope, span).success()
}

fn is_static_method(this: &Resolver, did: DefId) -> bool {
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_unicode/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@

#![feature(core_char_ext)]
#![feature(lang_items)]
#![cfg_attr(not(stage0), feature(primitive_type))]
#![feature(staged_api)]

mod tables;
mod u_str;
#[cfg_attr(not(stage0), primitive_type)]
pub mod char;

#[allow(deprecated)]
Expand Down
1 change: 0 additions & 1 deletion src/libstd/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,7 +1461,6 @@ mod tests {
use io::{ErrorKind, SeekFrom};
use path::Path;
use rand::{StdRng, Rng};
use str;
use sys_common::io::test::{TempDir, tmpdir};

#[cfg(windows)]
Expand Down
Loading