Skip to content

Commit d4c5d1a

Browse files
committed
---
yaml --- r: 235389 b: refs/heads/stable c: c044791 h: refs/heads/master i: 235387: e5631ea v: v3
1 parent c74dece commit d4c5d1a

File tree

6 files changed

+198
-91
lines changed

6 files changed

+198
-91
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 7fb8208758ceb25ed8e1beafc1b5ddb41315d32e
32+
refs/heads/stable: c044791d80ea0dc5c4b57b6030a67b69f8510239
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/libstd/thread/local.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ mod imp {
275275

276276
use cell::{Cell, UnsafeCell};
277277
use intrinsics;
278+
use ptr;
278279

279280
pub struct Key<T> {
280281
inner: UnsafeCell<Option<T>>,
@@ -327,7 +328,6 @@ mod imp {
327328
#[cfg(target_os = "linux")]
328329
unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
329330
use mem;
330-
use ptr;
331331
use libc;
332332
use sys_common::thread_local as os;
333333

@@ -394,7 +394,24 @@ mod imp {
394394
// destructor as running for this thread so calls to `get` will return
395395
// `None`.
396396
(*ptr).dtor_running.set(true);
397-
intrinsics::drop_in_place((*ptr).inner.get());
397+
398+
// The OSX implementation of TLS apparently had an odd aspect to it
399+
// where the pointer we have may be overwritten while this destructor
400+
// is running. Specifically if a TLS destructor re-accesses TLS it may
401+
// trigger a re-initialization of all TLS variables, paving over at
402+
// least some destroyed ones with initial values.
403+
//
404+
// This means that if we drop a TLS value in place on OSX that we could
405+
// revert the value to its original state halfway through the
406+
// destructor, which would be bad!
407+
//
408+
// Hence, we use `ptr::read` on OSX (to move to a "safe" location)
409+
// instead of drop_in_place.
410+
if cfg!(target_os = "macos") {
411+
ptr::read((*ptr).inner.get());
412+
} else {
413+
intrinsics::drop_in_place((*ptr).inner.get());
414+
}
398415
}
399416
}
400417

branches/stable/src/libsyntax/parse/lexer/mod.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ impl<'a> StringReader<'a> {
172172
self.span_diagnostic.span_err(sp, m)
173173
}
174174

175+
/// Suggest some help with a given span.
176+
pub fn help_span(&self, sp: Span, m: &str) {
177+
self.span_diagnostic.span_help(sp, m)
178+
}
179+
175180
/// Report a fatal error spanning [`from_pos`, `to_pos`).
176181
fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> ! {
177182
self.fatal_span(codemap::mk_sp(from_pos, to_pos), m)
@@ -182,6 +187,11 @@ impl<'a> StringReader<'a> {
182187
self.err_span(codemap::mk_sp(from_pos, to_pos), m)
183188
}
184189

190+
/// Suggest some help spanning [`from_pos`, `to_pos`).
191+
fn help_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
192+
self.help_span(codemap::mk_sp(from_pos, to_pos), m)
193+
}
194+
185195
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
186196
/// escaped character to the error message
187197
fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> ! {
@@ -728,19 +738,24 @@ impl<'a> StringReader<'a> {
728738
return match e {
729739
'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true,
730740
'x' => self.scan_byte_escape(delim, !ascii_only),
731-
'u' if self.curr_is('{') => {
732-
let valid = self.scan_unicode_escape(delim);
733-
if valid && ascii_only {
734-
self.err_span_(
735-
escaped_pos,
736-
self.last_pos,
741+
'u' => {
742+
let valid = if self.curr_is('{') {
743+
self.scan_unicode_escape(delim) && !ascii_only
744+
} else {
745+
self.err_span_(start, self.last_pos,
746+
"incorrect unicode escape sequence");
747+
self.help_span_(start, self.last_pos,
748+
"format of unicode escape sequences is `\\u{…}`");
749+
false
750+
};
751+
if ascii_only {
752+
self.err_span_(start, self.last_pos,
737753
"unicode escape sequences cannot be used as a byte or in \
738754
a byte string"
739755
);
740-
false
741-
} else {
742-
valid
743756
}
757+
valid
758+
744759
}
745760
'\n' if delim == '"' => {
746761
self.consume_whitespace();
@@ -757,16 +772,13 @@ impl<'a> StringReader<'a> {
757772
if ascii_only { "unknown byte escape" }
758773
else { "unknown character escape" },
759774
c);
760-
let sp = codemap::mk_sp(escaped_pos, last_pos);
761775
if e == '\r' {
762-
self.span_diagnostic.span_help(
763-
sp,
776+
self.help_span_(escaped_pos, last_pos,
764777
"this is an isolated carriage return; consider checking \
765778
your editor and version control settings")
766779
}
767780
if (e == '{' || e == '}') && !ascii_only {
768-
self.span_diagnostic.span_help(
769-
sp,
781+
self.help_span_(escaped_pos, last_pos,
770782
"if used in a formatting string, \
771783
curly braces are escaped with `{{` and `}}`")
772784
}
@@ -848,14 +860,12 @@ impl<'a> StringReader<'a> {
848860
valid = false;
849861
}
850862

851-
self.bump(); // past the ending }
852-
853863
if valid && (char::from_u32(accum_int).is_none() || count == 0) {
854864
self.err_span_(start_bpos, self.last_pos, "illegal unicode character escape");
855865
valid = false;
856866
}
857867

858-
868+
self.bump(); // past the ending }
859869
valid
860870
}
861871

branches/stable/src/libsyntax/parse/parser.rs

Lines changed: 108 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
6060
use ast::{Visibility, WhereClause};
6161
use ast;
6262
use ast_util::{self, AS_PREC, ident_to_path, operator_prec};
63-
use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp};
63+
use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
6464
use diagnostic;
6565
use ext::tt::macro_parser;
6666
use parse;
@@ -297,6 +297,24 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
297297
t.is_plain_ident() || *t == token::Underscore
298298
}
299299

300+
/// Information about the path to a module.
301+
pub struct ModulePath {
302+
pub name: String,
303+
pub path_exists: bool,
304+
pub result: Result<ModulePathSuccess, ModulePathError>,
305+
}
306+
307+
pub struct ModulePathSuccess {
308+
pub path: ::std::path::PathBuf,
309+
pub owns_directory: bool,
310+
}
311+
312+
pub struct ModulePathError {
313+
pub err_msg: String,
314+
pub help_msg: String,
315+
}
316+
317+
300318
impl<'a> Parser<'a> {
301319
pub fn new(sess: &'a ParseSess,
302320
cfg: ast::CrateConfig,
@@ -4859,82 +4877,104 @@ impl<'a> Parser<'a> {
48594877
self.mod_path_stack.pop().unwrap();
48604878
}
48614879

4862-
/// Read a module from a source file.
4863-
fn eval_src_mod(&mut self,
4864-
id: ast::Ident,
4865-
outer_attrs: &[ast::Attribute],
4866-
id_sp: Span)
4867-
-> PResult<(ast::Item_, Vec<ast::Attribute> )> {
4880+
pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
4881+
::attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&*d))
4882+
}
4883+
4884+
/// Returns either a path to a module, or .
4885+
pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -> ModulePath
4886+
{
4887+
let mod_string = token::get_ident(id);
4888+
let mod_name = mod_string.to_string();
4889+
let default_path_str = format!("{}.rs", mod_name);
4890+
let secondary_path_str = format!("{}/mod.rs", mod_name);
4891+
let default_path = dir_path.join(&default_path_str);
4892+
let secondary_path = dir_path.join(&secondary_path_str);
4893+
let default_exists = codemap.file_exists(&default_path);
4894+
let secondary_exists = codemap.file_exists(&secondary_path);
4895+
4896+
let result = match (default_exists, secondary_exists) {
4897+
(true, false) => Ok(ModulePathSuccess { path: default_path, owns_directory: false }),
4898+
(false, true) => Ok(ModulePathSuccess { path: secondary_path, owns_directory: true }),
4899+
(false, false) => Err(ModulePathError {
4900+
err_msg: format!("file not found for module `{}`", mod_name),
4901+
help_msg: format!("name the file either {} or {} inside the directory {:?}",
4902+
default_path_str,
4903+
secondary_path_str,
4904+
dir_path.display()),
4905+
}),
4906+
(true, true) => Err(ModulePathError {
4907+
err_msg: format!("file for module `{}` found at both {} and {}",
4908+
mod_name,
4909+
default_path_str,
4910+
secondary_path_str),
4911+
help_msg: "delete or rename one of them to remove the ambiguity".to_owned(),
4912+
}),
4913+
};
4914+
4915+
ModulePath {
4916+
name: mod_name,
4917+
path_exists: default_exists || secondary_exists,
4918+
result: result,
4919+
}
4920+
}
4921+
4922+
fn submod_path(&mut self,
4923+
id: ast::Ident,
4924+
outer_attrs: &[ast::Attribute],
4925+
id_sp: Span) -> PResult<ModulePathSuccess> {
48684926
let mut prefix = PathBuf::from(&self.sess.codemap().span_to_filename(self.span));
48694927
prefix.pop();
48704928
let mut dir_path = prefix;
48714929
for part in &self.mod_path_stack {
48724930
dir_path.push(&**part);
48734931
}
4874-
let mod_string = token::get_ident(id);
4875-
let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
4876-
outer_attrs, "path") {
4877-
Some(d) => (dir_path.join(&*d), true),
4878-
None => {
4879-
let mod_name = mod_string.to_string();
4880-
let default_path_str = format!("{}.rs", mod_name);
4881-
let secondary_path_str = format!("{}/mod.rs", mod_name);
4882-
let default_path = dir_path.join(&default_path_str[..]);
4883-
let secondary_path = dir_path.join(&secondary_path_str[..]);
4884-
let default_exists = self.sess.codemap().file_exists(&default_path);
4885-
let secondary_exists = self.sess.codemap().file_exists(&secondary_path);
4886-
4887-
if !self.owns_directory {
4888-
self.span_err(id_sp,
4889-
"cannot declare a new module at this location");
4890-
let this_module = match self.mod_path_stack.last() {
4891-
Some(name) => name.to_string(),
4892-
None => self.root_module_name.as_ref().unwrap().clone(),
4893-
};
4894-
self.span_note(id_sp,
4895-
&format!("maybe move this module `{0}` \
4896-
to its own directory via \
4897-
`{0}/mod.rs`",
4898-
this_module));
4899-
if default_exists || secondary_exists {
4900-
self.span_note(id_sp,
4901-
&format!("... or maybe `use` the module \
4902-
`{}` instead of possibly \
4903-
redeclaring it",
4904-
mod_name));
4905-
}
4906-
self.abort_if_errors();
4907-
}
49084932

4909-
match (default_exists, secondary_exists) {
4910-
(true, false) => (default_path, false),
4911-
(false, true) => (secondary_path, true),
4912-
(false, false) => {
4913-
return Err(self.span_fatal_help(id_sp,
4914-
&format!("file not found for module `{}`",
4915-
mod_name),
4916-
&format!("name the file either {} or {} inside \
4917-
the directory {:?}",
4918-
default_path_str,
4919-
secondary_path_str,
4920-
dir_path.display())));
4921-
}
4922-
(true, true) => {
4923-
return Err(self.span_fatal_help(
4924-
id_sp,
4925-
&format!("file for module `{}` found at both {} \
4926-
and {}",
4927-
mod_name,
4928-
default_path_str,
4929-
secondary_path_str),
4930-
"delete or rename one of them to remove the ambiguity"));
4931-
}
4932-
}
4933+
if let Some(p) = Parser::submod_path_from_attr(outer_attrs, &dir_path) {
4934+
return Ok(ModulePathSuccess { path: p, owns_directory: true });
4935+
}
4936+
4937+
let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap());
4938+
4939+
if !self.owns_directory {
4940+
self.span_err(id_sp, "cannot declare a new module at this location");
4941+
let this_module = match self.mod_path_stack.last() {
4942+
Some(name) => name.to_string(),
4943+
None => self.root_module_name.as_ref().unwrap().clone(),
4944+
};
4945+
self.span_note(id_sp,
4946+
&format!("maybe move this module `{0}` to its own directory \
4947+
via `{0}/mod.rs`",
4948+
this_module));
4949+
if paths.path_exists {
4950+
self.span_note(id_sp,
4951+
&format!("... or maybe `use` the module `{}` instead \
4952+
of possibly redeclaring it",
4953+
paths.name));
49334954
}
4934-
};
4955+
self.abort_if_errors();
4956+
}
4957+
4958+
match paths.result {
4959+
Ok(succ) => Ok(succ),
4960+
Err(err) => Err(self.span_fatal_help(id_sp, &err.err_msg, &err.help_msg)),
4961+
}
4962+
}
49354963

4936-
self.eval_src_mod_from_path(file_path, owns_directory,
4937-
mod_string.to_string(), id_sp)
4964+
/// Read a module from a source file.
4965+
fn eval_src_mod(&mut self,
4966+
id: ast::Ident,
4967+
outer_attrs: &[ast::Attribute],
4968+
id_sp: Span)
4969+
-> PResult<(ast::Item_, Vec<ast::Attribute> )> {
4970+
let ModulePathSuccess { path, owns_directory } = try!(self.submod_path(id,
4971+
outer_attrs,
4972+
id_sp));
4973+
4974+
self.eval_src_mod_from_path(path,
4975+
owns_directory,
4976+
token::get_ident(id).to_string(),
4977+
id_sp)
49384978
}
49394979

49404980
fn eval_src_mod_from_path(&mut self,

branches/stable/src/test/parse-fail/issue-23620-invalid-escapes.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ fn main() {
1616
//~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
1717

1818
let _ = b'\u';
19-
//~^ ERROR unknown byte escape: u
19+
//~^ ERROR incorrect unicode escape sequence
20+
//~^^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
2021

2122
let _ = b'\x5';
2223
//~^ ERROR numeric character escape is too short
@@ -35,11 +36,12 @@ fn main() {
3536
let _ = b"\u{a4a4} \xf \u";
3637
//~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
3738
//~^^ ERROR illegal character in numeric character escape:
38-
//~^^^ ERROR unknown byte escape: u
39+
//~^^^ ERROR incorrect unicode escape sequence
40+
//~^^^^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
3941

4042
let _ = "\u{ffffff} \xf \u";
4143
//~^ ERROR illegal unicode character escape
4244
//~^^ ERROR illegal character in numeric character escape:
4345
//~^^^ ERROR form of character escape may only be used with characters in the range [\x00-\x7f]
44-
//~^^^^ ERROR unknown character escape: u
46+
//~^^^^ ERROR incorrect unicode escape sequence
4547
}

0 commit comments

Comments
 (0)