Skip to content

Commit 9a6a72b

Browse files
committed
Merge branch 'master' of https://github.com/rust-lang/rust
2 parents b3f61ce + 0e77277 commit 9a6a72b

File tree

47 files changed

+391
-223
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+391
-223
lines changed

src/bootstrap/bin/rustc.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ fn main() {
205205
}
206206
}
207207
}
208+
209+
if target.contains("pc-windows-msvc") {
210+
cmd.arg("-Z").arg("unstable-options");
211+
cmd.arg("-C").arg("target-feature=+crt-static");
212+
}
208213
}
209214

210215
if verbose > 1 {

src/bootstrap/bootstrap.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ def download_stage0(self):
173173
if not os.path.exists(tarball):
174174
get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
175175
unpack(tarball, self.bin_root(), match="rustc", verbose=self.verbose)
176+
self.fix_executable(self.bin_root() + "/bin/rustc")
177+
self.fix_executable(self.bin_root() + "/bin/rustdoc")
176178
with open(self.rustc_stamp(), 'w') as f:
177179
f.write(self.stage0_rustc_date())
178180

@@ -185,9 +187,63 @@ def download_stage0(self):
185187
if not os.path.exists(tarball):
186188
get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
187189
unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose)
190+
self.fix_executable(self.bin_root() + "/bin/cargo")
188191
with open(self.cargo_stamp(), 'w') as f:
189192
f.write(self.stage0_cargo_rev())
190193

194+
def fix_executable(self, fname):
195+
# If we're on NixOS we need to change the path to the dynamic loader
196+
197+
default_encoding = sys.getdefaultencoding()
198+
try:
199+
ostype = subprocess.check_output(['uname', '-s']).strip().decode(default_encoding)
200+
except (subprocess.CalledProcessError, WindowsError):
201+
return
202+
203+
if ostype != "Linux":
204+
return
205+
206+
if not os.path.exists("/etc/NIXOS"):
207+
return
208+
if os.path.exists("/lib"):
209+
return
210+
211+
# At this point we're pretty sure the user is running NixOS
212+
print("info: you seem to be running NixOS. Attempting to patch " + fname)
213+
214+
try:
215+
interpreter = subprocess.check_output(["patchelf", "--print-interpreter", fname])
216+
interpreter = interpreter.strip().decode(default_encoding)
217+
except subprocess.CalledProcessError as e:
218+
print("warning: failed to call patchelf: %s" % e)
219+
return
220+
221+
loader = interpreter.split("/")[-1]
222+
223+
try:
224+
ldd_output = subprocess.check_output(['ldd', '/run/current-system/sw/bin/sh'])
225+
ldd_output = ldd_output.strip().decode(default_encoding)
226+
except subprocess.CalledProcessError as e:
227+
print("warning: unable to call ldd: %s" % e)
228+
return
229+
230+
for line in ldd_output.splitlines():
231+
libname = line.split()[0]
232+
if libname.endswith(loader):
233+
loader_path = libname[:len(libname) - len(loader)]
234+
break
235+
else:
236+
print("warning: unable to find the path to the dynamic linker")
237+
return
238+
239+
correct_interpreter = loader_path + loader
240+
241+
try:
242+
subprocess.check_output(["patchelf", "--set-interpreter", correct_interpreter, fname])
243+
except subprocess.CalledProcessError as e:
244+
print("warning: failed to call patchelf: %s" % e)
245+
return
246+
191247
def stage0_cargo_rev(self):
192248
return self._cargo_rev
193249

src/bootstrap/native.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ pub fn llvm(build: &Build, target: &str) {
9999
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
100100
.define("LLVM_DEFAULT_TARGET_TRIPLE", target);
101101

102+
if target.contains("msvc") {
103+
cfg.define("LLVM_USE_CRT_DEBUG", "MT");
104+
cfg.define("LLVM_USE_CRT_RELEASE", "MT");
105+
cfg.define("LLVM_USE_CRT_RELWITHDEBINFO", "MT");
106+
}
107+
102108
if target.starts_with("i686") {
103109
cfg.define("LLVM_BUILD_32_BITS", "ON");
104110
}

src/doc/book/src/procedural-macros.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ So this is where quotes comes in. The `ast` argument is a struct that gives us
169169
a representation of our type (which can be either a `struct` or an `enum`).
170170
Check out the [docs](https://docs.rs/syn/0.10.5/syn/struct.MacroInput.html),
171171
there is some useful information there. We are able to get the name of the
172-
type using `ast.ident`. The `quote!` macro let's us write up the Rust code
172+
type using `ast.ident`. The `quote!` macro lets us write up the Rust code
173173
that we wish to return and convert it into `Tokens`. `quote!` let's us use some
174174
really cool templating mechanics; we simply write `#name` and `quote!` will
175175
replace it with the variable named `name`. You can even do some repetition

src/libcollections/string.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,17 +1250,17 @@ impl String {
12501250
self.len() == 0
12511251
}
12521252

1253-
/// Divide one string into two at an index.
1253+
/// Splits the string into two at the given index.
12541254
///
1255-
/// The argument, `mid`, should be a byte offset from the start of the string. It must also
1256-
/// be on the boundary of a UTF-8 code point.
1255+
/// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and
1256+
/// the returned `String` contains bytes `[at, len)`. `at` must be on the
1257+
/// boundary of a UTF-8 code point.
12571258
///
1258-
/// The two strings returned go from the start of the string to `mid`, and from `mid` to the end
1259-
/// of the string.
1259+
/// Note that the capacity of `self` does not change.
12601260
///
12611261
/// # Panics
12621262
///
1263-
/// Panics if `mid` is not on a `UTF-8` code point boundary, or if it is beyond the last
1263+
/// Panics if `at` is not on a `UTF-8` code point boundary, or if it is beyond the last
12641264
/// code point of the string.
12651265
///
12661266
/// # Examples
@@ -1275,9 +1275,9 @@ impl String {
12751275
/// ```
12761276
#[inline]
12771277
#[stable(feature = "string_split_off", since = "1.16.0")]
1278-
pub fn split_off(&mut self, mid: usize) -> String {
1279-
assert!(self.is_char_boundary(mid));
1280-
let other = self.vec.split_off(mid);
1278+
pub fn split_off(&mut self, at: usize) -> String {
1279+
assert!(self.is_char_boundary(at));
1280+
let other = self.vec.split_off(at);
12811281
unsafe { String::from_utf8_unchecked(other) }
12821282
}
12831283

src/libcore/iter/iterator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,12 +1603,12 @@ pub trait Iterator {
16031603
let mut i = self.len();
16041604

16051605
while let Some(v) = self.next_back() {
1606-
if predicate(v) {
1607-
return Some(i - 1);
1608-
}
16091606
// No need for an overflow check here, because `ExactSizeIterator`
16101607
// implies that the number of elements fits into a `usize`.
16111608
i -= 1;
1609+
if predicate(v) {
1610+
return Some(i);
1611+
}
16121612
}
16131613
None
16141614
}

src/librustc/dep_graph/dep_node.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,37 @@ pub enum DepNode<D: Clone + Debug> {
131131
// which would yield an overly conservative dep-graph.
132132
TraitItems(D),
133133
ReprHints(D),
134-
TraitSelect(Vec<D>),
134+
135+
// Trait selection cache is a little funny. Given a trait
136+
// reference like `Foo: SomeTrait<Bar>`, there could be
137+
// arbitrarily many def-ids to map on in there (e.g., `Foo`,
138+
// `SomeTrait`, `Bar`). We could have a vector of them, but it
139+
// requires heap-allocation, and trait sel in general can be a
140+
// surprisingly hot path. So instead we pick two def-ids: the
141+
// trait def-id, and the first def-id in the input types. If there
142+
// is no def-id in the input types, then we use the trait def-id
143+
// again. So for example:
144+
//
145+
// - `i32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
146+
// - `u32: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
147+
// - `Clone: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Clone }`
148+
// - `Vec<i32>: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: Vec }`
149+
// - `String: Clone` -> `TraitSelect { trait_def_id: Clone, self_def_id: String }`
150+
// - `Foo: Trait<Bar>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
151+
// - `Foo: Trait<i32>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
152+
// - `(Foo, Bar): Trait` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
153+
// - `i32: Trait<Foo>` -> `TraitSelect { trait_def_id: Trait, self_def_id: Foo }`
154+
//
155+
// You can see that we map many trait refs to the same
156+
// trait-select node. This is not a problem, it just means
157+
// imprecision in our dep-graph tracking. The important thing is
158+
// that for any given trait-ref, we always map to the **same**
159+
// trait-select node.
160+
TraitSelect { trait_def_id: D, input_def_id: D },
161+
162+
// For proj. cache, we just keep a list of all def-ids, since it is
163+
// not a hotspot.
164+
ProjectionCache { def_ids: Vec<D> },
135165
}
136166

137167
impl<D: Clone + Debug> DepNode<D> {
@@ -236,9 +266,17 @@ impl<D: Clone + Debug> DepNode<D> {
236266
TraitImpls(ref d) => op(d).map(TraitImpls),
237267
TraitItems(ref d) => op(d).map(TraitItems),
238268
ReprHints(ref d) => op(d).map(ReprHints),
239-
TraitSelect(ref type_ds) => {
240-
let type_ds = try_opt!(type_ds.iter().map(|d| op(d)).collect());
241-
Some(TraitSelect(type_ds))
269+
TraitSelect { ref trait_def_id, ref input_def_id } => {
270+
op(trait_def_id).and_then(|trait_def_id| {
271+
op(input_def_id).and_then(|input_def_id| {
272+
Some(TraitSelect { trait_def_id: trait_def_id,
273+
input_def_id: input_def_id })
274+
})
275+
})
276+
}
277+
ProjectionCache { ref def_ids } => {
278+
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
279+
def_ids.map(|d| ProjectionCache { def_ids: d })
242280
}
243281
}
244282
}

src/librustc/hir/def.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,45 @@ pub enum Def {
5959
Err,
6060
}
6161

62-
/// The result of resolving a path.
63-
/// Before type checking completes, `depth` represents the number of
64-
/// trailing segments which are yet unresolved. Afterwards, if there
65-
/// were no errors, all paths should be fully resolved, with `depth`
66-
/// set to `0` and `base_def` representing the final resolution.
67-
///
62+
/// The result of resolving a path before lowering to HIR.
63+
/// `base_def` is definition of resolved part of the
64+
/// path, `unresolved_segments` is the number of unresolved
65+
/// segments.
6866
/// module::Type::AssocX::AssocY::MethodOrAssocType
6967
/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70-
/// base_def depth = 3
68+
/// base_def unresolved_segments = 3
7169
///
7270
/// <T as Trait>::AssocX::AssocY::MethodOrAssocType
7371
/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
74-
/// base_def depth = 2
72+
/// base_def unresolved_segments = 2
7573
#[derive(Copy, Clone, Debug)]
7674
pub struct PathResolution {
77-
pub base_def: Def,
78-
pub depth: usize
75+
base_def: Def,
76+
unresolved_segments: usize,
7977
}
8078

8179
impl PathResolution {
82-
pub fn new(def: Def) -> PathResolution {
83-
PathResolution { base_def: def, depth: 0 }
80+
pub fn new(def: Def) -> Self {
81+
PathResolution { base_def: def, unresolved_segments: 0 }
82+
}
83+
84+
pub fn with_unresolved_segments(def: Def, mut unresolved_segments: usize) -> Self {
85+
if def == Def::Err { unresolved_segments = 0 }
86+
PathResolution { base_def: def, unresolved_segments: unresolved_segments }
87+
}
88+
89+
#[inline]
90+
pub fn base_def(&self) -> Def {
91+
self.base_def
92+
}
93+
94+
#[inline]
95+
pub fn unresolved_segments(&self) -> usize {
96+
self.unresolved_segments
8497
}
8598

8699
pub fn kind_name(&self) -> &'static str {
87-
if self.depth != 0 {
100+
if self.unresolved_segments != 0 {
88101
"associated item"
89102
} else {
90103
self.base_def.kind_name()

src/librustc/hir/lowering.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ impl<'a> LoweringContext<'a> {
217217

218218
fn expect_full_def(&mut self, id: NodeId) -> Def {
219219
self.resolver.get_resolution(id).map_or(Def::Err, |pr| {
220-
if pr.depth != 0 {
220+
if pr.unresolved_segments() != 0 {
221221
bug!("path not fully resolved: {:?}", pr);
222222
}
223-
pr.base_def
223+
pr.base_def()
224224
})
225225
}
226226

@@ -421,9 +421,9 @@ impl<'a> LoweringContext<'a> {
421421
let resolution = self.resolver.get_resolution(id)
422422
.unwrap_or(PathResolution::new(Def::Err));
423423

424-
let proj_start = p.segments.len() - resolution.depth;
424+
let proj_start = p.segments.len() - resolution.unresolved_segments();
425425
let path = P(hir::Path {
426-
def: resolution.base_def,
426+
def: resolution.base_def(),
427427
segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
428428
let param_mode = match (qself_position, param_mode) {
429429
(Some(j), ParamMode::Optional) if i < j => {
@@ -443,7 +443,7 @@ impl<'a> LoweringContext<'a> {
443443
index: this.def_key(def_id).parent.expect("missing parent")
444444
}
445445
};
446-
let type_def_id = match resolution.base_def {
446+
let type_def_id = match resolution.base_def() {
447447
Def::AssociatedTy(def_id) if i + 2 == proj_start => {
448448
Some(parent_def_id(self, def_id))
449449
}
@@ -474,7 +474,7 @@ impl<'a> LoweringContext<'a> {
474474

475475
// Simple case, either no projections, or only fully-qualified.
476476
// E.g. `std::mem::size_of` or `<I as Iterator>::Item`.
477-
if resolution.depth == 0 {
477+
if resolution.unresolved_segments() == 0 {
478478
return hir::QPath::Resolved(qself, path);
479479
}
480480

@@ -749,7 +749,7 @@ impl<'a> LoweringContext<'a> {
749749
bound_pred.bound_lifetimes.is_empty() => {
750750
if let Some(Def::TyParam(def_id)) =
751751
self.resolver.get_resolution(bound_pred.bounded_ty.id)
752-
.map(|d| d.base_def) {
752+
.map(|d| d.base_def()) {
753753
if let Some(node_id) =
754754
self.resolver.definitions().as_local_node_id(def_id) {
755755
for ty_param in &g.ty_params {
@@ -1295,7 +1295,7 @@ impl<'a> LoweringContext<'a> {
12951295
PatKind::Wild => hir::PatKind::Wild,
12961296
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
12971297
self.with_parent_def(p.id, |this| {
1298-
match this.resolver.get_resolution(p.id).map(|d| d.base_def) {
1298+
match this.resolver.get_resolution(p.id).map(|d| d.base_def()) {
12991299
// `None` can occur in body-less function signatures
13001300
def @ None | def @ Some(Def::Local(_)) => {
13011301
let def_id = def.map(|d| d.def_id()).unwrap_or_else(|| {

src/librustc/mir/mod.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,12 @@ pub enum StatementKind<'tcx> {
777777
/// End the current live range for the storage of the local.
778778
StorageDead(Lvalue<'tcx>),
779779

780+
InlineAsm {
781+
asm: InlineAsm,
782+
outputs: Vec<Lvalue<'tcx>>,
783+
inputs: Vec<Operand<'tcx>>
784+
},
785+
780786
/// No-op. Useful for deleting instructions without affecting statement indices.
781787
Nop,
782788
}
@@ -790,7 +796,10 @@ impl<'tcx> Debug for Statement<'tcx> {
790796
StorageDead(ref lv) => write!(fmt, "StorageDead({:?})", lv),
791797
SetDiscriminant{lvalue: ref lv, variant_index: index} => {
792798
write!(fmt, "discriminant({:?}) = {:?}", lv, index)
793-
}
799+
},
800+
InlineAsm { ref asm, ref outputs, ref inputs } => {
801+
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
802+
},
794803
Nop => write!(fmt, "nop"),
795804
}
796805
}
@@ -1004,12 +1013,6 @@ pub enum Rvalue<'tcx> {
10041013
/// that `Foo` has a destructor. These rvalues can be optimized
10051014
/// away after type-checking and before lowering.
10061015
Aggregate(AggregateKind<'tcx>, Vec<Operand<'tcx>>),
1007-
1008-
InlineAsm {
1009-
asm: InlineAsm,
1010-
outputs: Vec<Lvalue<'tcx>>,
1011-
inputs: Vec<Operand<'tcx>>
1012-
}
10131016
}
10141017

10151018
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
@@ -1111,10 +1114,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
11111114
UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a),
11121115
Discriminant(ref lval) => write!(fmt, "discriminant({:?})", lval),
11131116
Box(ref t) => write!(fmt, "Box({:?})", t),
1114-
InlineAsm { ref asm, ref outputs, ref inputs } => {
1115-
write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
1116-
}
1117-
11181117
Ref(_, borrow_kind, ref lv) => {
11191118
let kind_str = match borrow_kind {
11201119
BorrowKind::Shared => "",

src/librustc/mir/tcx.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ impl<'tcx> Rvalue<'tcx> {
207207
}
208208
}
209209
}
210-
Rvalue::InlineAsm { .. } => None
211210
}
212211
}
213212
}

0 commit comments

Comments
 (0)