Skip to content

Rollup of 5 pull requests #40785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Changes from all commits
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
17 changes: 5 additions & 12 deletions src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
@@ -160,11 +160,8 @@ class RustBuild(object):
def download_stage0(self):
cache_dst = os.path.join(self.build_dir, "cache")
rustc_cache = os.path.join(cache_dst, self.stage0_rustc_date())
cargo_cache = os.path.join(cache_dst, self.stage0_cargo_rev())
if not os.path.exists(rustc_cache):
os.makedirs(rustc_cache)
if not os.path.exists(cargo_cache):
os.makedirs(cargo_cache)

if self.rustc().startswith(self.bin_root()) and \
(not os.path.exists(self.rustc()) or self.rustc_out_of_date()):
@@ -195,15 +192,15 @@ def download_stage0(self):
if self.cargo().startswith(self.bin_root()) and \
(not os.path.exists(self.cargo()) or self.cargo_out_of_date()):
self.print_what_it_means_to_bootstrap()
filename = "cargo-nightly-{}.tar.gz".format(self.build)
url = "https://s3.amazonaws.com/rust-lang-ci/cargo-builds/" + self.stage0_cargo_rev()
tarball = os.path.join(cargo_cache, filename)
filename = "cargo-{}-{}.tar.gz".format(channel, self.build)
url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date()
tarball = os.path.join(rustc_cache, filename)
if not os.path.exists(tarball):
get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose)
self.fix_executable(self.bin_root() + "/bin/cargo")
with open(self.cargo_stamp(), 'w') as f:
f.write(self.stage0_cargo_rev())
f.write(self.stage0_rustc_date())

def fix_executable(self, fname):
# If we're on NixOS we need to change the path to the dynamic loader
@@ -258,9 +255,6 @@ def fix_executable(self, fname):
print("warning: failed to call patchelf: %s" % e)
return

def stage0_cargo_rev(self):
return self._cargo_rev

def stage0_rustc_date(self):
return self._rustc_date

@@ -283,7 +277,7 @@ def cargo_out_of_date(self):
if not os.path.exists(self.cargo_stamp()) or self.clean:
return True
with open(self.cargo_stamp(), 'r') as f:
return self.stage0_cargo_rev() != f.read()
return self.stage0_rustc_date() != f.read()

def bin_root(self):
return os.path.join(self.build_dir, self.build, "stage0")
@@ -578,7 +572,6 @@ def bootstrap():

data = stage0_data(rb.rust_root)
rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1)
rb._cargo_rev = data['cargo']

# Fetch/build the bootstrap
rb.build = rb.build_triple()
2 changes: 1 addition & 1 deletion src/bootstrap/channel.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ use build_helper::output;
use Build;

// The version number
pub const CFG_RELEASE_NUM: &'static str = "1.17.0";
pub const CFG_RELEASE_NUM: &'static str = "1.18.0";

// An optional number to put after the label, e.g. '.2' -> '-beta.2'
// Be sure to make this starts with a dot to conform to semver pre-release
6 changes: 3 additions & 3 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
@@ -1162,7 +1162,7 @@ impl<T> [T] {
///
/// # Current implementation
///
/// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort],
/// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort],
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
/// heapsort on degenerate inputs.
@@ -1199,7 +1199,7 @@ impl<T> [T] {
///
/// # Current implementation
///
/// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort],
/// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort],
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
/// heapsort on degenerate inputs.
@@ -1239,7 +1239,7 @@ impl<T> [T] {
///
/// # Current implementation
///
/// The current algorithm is based on Orson Peters' [pdqsort][pattern-defeating quicksort],
/// The current algorithm is based on Orson Peters' [pattern-defeating quicksort][pdqsort],
/// which is a quicksort variant designed to be very fast on certain kinds of patterns,
/// sometimes achieving linear time. It is randomized but deterministic, and falls back to
/// heapsort on degenerate inputs.
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@
#![feature(conservative_impl_trait)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![cfg_attr(stage0,feature(field_init_shorthand))]
#![feature(i128_type)]
#![feature(libc)]
#![feature(loop_break_value)]
4 changes: 2 additions & 2 deletions src/librustc_asan/lib.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![sanitizer_runtime]
#![feature(sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
1 change: 0 additions & 1 deletion src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
@@ -27,7 +27,6 @@

#![feature(shared)]
#![feature(collections_range)]
#![cfg_attr(stage0,feature(field_init_shorthand))]
#![feature(nonzero)]
#![feature(rustc_private)]
#![feature(staged_api)]
1 change: 0 additions & 1 deletion src/librustc_incremental/lib.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@
#![feature(rand)]
#![feature(core_intrinsics)]
#![feature(conservative_impl_trait)]
#![cfg_attr(stage0,feature(field_init_shorthand))]
#![cfg_attr(stage0, feature(pub_restricted))]

extern crate graphviz;
4 changes: 2 additions & 2 deletions src/librustc_lsan/lib.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![sanitizer_runtime]
#![feature(sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
1 change: 0 additions & 1 deletion src/librustc_metadata/lib.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
#![feature(box_patterns)]
#![feature(conservative_impl_trait)]
#![feature(core_intrinsics)]
#![cfg_attr(stage0, feature(field_init_shorthand))]
#![feature(i128_type)]
#![feature(proc_macro_internals)]
#![feature(quote)]
3 changes: 1 addition & 2 deletions src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![feature(associated_consts)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![cfg_attr(stage0, feature(field_init_shorthand))]
#![feature(i128_type)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
@@ -61,4 +60,4 @@ pub fn provide(providers: &mut Providers) {
mir_map::provide(providers);
shim::provide(providers);
transform::qualify_consts::provide(providers);
}
}
4 changes: 2 additions & 2 deletions src/librustc_msan/lib.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![sanitizer_runtime]
#![feature(sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
2 changes: 1 addition & 1 deletion src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -539,7 +539,7 @@ impl<'a> Resolver<'a> {
binding: &'a NameBinding<'a>,
span: Span,
allow_shadowing: bool) {
if self.builtin_macros.insert(name, binding).is_some() && !allow_shadowing {
if self.global_macros.insert(name, binding).is_some() && !allow_shadowing {
let msg = format!("`{}` is already in scope", name);
let note =
"macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
44 changes: 24 additions & 20 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ use std::mem::replace;
use std::rc::Rc;

use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
use macros::{InvocationData, LegacyBinding, LegacyScope};
use macros::{InvocationData, LegacyBinding, LegacyScope, MacroBinding};

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
@@ -1174,7 +1174,7 @@ pub struct Resolver<'a> {

crate_loader: &'a mut CrateLoader,
macro_names: FxHashSet<Name>,
builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
global_macros: FxHashMap<Name, &'a NameBinding<'a>>,
lexical_macro_resolutions: Vec<(Name, &'a Cell<LegacyScope<'a>>)>,
macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
macro_defs: FxHashMap<Mark, DefId>,
@@ -1372,7 +1372,7 @@ impl<'a> Resolver<'a> {

crate_loader: crate_loader,
macro_names: FxHashSet(),
builtin_macros: FxHashMap(),
global_macros: FxHashMap(),
lexical_macro_resolutions: Vec::new(),
macro_map: FxHashMap(),
macro_exports: Vec::new(),
@@ -2429,9 +2429,9 @@ impl<'a> Resolver<'a> {
};
}
}
let is_builtin = self.builtin_macros.get(&path[0].name).cloned()
let is_global = self.global_macros.get(&path[0].name).cloned()
.map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
if primary_ns != MacroNS && (is_builtin || self.macro_names.contains(&path[0].name)) {
if primary_ns != MacroNS && (is_global || self.macro_names.contains(&path[0].name)) {
// Return some dummy definition, it's enough for error reporting.
return Some(
PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
@@ -2566,6 +2566,7 @@ impl<'a> Resolver<'a> {
self.resolve_ident_in_module(module, ident, ns, false, record_used)
} else if opt_ns == Some(MacroNS) {
self.resolve_lexical_macro_path_segment(ident, ns, record_used)
.map(MacroBinding::binding)
} else {
match self.resolve_ident_in_lexical_scope(ident, ns, record_used) {
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
@@ -3223,7 +3224,7 @@ impl<'a> Resolver<'a> {
};
let msg1 = format!("`{}` could refer to the name {} here", name, participle(b1));
let msg2 = format!("`{}` could also refer to the name {} here", name, participle(b2));
let note = if !lexical && b1.is_glob_import() {
let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
format!("consider adding an explicit import of `{}` to disambiguate", name)
} else if let Def::Macro(..) = b1.def() {
format!("macro-expanded {} do not shadow",
@@ -3243,11 +3244,15 @@ impl<'a> Resolver<'a> {
let msg = format!("`{}` is ambiguous", name);
self.session.add_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
} else {
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
.span_note(b1.span, &msg1)
.span_note(b2.span, &msg2)
.note(&note)
.emit();
let mut err =
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name));
err.span_note(b1.span, &msg1);
match b2.def() {
Def::Macro(..) if b2.span == DUMMY_SP =>
err.note(&format!("`{}` is also a builtin macro", name)),
_ => err.span_note(b2.span, &msg2),
};
err.note(&note).emit();
}
}

@@ -3361,22 +3366,21 @@ impl<'a> Resolver<'a> {
if self.proc_macro_enabled { return; }

for attr in attrs {
let name = unwrap_or!(attr.name(), continue);
let maybe_binding = self.builtin_macros.get(&name).cloned().or_else(|| {
let ident = Ident::with_empty_ctxt(name);
self.resolve_lexical_macro_path_segment(ident, MacroNS, None).ok()
});

if let Some(binding) = maybe_binding {
if let SyntaxExtension::AttrProcMacro(..) = *binding.get_macro(self) {
if attr.path.segments.len() > 1 {
continue
}
let ident = attr.path.segments[0].identifier;
let result = self.resolve_lexical_macro_path_segment(ident, MacroNS, None);
if let Ok(binding) = result {
if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) {
attr::mark_known(attr);

let msg = "attribute procedural macros are experimental";
let feature = "proc_macro";

feature_err(&self.session.parse_sess, feature,
attr.span, GateIssue::Language, msg)
.span_note(binding.span, "procedural macro imported here")
.span_note(binding.span(), "procedural macro imported here")
.emit();
}
}
116 changes: 71 additions & 45 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
@@ -81,11 +81,29 @@ pub struct LegacyBinding<'a> {
pub span: Span,
}

#[derive(Copy, Clone)]
pub enum MacroBinding<'a> {
Legacy(&'a LegacyBinding<'a>),
Global(&'a NameBinding<'a>),
Modern(&'a NameBinding<'a>),
}

impl<'a> MacroBinding<'a> {
pub fn span(self) -> Span {
match self {
MacroBinding::Legacy(binding) => binding.span,
MacroBinding::Global(binding) | MacroBinding::Modern(binding) => binding.span,
}
}

pub fn binding(self) -> &'a NameBinding<'a> {
match self {
MacroBinding::Global(binding) | MacroBinding::Modern(binding) => binding,
MacroBinding::Legacy(_) => panic!("unexpected MacroBinding::Legacy"),
}
}
}

impl<'a> base::Resolver for Resolver<'a> {
fn next_node_id(&mut self) -> ast::NodeId {
self.session.next_node_id()
@@ -171,7 +189,7 @@ impl<'a> base::Resolver for Resolver<'a> {
vis: ty::Visibility::Invisible,
expansion: Mark::root(),
});
self.builtin_macros.insert(ident.name, binding);
self.global_macros.insert(ident.name, binding);
}

fn resolve_imports(&mut self) {
@@ -189,7 +207,7 @@ impl<'a> base::Resolver for Resolver<'a> {
attr::mark_known(&attrs[i]);
}

match self.builtin_macros.get(&name).cloned() {
match self.global_macros.get(&name).cloned() {
Some(binding) => match *binding.get_macro(self) {
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
return Some(attrs.remove(i))
@@ -221,7 +239,7 @@ impl<'a> base::Resolver for Resolver<'a> {
}
let trait_name = traits[j].segments[0].identifier.name;
let legacy_name = Symbol::intern(&format!("derive_{}", trait_name));
if !self.builtin_macros.contains_key(&legacy_name) {
if !self.global_macros.contains_key(&legacy_name) {
continue
}
let span = traits.remove(j).span;
@@ -378,18 +396,18 @@ impl<'a> Resolver<'a> {
}

let name = path[0].name;
let result = match self.resolve_legacy_scope(&invocation.legacy_scope, name, false) {
Some(MacroBinding::Legacy(binding)) => Ok(Def::Macro(binding.def_id, MacroKind::Bang)),
Some(MacroBinding::Modern(binding)) => Ok(binding.def_ignoring_ambiguity()),
None => match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) {
Ok(binding) => Ok(binding.def_ignoring_ambiguity()),
Err(Determinacy::Undetermined) if !force =>
return Err(Determinacy::Undetermined),
let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, name, false);
let result = if let Some(MacroBinding::Legacy(binding)) = legacy_resolution {
Ok(Def::Macro(binding.def_id, MacroKind::Bang))
} else {
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) {
Ok(binding) => Ok(binding.binding().def_ignoring_ambiguity()),
Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined),
Err(_) => {
self.found_unresolved_macro = true;
Err(Determinacy::Determined)
}
},
}
};

self.current_module.legacy_macro_resolutions.borrow_mut()
@@ -403,42 +421,56 @@ impl<'a> Resolver<'a> {
ident: Ident,
ns: Namespace,
record_used: Option<Span>)
-> Result<&'a NameBinding<'a>, Determinacy> {
let mut module = self.current_module;
let mut potential_expanded_shadower: Option<&NameBinding> = None;
-> Result<MacroBinding<'a>, Determinacy> {
let mut module = Some(self.current_module);
let mut potential_illegal_shadower = Err(Determinacy::Determined);
let determinacy =
if record_used.is_some() { Determinacy::Determined } else { Determinacy::Undetermined };
loop {
// Since expanded macros may not shadow the lexical scope (enforced below),
// we can ignore unresolved invocations (indicated by the penultimate argument).
match self.resolve_ident_in_module(module, ident, ns, true, record_used) {
let result = if let Some(module) = module {
// Since expanded macros may not shadow the lexical scope and
// globs may not shadow global macros (both enforced below),
// we resolve with restricted shadowing (indicated by the penultimate argument).
self.resolve_ident_in_module(module, ident, ns, true, record_used)
.map(MacroBinding::Modern)
} else {
self.global_macros.get(&ident.name).cloned().ok_or(determinacy)
.map(MacroBinding::Global)
};

match result.map(MacroBinding::binding) {
Ok(binding) => {
let span = match record_used {
Some(span) => span,
None => return Ok(binding),
None => return result,
};
match potential_expanded_shadower {
Some(shadower) if shadower.def() != binding.def() => {
if let Ok(MacroBinding::Modern(shadower)) = potential_illegal_shadower {
if shadower.def() != binding.def() {
let name = ident.name;
self.ambiguity_errors.push(AmbiguityError {
span: span, name: name, b1: shadower, b2: binding, lexical: true,
legacy: false,
});
return Ok(shadower);
return potential_illegal_shadower;
}
_ if binding.expansion == Mark::root() => return Ok(binding),
_ => potential_expanded_shadower = Some(binding),
}
if binding.expansion != Mark::root() ||
(binding.is_glob_import() && module.unwrap().def().is_some()) {
potential_illegal_shadower = result;
} else {
return result;
}
},
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
Err(Determinacy::Determined) => {}
}

match module.kind {
ModuleKind::Block(..) => module = module.parent.unwrap(),
ModuleKind::Def(..) => return match potential_expanded_shadower {
Some(binding) => Ok(binding),
None if record_used.is_some() => Err(Determinacy::Determined),
None => Err(Determinacy::Undetermined),
module = match module {
Some(module) => match module.kind {
ModuleKind::Block(..) => module.parent,
ModuleKind::Def(..) => None,
},
None => return potential_illegal_shadower,
}
}
}
@@ -488,11 +520,11 @@ impl<'a> Resolver<'a> {

let binding = if let Some(binding) = binding {
MacroBinding::Legacy(binding)
} else if let Some(binding) = self.builtin_macros.get(&name).cloned() {
} else if let Some(binding) = self.global_macros.get(&name).cloned() {
if !self.use_extern_macros {
self.record_use(Ident::with_empty_ctxt(name), MacroNS, binding, DUMMY_SP);
}
MacroBinding::Modern(binding)
MacroBinding::Global(binding)
} else {
return None;
};
@@ -524,21 +556,15 @@ impl<'a> Resolver<'a> {
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true);
let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, Some(span));
match (legacy_resolution, resolution) {
(Some(legacy_resolution), Ok(resolution)) => {
let (legacy_span, participle) = match legacy_resolution {
MacroBinding::Modern(binding)
if binding.def() == resolution.def() => continue,
MacroBinding::Modern(binding) => (binding.span, "imported"),
MacroBinding::Legacy(binding) => (binding.span, "defined"),
};
let msg1 = format!("`{}` could refer to the macro {} here", ident, participle);
(Some(MacroBinding::Legacy(legacy_binding)), Ok(MacroBinding::Modern(binding))) => {
let msg1 = format!("`{}` could refer to the macro defined here", ident);
let msg2 = format!("`{}` could also refer to the macro imported here", ident);
self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
.span_note(legacy_span, &msg1)
.span_note(resolution.span, &msg2)
.span_note(legacy_binding.span, &msg1)
.span_note(binding.span, &msg2)
.emit();
},
(Some(MacroBinding::Modern(binding)), Err(_)) => {
(Some(MacroBinding::Global(binding)), Ok(MacroBinding::Global(_))) => {
self.record_use(ident, MacroNS, binding, span);
self.err_if_macro_use_proc_macro(ident.name, span, binding);
},
@@ -567,11 +593,11 @@ impl<'a> Resolver<'a> {
find_best_match_for_name(self.macro_names.iter(), name, None)
} else {
None
// Then check builtin macros.
// Then check global macros.
}.or_else(|| {
// FIXME: get_macro needs an &mut Resolver, can we do it without cloning?
let builtin_macros = self.builtin_macros.clone();
let names = builtin_macros.iter().filter_map(|(name, binding)| {
let global_macros = self.global_macros.clone();
let names = global_macros.iter().filter_map(|(name, binding)| {
if binding.get_macro(self).kind() == kind {
Some(name)
} else {
12 changes: 7 additions & 5 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@ impl<'a> Resolver<'a> {
module: Module<'a>,
ident: Ident,
ns: Namespace,
ignore_unresolved_invocations: bool,
restricted_shadowing: bool,
record_used: Option<Span>)
-> Result<&'a NameBinding<'a>, Determinacy> {
self.populate_module_if_necessary(module);
@@ -158,9 +158,8 @@ impl<'a> Resolver<'a> {
if let Some(binding) = resolution.binding {
if let Some(shadowed_glob) = resolution.shadows_glob {
let name = ident.name;
// If we ignore unresolved invocations, we must forbid
// expanded shadowing to avoid time travel.
if ignore_unresolved_invocations &&
// Forbid expanded shadowing to avoid time travel.
if restricted_shadowing &&
binding.expansion != Mark::root() &&
ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing
binding.def() != shadowed_glob.def() {
@@ -215,7 +214,7 @@ impl<'a> Resolver<'a> {
}

let no_unresolved_invocations =
ignore_unresolved_invocations || module.unresolved_invocations.borrow().is_empty();
restricted_shadowing || module.unresolved_invocations.borrow().is_empty();
match resolution.binding {
// In `MacroNS`, expanded bindings do not shadow (enforced in `try_define`).
Some(binding) if no_unresolved_invocations || ns == MacroNS =>
@@ -225,6 +224,9 @@ impl<'a> Resolver<'a> {
}

// Check if the globs are determined
if restricted_shadowing && module.def().is_some() {
return Err(Determined);
}
for directive in module.globs.borrow().iter() {
if self.is_accessible(directive.vis.get()) {
if let Some(module) = directive.imported_module.get() {
1 change: 0 additions & 1 deletion src/librustc_trans/lib.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(custom_attribute)]
#![cfg_attr(stage0, feature(field_init_shorthand))]
#![allow(unused_attributes)]
#![feature(i128_type)]
#![feature(libc)]
4 changes: 2 additions & 2 deletions src/librustc_tsan/lib.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![sanitizer_runtime]
#![feature(sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
11 changes: 11 additions & 0 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -4099,6 +4099,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};

if self.diverges.get().always() {
if let ExpectHasType(ety) = expected {
// Avoid forcing a type (only `!` for now) in unreachable code.
// FIXME(aburka) do we need this special case? and should it be is_uninhabited?
if !ety.is_never() {
if let Some(ref e) = blk.expr {
// Coerce the tail expression to the right type.
self.demand_coerce(e, ty, ety);
}
}
}

ty = self.next_diverging_ty_var(TypeVariableOrigin::DivergingBlockExpr(blk.span));
} else if let ExpectHasType(ety) = expected {
if let Some(ref e) = blk.expr {
1 change: 0 additions & 1 deletion src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
@@ -77,7 +77,6 @@ This API is completely unstable and subject to change.
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(conservative_impl_trait)]
#![cfg_attr(stage0,feature(field_init_shorthand))]
#![feature(loop_break_value)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
65 changes: 18 additions & 47 deletions src/libstd/collections/hash/table.rs
Original file line number Diff line number Diff line change
@@ -896,15 +896,23 @@ impl<K, V> RawTable<K, V> {
}
}

/// Returns an iterator that copies out each entry. Used while the table
/// is being dropped.
unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
let raw_bucket = self.first_bucket_raw();
RevMoveBuckets {
raw: raw_bucket.offset(self.capacity as isize),
hashes_end: raw_bucket.hash,
elems_left: self.size,
marker: marker::PhantomData,
/// Drops buckets in reverse order. It leaves the table in an inconsistent
/// state and should only be used for dropping the table's remaining
/// entries. It's used in the implementation of Drop.
unsafe fn rev_drop_buckets(&mut self) {
let first_raw = self.first_bucket_raw();
let mut raw = first_raw.offset(self.capacity as isize);
let mut elems_left = self.size;

while elems_left != 0 {
debug_assert!(raw.hash != first_raw.hash);

raw = raw.offset(-1);

if *raw.hash != EMPTY_BUCKET {
elems_left -= 1;
ptr::drop_in_place(raw.pair as *mut (K, V));
}
}
}

@@ -964,43 +972,6 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
}
}

/// An iterator that moves out buckets in reverse order. It leaves the table
/// in an inconsistent state and should only be used for dropping
/// the table's remaining entries. It's used in the implementation of Drop.
struct RevMoveBuckets<'a, K, V> {
raw: RawBucket<K, V>,
hashes_end: *mut HashUint,
elems_left: usize,

// As above, `&'a (K,V)` would seem better, but we often use
// 'static for the lifetime, and this is not a publicly exposed
// type.
marker: marker::PhantomData<&'a ()>,
}

impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
type Item = (K, V);

fn next(&mut self) -> Option<(K, V)> {
if self.elems_left == 0 {
return None;
}

loop {
debug_assert!(self.raw.hash != self.hashes_end);

unsafe {
self.raw = self.raw.offset(-1);

if *self.raw.hash != EMPTY_BUCKET {
self.elems_left -= 1;
return Some(ptr::read(self.raw.pair));
}
}
}
}
}

/// Iterator over shared references to entries in a table.
pub struct Iter<'a, K: 'a, V: 'a> {
iter: RawBuckets<'a, K, V>,
@@ -1227,7 +1198,7 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
unsafe {
if needs_drop::<(K, V)>() {
// avoid linear runtime for types that don't need drop
for _ in self.rev_move_buckets() {}
self.rev_drop_buckets();
}
}

3 changes: 1 addition & 2 deletions src/stage0.txt
Original file line number Diff line number Diff line change
@@ -12,5 +12,4 @@
# tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was
# released on `$date`

rustc: beta-2017-02-01
cargo: 407edef22e894266eb562618cba5ca9757051946
rustc: beta-2017-03-21
72 changes: 72 additions & 0 deletions src/test/compile-fail/imports/shadow_builtin_macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2017 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.

// aux-build:two_macros.rs

#![feature(use_extern_macros)]

mod foo {
extern crate two_macros;
pub use self::two_macros::m as panic;
}

mod m1 {
use foo::panic; // ok
fn f() { panic!(); }
}

mod m2 {
use foo::*; //~ NOTE `panic` could refer to the name imported here
fn f() { panic!(); } //~ ERROR ambiguous
//~| NOTE `panic` is also a builtin macro
//~| NOTE consider adding an explicit import of `panic` to disambiguate
}

mod m3 {
::two_macros::m!(use foo::panic;); //~ NOTE `panic` could refer to the name imported here
//~| NOTE in this expansion
fn f() { panic!(); } //~ ERROR ambiguous
//~| NOTE `panic` is also a builtin macro
//~| NOTE macro-expanded macro imports do not shadow
}

mod m4 {
macro_rules! panic { () => {} } // ok
panic!();
}

mod m5 {
macro_rules! m { () => {
macro_rules! panic { () => {} } //~ ERROR `panic` is already in scope
//~| NOTE macro-expanded `macro_rules!`s may not shadow existing macros
} }
m!(); //~ NOTE in this expansion
//~| NOTE in this expansion
panic!();
}

#[macro_use(n)] //~ NOTE `n` could also refer to the name imported here
extern crate two_macros;
mod bar {
pub use two_macros::m as n;
}

mod m6 {
use bar::n; // ok
n!();
}

mod m7 {
use bar::*; //~ NOTE `n` could refer to the name imported here
n!(); //~ ERROR ambiguous
//~| NOTE consider adding an explicit import of `n` to disambiguate
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -8,12 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn g() {
&panic!()
}

fn f() -> isize {
(return 1, return 2)
//~^ ERROR mismatched types
//~| expected type `isize`
//~| found type `(_, _)`
//~| expected isize, found tuple
}

fn main() {}
17 changes: 17 additions & 0 deletions src/test/compile-fail/issue-5500.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
&panic!()
//~^ ERROR mismatched types
//~| expected type `()`
//~| found type `&_`
//~| expected (), found reference
}
7 changes: 3 additions & 4 deletions src/test/run-pass/issue-15763.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unused_features)]
#![allow(unreachable_code)]
#![allow(unknown_features)]
#![feature(box_syntax)]

#[derive(PartialEq, Debug)]
@@ -29,14 +28,14 @@ struct Foo {
}

fn foo() -> Result<Foo, isize> {
return Ok::<Foo, isize>(Foo {
return Ok(Foo {
x: Bar { x: 22 },
a: return Err(32)
});
}

fn baz() -> Result<Foo, isize> {
Ok::<Foo, isize>(Foo {
Ok(Foo {
x: Bar { x: 22 },
a: return Err(32)
})
21 changes: 21 additions & 0 deletions src/test/run-pass/issue-39984.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2016 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.

// Regression test for issue #39984.
//
// The key here is that the error type of the `Ok` call ought to be
// constrained to `String`, even though it is dead-code.

fn main() {}

fn t() -> Result<(), String> {
return Err("".into());
Ok(())
}
4 changes: 1 addition & 3 deletions src/test/run-pass/project-defer-unification.rs
Original file line number Diff line number Diff line change
@@ -11,8 +11,6 @@
// A regression test extracted from image-0.3.11. The point of
// failure was in `index_colors` below.

#![allow(unused)]

use std::ops::{Deref, DerefMut};

#[derive(Copy, Clone)]
@@ -94,7 +92,7 @@ pub fn index_colors<Pix>(image: &ImageBuffer<Pix, Vec<u8>>)
-> ImageBuffer<Luma<u8>, Vec<u8>>
where Pix: Pixel<Subpixel=u8> + 'static,
{
let mut indices: ImageBuffer<Luma<u8>, Vec<u8>> = loop { };
let mut indices: ImageBuffer<_,Vec<_>> = loop { };
for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) {
// failured occurred here ^^ because we were requiring that we
// could project Pixel or Subpixel from `T_indices` (type of
1 change: 0 additions & 1 deletion src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@

#![feature(box_syntax)]
#![feature(rustc_private)]
#![feature(static_in_const)]
#![feature(test)]
#![feature(libc)]