Skip to content

Commit 9578272

Browse files
committed
Auto merge of #65588 - Centril:rollup-9k55k3t, r=Centril
Rollup of 6 pull requests Successful merges: - #65174 (Fix zero-size uninitialized boxes) - #65252 (expand: Simplify expansion of derives) - #65485 (Suppress ICE when validators disagree on `LiveDrop`s in presence of `&mut`) - #65542 (Refer to "associated functions" instead of "static methods") - #65545 (More symbol cleanups) - #65576 (Don't add `argc` and `argv` arguments to `main` on WASI.) Failed merges: r? @ghost
2 parents 14f0ed6 + 3e1da91 commit 9578272

File tree

31 files changed

+282
-133
lines changed

31 files changed

+282
-133
lines changed

src/liballoc/boxed.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ impl<T> Box<T> {
142142
#[unstable(feature = "new_uninit", issue = "63291")]
143143
pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
144144
let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
145+
if layout.size() == 0 {
146+
return Box(NonNull::dangling().into())
147+
}
145148
let ptr = unsafe {
146149
Global.alloc(layout)
147150
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
@@ -182,9 +185,16 @@ impl<T> Box<[T]> {
182185
#[unstable(feature = "new_uninit", issue = "63291")]
183186
pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
184187
let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
185-
let ptr = unsafe { alloc::alloc(layout) };
186-
let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
187-
let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
188+
let ptr = if layout.size() == 0 {
189+
NonNull::dangling()
190+
} else {
191+
unsafe {
192+
Global.alloc(layout)
193+
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
194+
.cast()
195+
}
196+
};
197+
let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
188198
Box(Unique::from(slice))
189199
}
190200
}

src/liballoc/tests/boxed.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::ptr::NonNull;
2+
use std::mem::MaybeUninit;
3+
4+
#[test]
5+
fn unitialized_zero_size_box() {
6+
assert_eq!(
7+
&*Box::<()>::new_uninit() as *const _,
8+
NonNull::<MaybeUninit<()>>::dangling().as_ptr(),
9+
);
10+
assert_eq!(
11+
Box::<[()]>::new_uninit_slice(4).as_ptr(),
12+
NonNull::<MaybeUninit<()>>::dangling().as_ptr(),
13+
);
14+
assert_eq!(
15+
Box::<[String]>::new_uninit_slice(0).as_ptr(),
16+
NonNull::<MaybeUninit<String>>::dangling().as_ptr(),
17+
);
18+
}

src/liballoc/tests/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![feature(box_syntax)]
33
#![feature(drain_filter)]
44
#![feature(exact_size_is_empty)]
5+
#![feature(new_uninit)]
56
#![feature(option_flattening)]
67
#![feature(pattern)]
78
#![feature(trusted_len)]
@@ -14,6 +15,7 @@ use std::collections::hash_map::DefaultHasher;
1415

1516
mod arc;
1617
mod binary_heap;
18+
mod boxed;
1719
mod btree;
1820
mod cow_str;
1921
mod fmt;

src/librustc/hir/map/def_collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl<'a> DefCollector<'a> {
9090
}
9191
}
9292

93-
pub fn visit_macro_invoc(&mut self, id: NodeId) {
93+
fn visit_macro_invoc(&mut self, id: NodeId) {
9494
self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
9595
}
9696
}

src/librustc/hir/map/definitions.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub struct Definitions {
111111
/// A unique identifier that we can use to lookup a definition
112112
/// precisely. It combines the index of the definition's parent (if
113113
/// any) with a `DisambiguatedDefPathData`.
114-
#[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
114+
#[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
115115
pub struct DefKey {
116116
/// The parent path.
117117
pub parent: Option<DefIndex>,
@@ -162,13 +162,13 @@ impl DefKey {
162162
/// between them. This introduces some artificial ordering dependency
163163
/// but means that if you have, e.g., two impls for the same type in
164164
/// the same module, they do get distinct `DefId`s.
165-
#[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
165+
#[derive(Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
166166
pub struct DisambiguatedDefPathData {
167167
pub data: DefPathData,
168168
pub disambiguator: u32
169169
}
170170

171-
#[derive(Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
171+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
172172
pub struct DefPath {
173173
/// The path leading from the crate root to the item.
174174
pub data: Vec<DisambiguatedDefPathData>,

src/librustc_codegen_ssa/base.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
414414
rust_main_def_id: DefId,
415415
use_start_lang_item: bool,
416416
) {
417-
let llfty =
418-
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int());
417+
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
418+
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
419+
} else {
420+
cx.type_func(&[], cx.type_int())
421+
};
419422

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

446449
bx.insert_reference_to_gdb_debug_scripts_section_global();
447450

448-
// Params from native main() used as args for rust start function
449-
let param_argc = bx.get_param(0);
450-
let param_argv = bx.get_param(1);
451-
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
452-
let arg_argv = param_argv;
451+
let (arg_argc, arg_argv) = if cx.sess().target.target.options.main_needs_argc_argv {
452+
// Params from native main() used as args for rust start function
453+
let param_argc = bx.get_param(0);
454+
let param_argv = bx.get_param(1);
455+
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
456+
let arg_argv = param_argv;
457+
(arg_argc, arg_argv)
458+
} else {
459+
// The Rust start function doesn't need argc and argv, so just pass zeros.
460+
let arg_argc = bx.const_int(cx.type_int(), 0);
461+
let arg_argv = bx.const_null(cx.type_ptr_to(cx.type_i8p()));
462+
(arg_argc, arg_argv)
463+
};
453464

454465
let (start_fn, args) = if use_start_lang_item {
455466
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);

src/librustc_mir/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
1414
#![feature(core_intrinsics)]
1515
#![feature(const_fn)]
1616
#![feature(decl_macro)]
17+
#![feature(drain_filter)]
1718
#![feature(exhaustive_patterns)]
1819
#![feature(never_type)]
1920
#![feature(specialization)]

src/librustc_mir/transform/qualify_consts.rs

+58-17
Original file line numberDiff line numberDiff line change
@@ -1024,23 +1024,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
10241024
new_errors.dedup();
10251025

10261026
if self.errors != new_errors {
1027-
error!("old validator: {:?}", self.errors);
1028-
error!("new validator: {:?}", new_errors);
1029-
1030-
// ICE on nightly if the validators do not emit exactly the same errors.
1031-
// Users can supress this panic with an unstable compiler flag (hopefully after
1032-
// filing an issue).
1033-
let opts = &self.tcx.sess.opts;
1034-
let trigger_ice = opts.unstable_features.is_nightly_build()
1035-
&& !opts.debugging_opts.suppress_const_validation_back_compat_ice;
1036-
1037-
if trigger_ice {
1038-
span_bug!(
1039-
body.span,
1040-
"{}",
1041-
VALIDATOR_MISMATCH_ERR,
1042-
);
1043-
}
1027+
validator_mismatch(
1028+
self.tcx,
1029+
body,
1030+
std::mem::replace(&mut self.errors, vec![]),
1031+
new_errors,
1032+
);
10441033
}
10451034
}
10461035

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

1862+
fn validator_mismatch(
1863+
tcx: TyCtxt<'tcx>,
1864+
body: &Body<'tcx>,
1865+
mut old_errors: Vec<(Span, String)>,
1866+
mut new_errors: Vec<(Span, String)>,
1867+
) {
1868+
error!("old validator: {:?}", old_errors);
1869+
error!("new validator: {:?}", new_errors);
1870+
1871+
// ICE on nightly if the validators do not emit exactly the same errors.
1872+
// Users can supress this panic with an unstable compiler flag (hopefully after
1873+
// filing an issue).
1874+
let opts = &tcx.sess.opts;
1875+
let strict_validation_enabled = opts.unstable_features.is_nightly_build()
1876+
&& !opts.debugging_opts.suppress_const_validation_back_compat_ice;
1877+
1878+
if !strict_validation_enabled {
1879+
return;
1880+
}
1881+
1882+
// If this difference would cause a regression from the old to the new or vice versa, trigger
1883+
// the ICE.
1884+
if old_errors.is_empty() || new_errors.is_empty() {
1885+
span_bug!(body.span, "{}", VALIDATOR_MISMATCH_ERR);
1886+
}
1887+
1888+
// HACK: Borrows that would allow mutation are forbidden in const contexts, but they cause the
1889+
// new validator to be more conservative about when a dropped local has been moved out of.
1890+
//
1891+
// Supress the mismatch ICE in cases where the validators disagree only on the number of
1892+
// `LiveDrop` errors and both observe the same sequence of `MutBorrow`s.
1893+
1894+
let is_live_drop = |(_, s): &mut (_, String)| s.starts_with("LiveDrop");
1895+
let is_mut_borrow = |(_, s): &&(_, String)| s.starts_with("MutBorrow");
1896+
1897+
let old_live_drops: Vec<_> = old_errors.drain_filter(is_live_drop).collect();
1898+
let new_live_drops: Vec<_> = new_errors.drain_filter(is_live_drop).collect();
1899+
1900+
let only_live_drops_differ = old_live_drops != new_live_drops && old_errors == new_errors;
1901+
1902+
let old_mut_borrows = old_errors.iter().filter(is_mut_borrow);
1903+
let new_mut_borrows = new_errors.iter().filter(is_mut_borrow);
1904+
1905+
let at_least_one_mut_borrow = old_mut_borrows.clone().next().is_some();
1906+
1907+
if only_live_drops_differ && at_least_one_mut_borrow && old_mut_borrows.eq(new_mut_borrows) {
1908+
return;
1909+
}
1910+
1911+
span_bug!(body.span, "{}", VALIDATOR_MISMATCH_ERR);
1912+
}
1913+
18731914
const VALIDATOR_MISMATCH_ERR: &str =
18741915
r"Disagreement between legacy and dataflow-based const validators.
18751916
After filing an issue, use `-Zsuppress-const-validation-back-compat-ice` to compile your code.";

src/librustc_privacy/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -880,11 +880,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
880880
self.tcx,
881881
self.tcx.hir().local_def_id(md.hir_id)
882882
).unwrap();
883-
let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
884-
if !self.tcx.hir().is_hir_id_module(module_id) {
885-
// `module_id` doesn't correspond to a `mod`, return early (#63164).
886-
return;
887-
}
883+
let mut module_id = match self.tcx.hir().as_local_hir_id(macro_module_def_id) {
884+
Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id,
885+
// `module_id` doesn't correspond to a `mod`, return early (#63164, #65252).
886+
_ => return,
887+
};
888888
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
889889
let new_level = self.update(md.hir_id, level);
890890
if new_level.is_none() {

src/librustc_resolve/build_reduced_graph.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,15 @@ impl<'a> Resolver<'a> {
163163
Some(ext)
164164
}
165165

166-
// FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
167166
crate fn build_reduced_graph(
168167
&mut self,
169168
fragment: &AstFragment,
170-
extra_placeholders: &[NodeId],
171169
parent_scope: ParentScope<'a>,
172170
) -> LegacyScope<'a> {
173171
let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
174172
fragment.visit_with(&mut def_collector);
175-
for placeholder in extra_placeholders {
176-
def_collector.visit_macro_invoc(*placeholder);
177-
}
178-
179173
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
180174
fragment.visit_with(&mut visitor);
181-
for placeholder in extra_placeholders {
182-
visitor.parent_scope.legacy = visitor.visit_invoc(*placeholder);
183-
}
184-
185175
visitor.parent_scope.legacy
186176
}
187177

@@ -1064,8 +1054,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
10641054
None
10651055
}
10661056

1057+
// Mark the given macro as unused unless its name starts with `_`.
1058+
// Macro uses will remove items from this set, and the remaining
1059+
// items will be reported as `unused_macros`.
1060+
fn insert_unused_macro(&mut self, ident: Ident, node_id: NodeId, span: Span) {
1061+
if !ident.as_str().starts_with("_") {
1062+
self.r.unused_macros.insert(node_id, span);
1063+
}
1064+
}
1065+
10671066
fn define_macro(&mut self, item: &ast::Item) -> LegacyScope<'a> {
1068-
let parent_scope = &self.parent_scope;
1067+
let parent_scope = self.parent_scope;
10691068
let expansion = parent_scope.expansion;
10701069
let (ext, ident, span, is_legacy) = match &item.kind {
10711070
ItemKind::MacroDef(def) => {
@@ -1105,7 +1104,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
11051104
(res, vis, span, expansion, IsMacroExport));
11061105
} else {
11071106
self.r.check_reserved_macro_name(ident, res);
1108-
self.r.unused_macros.insert(item.id, span);
1107+
self.insert_unused_macro(ident, item.id, span);
11091108
}
11101109
LegacyScope::Binding(self.r.arenas.alloc_legacy_binding(LegacyBinding {
11111110
parent_legacy_scope: parent_scope.legacy, binding, ident
@@ -1114,7 +1113,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
11141113
let module = parent_scope.module;
11151114
let vis = self.resolve_visibility(&item.vis);
11161115
if vis != ty::Visibility::Public {
1117-
self.r.unused_macros.insert(item.id, span);
1116+
self.insert_unused_macro(ident, item.id, span);
11181117
}
11191118
self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
11201119
self.parent_scope.legacy

src/librustc_resolve/error_codes.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -1013,33 +1013,42 @@ fn h1() -> i32 {
10131013
"##,
10141014

10151015
E0424: r##"
1016-
The `self` keyword was used in a static method.
1016+
The `self` keyword was used inside of an associated function without a "`self`
1017+
receiver" parameter.
10171018
10181019
Erroneous code example:
10191020
10201021
```compile_fail,E0424
10211022
struct Foo;
10221023
10231024
impl Foo {
1024-
fn bar(self) {}
1025+
// `bar` is a method, because it has a receiver parameter.
1026+
fn bar(&self) {}
10251027
1028+
// `foo` is not a method, because it has no receiver parameter.
10261029
fn foo() {
1027-
self.bar(); // error: `self` is not available in a static method.
1030+
self.bar(); // error: `self` value is a keyword only available in
1031+
// methods with a `self` parameter
10281032
}
10291033
}
10301034
```
10311035
1032-
Please check if the method's argument list should have contained `self`,
1033-
`&self`, or `&mut self` (in case you didn't want to create a static
1034-
method), and add it if so. Example:
1036+
The `self` keyword can only be used inside methods, which are associated
1037+
functions (functions defined inside of a `trait` or `impl` block) that have a
1038+
`self` receiver as its first parameter, like `self`, `&self`, `&mut self` or
1039+
`self: &mut Pin<Self>` (this last one is an example of an ["abitrary `self`
1040+
type"](https://github.com/rust-lang/rust/issues/44874)).
1041+
1042+
Check if the associated function's parameter list should have contained a `self`
1043+
receiver for it to be a method, and add it if so. Example:
10351044
10361045
```
10371046
struct Foo;
10381047
10391048
impl Foo {
1040-
fn bar(self) {}
1049+
fn bar(&self) {}
10411050
1042-
fn foo(self) {
1051+
fn foo(self) { // `foo` is now a method.
10431052
self.bar(); // ok!
10441053
}
10451054
}

0 commit comments

Comments
 (0)