Skip to content
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

Rollup of 6 pull requests #65588

Merged
merged 26 commits into from
Oct 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
23d3ff1
Fix zero-size uninitialized boxes
SimonSapin Oct 6, 2019
ca1cfda
Uninitialized boxes: check for zero-size allocation based on Layout::…
SimonSapin Oct 16, 2019
75f4dac
Add regression test for #65394
ecstatic-morse Oct 17, 2019
22a0856
Enable `drain_filter`
ecstatic-morse Oct 17, 2019
af691de
Suppress validation mismatch ICE in the presence of mut borrows
ecstatic-morse Oct 17, 2019
b25e323
Don't add `argc` and `argv` arguments to `main` on WASI.
sunfishcode Oct 17, 2019
1101101
Refer to "associated functions" instead of "static methods"
estebank Oct 18, 2019
d8fca9e
Use `with` in `Symbol` trait methods.
nnethercote Oct 17, 2019
3532863
Change how `Symbol::Debug` works.
nnethercote Oct 17, 2019
f65a492
Point at enclosing function without `self` receiver
estebank Oct 18, 2019
0879f63
Remove `Copy` and `Clone` impls for `LocalInternedString`.
nnethercote Oct 18, 2019
d343ee8
Remove `Hash` impls for `DefPath`, `DisambiguatedDefPathData`, and `D…
nnethercote Oct 18, 2019
865c4bc
review comments: help wording
estebank Oct 18, 2019
bd813bf
review comment: span bug label
estebank Oct 18, 2019
2b76c8b
review comments
estebank Oct 18, 2019
2d3c17a
resolve: Mark macros starting with an underscore as used
petrochenkov Oct 9, 2019
7ce85f2
expand: Simplify expansion of derives
petrochenkov Oct 9, 2019
25cc99f
privacy: Avoid one more `unwrap` causing an ICE in rustdoc
petrochenkov Oct 15, 2019
7f89f04
Fix rebase
petrochenkov Oct 18, 2019
227db40
Uninitialized boxes: add test for zero-size allocations
SimonSapin Oct 16, 2019
beec0a5
Rollup merge of #65174 - SimonSapin:zero-box, r=alexcrichton
Centril Oct 19, 2019
99603e9
Rollup merge of #65252 - petrochenkov:deriveholders2, r=matthewjasper
Centril Oct 19, 2019
27f8c79
Rollup merge of #65485 - ecstatic-morse:const-validation-mismatch-ugl…
Centril Oct 19, 2019
fab7404
Rollup merge of #65542 - estebank:kill-static-methods, r=Centril
Centril Oct 19, 2019
ed4c2c2
Rollup merge of #65545 - nnethercote:more-symbol-cleanups, r=petroche…
Centril Oct 19, 2019
3e1da91
Rollup merge of #65576 - sunfishcode:main-needs-argc-argv, r=alexcric…
Centril Oct 19, 2019
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
16 changes: 13 additions & 3 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ impl<T> Box<T> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
if layout.size() == 0 {
return Box(NonNull::dangling().into())
}
let ptr = unsafe {
Global.alloc(layout)
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
Expand Down Expand Up @@ -182,9 +185,16 @@ impl<T> Box<[T]> {
#[unstable(feature = "new_uninit", issue = "63291")]
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
let ptr = unsafe { alloc::alloc(layout) };
let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
let ptr = if layout.size() == 0 {
NonNull::dangling()
} else {
unsafe {
Global.alloc(layout)
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
.cast()
}
};
let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
Box(Unique::from(slice))
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/liballoc/tests/boxed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::ptr::NonNull;
use std::mem::MaybeUninit;

#[test]
fn unitialized_zero_size_box() {
assert_eq!(
&*Box::<()>::new_uninit() as *const _,
NonNull::<MaybeUninit<()>>::dangling().as_ptr(),
);
assert_eq!(
Box::<[()]>::new_uninit_slice(4).as_ptr(),
NonNull::<MaybeUninit<()>>::dangling().as_ptr(),
);
assert_eq!(
Box::<[String]>::new_uninit_slice(0).as_ptr(),
NonNull::<MaybeUninit<String>>::dangling().as_ptr(),
);
}
2 changes: 2 additions & 0 deletions src/liballoc/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(box_syntax)]
#![feature(drain_filter)]
#![feature(exact_size_is_empty)]
#![feature(new_uninit)]
#![feature(option_flattening)]
#![feature(pattern)]
#![feature(trusted_len)]
Expand All @@ -14,6 +15,7 @@ use std::collections::hash_map::DefaultHasher;

mod arc;
mod binary_heap;
mod boxed;
mod btree;
mod cow_str;
mod fmt;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl<'a> DefCollector<'a> {
}
}

pub fn visit_macro_invoc(&mut self, id: NodeId) {
fn visit_macro_invoc(&mut self, id: NodeId) {
self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub struct Definitions {
/// A unique identifier that we can use to lookup a definition
/// precisely. It combines the index of the definition's parent (if
/// any) with a `DisambiguatedDefPathData`.
#[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
#[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct DefKey {
/// The parent path.
pub parent: Option<DefIndex>,
Expand Down Expand Up @@ -162,13 +162,13 @@ impl DefKey {
/// between them. This introduces some artificial ordering dependency
/// but means that if you have, e.g., two impls for the same type in
/// the same module, they do get distinct `DefId`s.
#[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
#[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct DisambiguatedDefPathData {
pub data: DefPathData,
pub disambiguator: u32
}

#[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct DefPath {
/// The path leading from the crate root to the item.
pub data: Vec<DisambiguatedDefPathData>,
Expand Down
25 changes: 18 additions & 7 deletions src/librustc_codegen_ssa/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
rust_main_def_id: DefId,
use_start_lang_item: bool,
) {
let llfty =
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int());
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
} else {
cx.type_func(&[], cx.type_int())
};

let main_ret_ty = cx.tcx().fn_sig(rust_main_def_id).output();
// Given that `main()` has no arguments,
Expand Down Expand Up @@ -445,11 +448,19 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'

bx.insert_reference_to_gdb_debug_scripts_section_global();

// Params from native main() used as args for rust start function
let param_argc = bx.get_param(0);
let param_argv = bx.get_param(1);
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
let arg_argv = param_argv;
let (arg_argc, arg_argv) = if cx.sess().target.target.options.main_needs_argc_argv {
// Params from native main() used as args for rust start function
let param_argc = bx.get_param(0);
let param_argv = bx.get_param(1);
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
let arg_argv = param_argv;
(arg_argc, arg_argv)
} else {
// The Rust start function doesn't need argc and argv, so just pass zeros.
let arg_argc = bx.const_int(cx.type_int(), 0);
let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p()));
(arg_argc, arg_argv)
};

let (start_fn, args) = if use_start_lang_item {
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![feature(core_intrinsics)]
#![feature(const_fn)]
#![feature(decl_macro)]
#![feature(drain_filter)]
#![feature(exhaustive_patterns)]
#![feature(never_type)]
#![feature(specialization)]
Expand Down
75 changes: 58 additions & 17 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,23 +1024,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
new_errors.dedup();

if self.errors != new_errors {
error!("old validator: {:?}", self.errors);
error!("new validator: {:?}", new_errors);

// ICE on nightly if the validators do not emit exactly the same errors.
// Users can supress this panic with an unstable compiler flag (hopefully after
// filing an issue).
let opts = &self.tcx.sess.opts;
let trigger_ice = opts.unstable_features.is_nightly_build()
&& !opts.debugging_opts.suppress_const_validation_back_compat_ice;

if trigger_ice {
span_bug!(
body.span,
"{}",
VALIDATOR_MISMATCH_ERR,
);
}
validator_mismatch(
self.tcx,
body,
std::mem::replace(&mut self.errors, vec![]),
new_errors,
);
}
}

Expand Down Expand Up @@ -1870,6 +1859,58 @@ fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize
Some(ret)
}

fn validator_mismatch(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
mut old_errors: Vec<(Span, String)>,
mut new_errors: Vec<(Span, String)>,
) {
error!("old validator: {:?}", old_errors);
error!("new validator: {:?}", new_errors);

// ICE on nightly if the validators do not emit exactly the same errors.
// Users can supress this panic with an unstable compiler flag (hopefully after
// filing an issue).
let opts = &tcx.sess.opts;
let strict_validation_enabled = opts.unstable_features.is_nightly_build()
&& !opts.debugging_opts.suppress_const_validation_back_compat_ice;

if !strict_validation_enabled {
return;
}

// If this difference would cause a regression from the old to the new or vice versa, trigger
// the ICE.
if old_errors.is_empty() || new_errors.is_empty() {
span_bug!(body.span, "{}", VALIDATOR_MISMATCH_ERR);
}

// HACK: Borrows that would allow mutation are forbidden in const contexts, but they cause the
// new validator to be more conservative about when a dropped local has been moved out of.
//
// Supress the mismatch ICE in cases where the validators disagree only on the number of
// `LiveDrop` errors and both observe the same sequence of `MutBorrow`s.

let is_live_drop = |(_, s): &mut (_, String)| s.starts_with("LiveDrop");
let is_mut_borrow = |(_, s): &&(_, String)| s.starts_with("MutBorrow");

let old_live_drops: Vec<_> = old_errors.drain_filter(is_live_drop).collect();
let new_live_drops: Vec<_> = new_errors.drain_filter(is_live_drop).collect();

let only_live_drops_differ = old_live_drops != new_live_drops && old_errors == new_errors;

let old_mut_borrows = old_errors.iter().filter(is_mut_borrow);
let new_mut_borrows = new_errors.iter().filter(is_mut_borrow);

let at_least_one_mut_borrow = old_mut_borrows.clone().next().is_some();

if only_live_drops_differ && at_least_one_mut_borrow && old_mut_borrows.eq(new_mut_borrows) {
return;
}

span_bug!(body.span, "{}", VALIDATOR_MISMATCH_ERR);
}

const VALIDATOR_MISMATCH_ERR: &str =
r"Disagreement between legacy and dataflow-based const validators.
After filing an issue, use `-Zsuppress-const-validation-back-compat-ice` to compile your code.";
10 changes: 5 additions & 5 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,11 +880,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
self.tcx,
self.tcx.hir().local_def_id(md.hir_id)
).unwrap();
let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
if !self.tcx.hir().is_hir_id_module(module_id) {
// `module_id` doesn't correspond to a `mod`, return early (#63164).
return;
}
let mut module_id = match self.tcx.hir().as_local_hir_id(macro_module_def_id) {
Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id,
// `module_id` doesn't correspond to a `mod`, return early (#63164, #65252).
_ => return,
};
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
let new_level = self.update(md.hir_id, level);
if new_level.is_none() {
Expand Down
25 changes: 12 additions & 13 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,25 +163,15 @@ impl<'a> Resolver<'a> {
Some(ext)
}

// FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
crate fn build_reduced_graph(
&mut self,
fragment: &AstFragment,
extra_placeholders: &[NodeId],
parent_scope: ParentScope<'a>,
) -> LegacyScope<'a> {
let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
fragment.visit_with(&mut def_collector);
for placeholder in extra_placeholders {
def_collector.visit_macro_invoc(*placeholder);
}

let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
fragment.visit_with(&mut visitor);
for placeholder in extra_placeholders {
visitor.parent_scope.legacy = visitor.visit_invoc(*placeholder);
}

visitor.parent_scope.legacy
}

Expand Down Expand Up @@ -1064,8 +1054,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
None
}

// Mark the given macro as unused unless its name starts with `_`.
// Macro uses will remove items from this set, and the remaining
// items will be reported as `unused_macros`.
fn insert_unused_macro(&mut self, ident: Ident, node_id: NodeId, span: Span) {
if !ident.as_str().starts_with("_") {
self.r.unused_macros.insert(node_id, span);
}
}

fn define_macro(&mut self, item: &ast::Item) -> LegacyScope<'a> {
let parent_scope = &self.parent_scope;
let parent_scope = self.parent_scope;
let expansion = parent_scope.expansion;
let (ext, ident, span, is_legacy) = match &item.kind {
ItemKind::MacroDef(def) => {
Expand Down Expand Up @@ -1105,7 +1104,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
(res, vis, span, expansion, IsMacroExport));
} else {
self.r.check_reserved_macro_name(ident, res);
self.r.unused_macros.insert(item.id, span);
self.insert_unused_macro(ident, item.id, span);
}
LegacyScope::Binding(self.r.arenas.alloc_legacy_binding(LegacyBinding {
parent_legacy_scope: parent_scope.legacy, binding, ident
Expand All @@ -1114,7 +1113,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
let module = parent_scope.module;
let vis = self.resolve_visibility(&item.vis);
if vis != ty::Visibility::Public {
self.r.unused_macros.insert(item.id, span);
self.insert_unused_macro(ident, item.id, span);
}
self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
self.parent_scope.legacy
Expand Down
25 changes: 17 additions & 8 deletions src/librustc_resolve/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,33 +1013,42 @@ fn h1() -> i32 {
"##,

E0424: r##"
The `self` keyword was used in a static method.
The `self` keyword was used inside of an associated function without a "`self`
receiver" parameter.

Erroneous code example:

```compile_fail,E0424
struct Foo;

impl Foo {
fn bar(self) {}
// `bar` is a method, because it has a receiver parameter.
fn bar(&self) {}

// `foo` is not a method, because it has no receiver parameter.
fn foo() {
self.bar(); // error: `self` is not available in a static method.
self.bar(); // error: `self` value is a keyword only available in
// methods with a `self` parameter
}
}
```

Please check if the method's argument list should have contained `self`,
`&self`, or `&mut self` (in case you didn't want to create a static
method), and add it if so. Example:
The `self` keyword can only be used inside methods, which are associated
functions (functions defined inside of a `trait` or `impl` block) that have a
`self` receiver as its first parameter, like `self`, `&self`, `&mut self` or
`self: &mut Pin<Self>` (this last one is an example of an ["abitrary `self`
type"](https://github.com/rust-lang/rust/issues/44874)).

Check if the associated function's parameter list should have contained a `self`
receiver for it to be a method, and add it if so. Example:

```
struct Foo;

impl Foo {
fn bar(self) {}
fn bar(&self) {}

fn foo(self) {
fn foo(self) { // `foo` is now a method.
self.bar(); // ok!
}
}
Expand Down
Loading