Skip to content

Rollup of 10 pull requests #81171

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 22 commits into from
Closed
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
14eb94f
don't suggest erroneous trailing comma after `..`
zackmdavis Jan 16, 2021
ad5aa23
Remove an unnecessary field from a `NonConstOp`
oli-obk Jan 4, 2021
949bdd8
Add regression test
oli-obk Jan 4, 2021
2136a5c
Fix `unused_unsafe` label with `unsafe_block_in_unsafe_fn
LeSeulArtichaut Jan 17, 2021
70a43e0
Fix structured suggestion for explicit `drop` call
estebank Jan 18, 2021
dc04cea
use raw-ptr-addr-of for slice::swap
RalfJung Jan 18, 2021
1d1ab21
Remove inline script tags
GuillaumeGomez Jan 18, 2021
5bac1c9
Only inherit const stability for methods of `impl const Trait` blocks
oli-obk Jan 16, 2021
222e0e4
Fix typo in simplify.rs
eltociear Jan 18, 2021
712d065
remove some outdated comments regarding debug assertions
RalfJung Jan 18, 2021
47c2476
Fixes #81109 - Typo in pointer::wrapping_sub
soniasingla Jan 18, 2021
4775334
BTreeMap: prefer bulk_steal functions over specialized ones
ssomers Jan 17, 2021
6f0cfce
Rollup merge of #80707 - oli-obk:stability_hole_const_intrinsics, r=R…
m-ou-se Jan 18, 2021
a246cdb
Rollup merge of #81103 - zackmdavis:comma_trail, r=davidtwco
m-ou-se Jan 18, 2021
d68ed11
Rollup merge of #81110 - LeSeulArtichaut:fix-unused-unsafe-label, r=R…
m-ou-se Jan 18, 2021
eee7d3c
Rollup merge of #81115 - ssomers:btree_drainy_refactor_4, r=Mark-Simu…
m-ou-se Jan 18, 2021
3a8aa7b
Rollup merge of #81147 - estebank:drop-suggestion, r=varkor
m-ou-se Jan 18, 2021
0f1dff9
Rollup merge of #81160 - RalfJung:swap, r=oli-obk
m-ou-se Jan 18, 2021
eb65d22
Rollup merge of #81161 - GuillaumeGomez:remove-inline-script, r=Nemo157
m-ou-se Jan 18, 2021
fd52951
Rollup merge of #81164 - eltociear:patch-5, r=jonas-schievink
m-ou-se Jan 18, 2021
c3fcaf8
Rollup merge of #81166 - RalfJung:debug-assert-comments, r=Mark-Simul…
m-ou-se Jan 18, 2021
1ae90bd
Rollup merge of #81168 - soniasingla:doc/sonia, r=jonas-schievink
m-ou-se Jan 18, 2021
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
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ impl NonConstOp for FnCallIndirect {

/// A function call where the callee is not marked as `const`.
#[derive(Debug)]
pub struct FnCallNonConst(pub DefId);
pub struct FnCallNonConst;
impl NonConstOp for FnCallNonConst {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
struct_span_err!(
24 changes: 17 additions & 7 deletions compiler/rustc_mir/src/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
@@ -789,10 +789,10 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
}
}

#[instrument(skip(self))]
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
use rustc_target::spec::abi::Abi::RustIntrinsic;

trace!("visit_terminator: terminator={:?} location={:?}", terminator, location);
self.super_terminator(terminator, location);

match &terminator.kind {
@@ -816,8 +816,9 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {

// Attempting to call a trait method?
if let Some(trait_id) = tcx.trait_of_item(callee) {
trace!("attempting to call a trait method");
if !self.tcx.features().const_trait_impl {
self.check_op(ops::FnCallNonConst(callee));
self.check_op(ops::FnCallNonConst);
return;
}

@@ -871,25 +872,26 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
return;
}

let is_intrinsic = tcx.fn_sig(callee).abi() == RustIntrinsic;

// HACK: This is to "unstabilize" the `transmute` intrinsic
// within const fns. `transmute` is allowed in all other const contexts.
// This won't really scale to more intrinsics or functions. Let's allow const
// transmutes in const fn before we add more hacks to this.
if tcx.fn_sig(callee).abi() == RustIntrinsic
&& tcx.item_name(callee) == sym::transmute
{
if is_intrinsic && tcx.item_name(callee) == sym::transmute {
self.check_op(ops::Transmute);
return;
}

if !tcx.is_const_fn_raw(callee) {
self.check_op(ops::FnCallNonConst(callee));
self.check_op(ops::FnCallNonConst);
return;
}

// If the `const fn` we are trying to call is not const-stable, ensure that we have
// the proper feature gate enabled.
if let Some(gate) = is_unstable_const_fn(tcx, callee) {
trace!(?gate, "calling unstable const fn");
if self.span.allows_unstable(gate) {
return;
}
@@ -904,12 +906,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
// If this crate is not using stability attributes, or the caller is not claiming to be a
// stable `const fn`, that is all that is required.
if !self.ccx.is_const_stable_const_fn() {
trace!("crate not using stability attributes or caller not stably const");
return;
}

// Otherwise, we are something const-stable calling a const-unstable fn.

if super::rustc_allow_const_fn_unstable(tcx, caller, gate) {
trace!("rustc_allow_const_fn_unstable gate active");
return;
}

@@ -923,10 +927,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
let callee_is_unstable_unmarked = tcx.lookup_const_stability(callee).is_none()
&& tcx.lookup_stability(callee).map_or(false, |s| s.level.is_unstable());
if callee_is_unstable_unmarked {
if self.ccx.is_const_stable_const_fn() {
trace!("callee_is_unstable_unmarked");
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
// `extern` funtions, and these have no way to get marked `const`. So instead we
// use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
if self.ccx.is_const_stable_const_fn() || is_intrinsic {
self.check_op(ops::FnCallUnstable(callee, None));
return;
}
}
trace!("permitting call");
}

// Forbid all `Drop` terminators unless the place being dropped is a local with no
17 changes: 9 additions & 8 deletions compiler/rustc_mir/src/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
@@ -568,24 +568,23 @@ fn is_enclosed(
tcx: TyCtxt<'_>,
used_unsafe: &FxHashSet<hir::HirId>,
id: hir::HirId,
) -> Option<(String, hir::HirId)> {
unsafe_op_in_unsafe_fn_allowed: bool,
) -> Option<(&'static str, hir::HirId)> {
let parent_id = tcx.hir().get_parent_node(id);
if parent_id != id {
if used_unsafe.contains(&parent_id) {
Some(("block".to_string(), parent_id))
Some(("block", parent_id))
} else if let Some(Node::Item(&hir::Item {
kind: hir::ItemKind::Fn(ref sig, _, _), ..
})) = tcx.hir().find(parent_id)
{
if sig.header.unsafety == hir::Unsafety::Unsafe
&& !tcx.features().unsafe_block_in_unsafe_fn
{
Some(("fn".to_string(), parent_id))
if sig.header.unsafety == hir::Unsafety::Unsafe && unsafe_op_in_unsafe_fn_allowed {
Some(("fn", parent_id))
} else {
None
}
} else {
is_enclosed(tcx, used_unsafe, parent_id)
is_enclosed(tcx, used_unsafe, parent_id, unsafe_op_in_unsafe_fn_allowed)
}
} else {
None
@@ -598,7 +597,9 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, used_unsafe: &FxHashSet<hir::HirId>, id
let msg = "unnecessary `unsafe` block";
let mut db = lint.build(msg);
db.span_label(span, msg);
if let Some((kind, id)) = is_enclosed(tcx, used_unsafe, id) {
if let Some((kind, id)) =
is_enclosed(tcx, used_unsafe, id, unsafe_op_in_unsafe_fn_allowed(tcx, id))
{
db.span_label(
tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
format!("because it's nested under this `unsafe` {}", kind),
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/build/matches/simplify.rs
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// * the bindings from the previous iteration of the loop is prepended to the bindings from
// the current iteration (in the implementation this is done by mem::swap and extend)
// * after all iterations, these new bindings are then appended to the bindings that were
// prexisting (i.e. `candidate.binding` when the function was called).
// preexisting (i.e. `candidate.binding` when the function was called).
//
// example:
// candidate.bindings = [1, 2, 3]
70 changes: 60 additions & 10 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
@@ -55,6 +55,21 @@ impl InheritDeprecation {
}
}

/// Whether to inherit const stability flags for nested items. In most cases, we do not want to
/// inherit const stability: just because an enclosing `fn` is const-stable does not mean
/// all `extern` imports declared in it should be const-stable! However, trait methods
/// inherit const stability attributes from their parent and do not have their own.
enum InheritConstStability {
Yes,
No,
}

impl InheritConstStability {
fn yes(&self) -> bool {
matches!(self, InheritConstStability::Yes)
}
}

// A private tree-walker for producing an Index.
struct Annotator<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
@@ -75,6 +90,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
item_sp: Span,
kind: AnnotationKind,
inherit_deprecation: InheritDeprecation,
inherit_const_stability: InheritConstStability,
visit_children: F,
) where
F: FnOnce(&mut Self),
@@ -140,6 +156,8 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
const_stab
});

// `impl const Trait for Type` items forward their const stability to their
// immediate children.
if const_stab.is_none() {
debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab);
if let Some(parent) = self.parent_const_stab {
@@ -228,7 +246,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
self.recurse_with_stability_attrs(
depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
stab,
const_stab,
if inherit_const_stability.yes() { const_stab } else { None },
visit_children,
);
}
@@ -325,6 +343,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
let orig_in_trait_impl = self.in_trait_impl;
let mut kind = AnnotationKind::Required;
let mut const_stab_inherit = InheritConstStability::No;
match i.kind {
// Inherent impls and foreign modules serve only as containers for other items,
// they don't have their own stability. They still can be annotated as unstable
@@ -338,6 +357,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
self.in_trait_impl = true;
kind = AnnotationKind::DeprecationProhibited;
const_stab_inherit = InheritConstStability::Yes;
}
hir::ItemKind::Struct(ref sd, _) => {
if let Some(ctor_hir_id) = sd.ctor_hir_id() {
@@ -347,16 +367,23 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
i.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|_| {},
)
}
}
_ => {}
}

self.annotate(i.hir_id, &i.attrs, i.span, kind, InheritDeprecation::Yes, |v| {
intravisit::walk_item(v, i)
});
self.annotate(
i.hir_id,
&i.attrs,
i.span,
kind,
InheritDeprecation::Yes,
const_stab_inherit,
|v| intravisit::walk_item(v, i),
);
self.in_trait_impl = orig_in_trait_impl;
}

@@ -367,6 +394,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
ti.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|v| {
intravisit::walk_trait_item(v, ti);
},
@@ -376,9 +404,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
let kind =
if self.in_trait_impl { AnnotationKind::Prohibited } else { AnnotationKind::Required };
self.annotate(ii.hir_id, &ii.attrs, ii.span, kind, InheritDeprecation::Yes, |v| {
intravisit::walk_impl_item(v, ii);
});
self.annotate(
ii.hir_id,
&ii.attrs,
ii.span,
kind,
InheritDeprecation::Yes,
InheritConstStability::No,
|v| {
intravisit::walk_impl_item(v, ii);
},
);
}

fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
@@ -388,6 +424,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
var.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|v| {
if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
v.annotate(
@@ -396,6 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
var.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|_| {},
);
}
@@ -412,6 +450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
s.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|v| {
intravisit::walk_struct_field(v, s);
},
@@ -425,6 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
i.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|v| {
intravisit::walk_foreign_item(v, i);
},
@@ -438,6 +478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
md.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|_| {},
);
}
@@ -451,9 +492,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
_ => AnnotationKind::Prohibited,
};

self.annotate(p.hir_id, &p.attrs, p.span, kind, InheritDeprecation::No, |v| {
intravisit::walk_generic_param(v, p);
});
self.annotate(
p.hir_id,
&p.attrs,
p.span,
kind,
InheritDeprecation::No,
InheritConstStability::No,
|v| {
intravisit::walk_generic_param(v, p);
},
);
}
}

@@ -618,6 +667,7 @@ fn new_index(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
krate.item.span,
AnnotationKind::Required,
InheritDeprecation::Yes,
InheritConstStability::No,
|v| intravisit::walk_crate(v, krate),
);
}
18 changes: 9 additions & 9 deletions compiler/rustc_typeck/src/check/callee.rs
Original file line number Diff line number Diff line change
@@ -25,24 +25,24 @@ pub fn check_legal_trait_for_method_call(
tcx: TyCtxt<'_>,
span: Span,
receiver: Option<Span>,
expr_span: Span,
trait_id: DefId,
) {
if tcx.lang_items().drop_trait() == Some(trait_id) {
let mut err = struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
err.span_label(span, "explicit destructor calls not allowed");

let snippet = receiver
let (sp, suggestion) = receiver
.and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
.unwrap_or_default();

let suggestion =
if snippet.is_empty() { "drop".to_string() } else { format!("drop({})", snippet) };
.filter(|snippet| !snippet.is_empty())
.map(|snippet| (expr_span, format!("drop({})", snippet)))
.unwrap_or_else(|| (span, "drop".to_string()));

err.span_suggestion(
span,
&format!("consider using `drop` function: `{}`", suggestion),
String::new(),
Applicability::Unspecified,
sp,
"consider using `drop` function",
suggestion,
Applicability::MaybeIncorrect,
);

err.emit();
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -1163,7 +1163,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
match container {
ty::TraitContainer(trait_did) => {
callee::check_legal_trait_for_method_call(tcx, span, None, trait_did)
callee::check_legal_trait_for_method_call(tcx, span, None, span, trait_did)
}
ty::ImplContainer(impl_def_id) => {
if segments.len() == 1 {
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/method/confirm.rs
Original file line number Diff line number Diff line change
@@ -508,6 +508,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
self.tcx,
self.span,
Some(self.self_expr.span),
self.call_expr.span,
trait_def_id,
),
ty::ImplContainer(..) => {}
32 changes: 22 additions & 10 deletions compiler/rustc_typeck/src/check/pat.rs
Original file line number Diff line number Diff line change
@@ -1486,11 +1486,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Returns a diagnostic reporting a struct pattern which does not mention some fields.
///
/// ```text
/// error[E0027]: pattern does not mention field `you_cant_use_this_field`
/// error[E0027]: pattern does not mention field `bar`
/// --> src/main.rs:15:9
/// |
/// LL | let foo::Foo {} = foo::Foo::new();
/// | ^^^^^^^^^^^ missing field `you_cant_use_this_field`
/// | ^^^^^^^^^^^ missing field `bar`
/// ```
fn error_unmentioned_fields(
&self,
@@ -1524,14 +1524,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
_ => return err,
},
[.., field] => (
match pat.kind {
PatKind::Struct(_, [_, ..], _) => ", ",
_ => "",
},
"",
field.span.shrink_to_hi(),
),
[.., field] => {
// if last field has a trailing comma, use the comma
// as the span to avoid trailing comma in ultimate
// suggestion (Issue #78511)
let tail = field.span.shrink_to_hi().until(pat.span.shrink_to_hi());
let tail_through_comma = self.tcx.sess.source_map().span_through_char(tail, ',');
let sp = if tail_through_comma == tail {
field.span.shrink_to_hi()
} else {
tail_through_comma
};
(
match pat.kind {
PatKind::Struct(_, [_, ..], _) => ", ",
_ => "",
},
"",
sp,
)
}
};
err.span_suggestion(
sp,
121 changes: 4 additions & 117 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
@@ -592,17 +592,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
self.val_area_mut(idx).write(val);
}
}

/// Adds a key-value pair to the beginning of the node.
fn push_front(&mut self, key: K, val: V) {
let new_len = self.len() + 1;
assert!(new_len <= CAPACITY);
unsafe {
slice_insert(self.key_area_mut(..new_len), 0, key);
slice_insert(self.val_area_mut(..new_len), 0, val);
*self.len_mut() = new_len as u16;
}
}
}

impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
@@ -638,88 +627,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link();
}
}

/// Adds a key-value pair, and an edge to go to the left of that pair,
/// to the beginning of the node.
fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) {
let new_len = self.len() + 1;
assert!(edge.height == self.height - 1);
assert!(new_len <= CAPACITY);

unsafe {
slice_insert(self.key_area_mut(..new_len), 0, key);
slice_insert(self.val_area_mut(..new_len), 0, val);
slice_insert(self.edge_area_mut(..new_len + 1), 0, edge.node);
*self.len_mut() = new_len as u16;
}

self.correct_all_childrens_parent_links();
}
}

impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
/// Removes a key-value pair from the end of the node and returns the pair.
/// Also removes the edge that was to the right of that pair and, if the node
/// is internal, returns the orphaned subtree that this edge owned.
///
/// # Safety
/// The node must not be empty.
unsafe fn pop(&mut self) -> (K, V, Option<Root<K, V>>) {
debug_assert!(self.len() > 0);

let idx = self.len() - 1;

unsafe {
let key = self.key_area_mut(idx).assume_init_read();
let val = self.val_area_mut(idx).assume_init_read();
let edge = match self.reborrow_mut().force() {
ForceResult::Leaf(_) => None,
ForceResult::Internal(mut internal) => {
let node = internal.edge_area_mut(idx + 1).assume_init_read();
let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData };
// Currently, clearing the parent link is superfluous, because we will
// insert the node elsewhere and set its parent link again.
edge.clear_parent_link();
Some(edge)
}
};

*self.len_mut() -= 1;
(key, val, edge)
}
}

/// Removes a key-value pair from the beginning of the node and returns the pair.
/// Also removes the edge that was to the left of that pair and, if the node is
/// internal, returns the orphaned subtree that this edge owned.
fn pop_front(&mut self) -> (K, V, Option<Root<K, V>>) {
debug_assert!(self.len() > 0);

let old_len = self.len();

unsafe {
let key = slice_remove(self.key_area_mut(..old_len), 0);
let val = slice_remove(self.val_area_mut(..old_len), 0);
let edge = match self.reborrow_mut().force() {
ForceResult::Leaf(_) => None,
ForceResult::Internal(mut internal) => {
let node = slice_remove(internal.edge_area_mut(..old_len + 1), 0);
let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData };
// Currently, clearing the parent link is superfluous, because we will
// insert the node elsewhere and set its parent link again.
edge.clear_parent_link();

internal.correct_childrens_parent_links(0..old_len);

Some(edge)
}
};

*self.len_mut() -= 1;

(key, val, edge)
}
}
}

impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
@@ -1399,18 +1306,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
mut self,
track_right_edge_idx: usize,
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
unsafe {
let (k, v, edge) = self.left_child.pop();

let (k, v) = self.parent.replace_kv(k, v);

match self.right_child.reborrow_mut().force() {
ForceResult::Leaf(mut leaf) => leaf.push_front(k, v),
ForceResult::Internal(mut internal) => internal.push_front(k, v, edge.unwrap()),
}

Handle::new_edge(self.right_child, 1 + track_right_edge_idx)
}
self.bulk_steal_left(1);
unsafe { Handle::new_edge(self.right_child, 1 + track_right_edge_idx) }
}

/// Removes a key-value pair from the right child and places it in the key-value storage
@@ -1421,18 +1318,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
mut self,
track_left_edge_idx: usize,
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
unsafe {
let (k, v, edge) = self.right_child.pop_front();

let (k, v) = self.parent.replace_kv(k, v);

match self.left_child.reborrow_mut().force() {
ForceResult::Leaf(mut leaf) => leaf.push(k, v),
ForceResult::Internal(mut internal) => internal.push(k, v, edge.unwrap()),
}

Handle::new_edge(self.left_child, track_left_edge_idx)
}
self.bulk_steal_right(1);
unsafe { Handle::new_edge(self.left_child, track_left_edge_idx) }
}

/// This does stealing similar to `steal_left` but steals multiple elements at once.
8 changes: 4 additions & 4 deletions library/alloc/src/collections/btree/remove.rs
Original file line number Diff line number Diff line change
@@ -121,25 +121,25 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
self,
) -> Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>> {
match self.forget_type().choose_parent_kv() {
Ok(Left(left_parent_kv)) => {
Ok(Left(mut left_parent_kv)) => {
debug_assert_eq!(left_parent_kv.right_child_len(), MIN_LEN - 1);
if left_parent_kv.can_merge() {
let parent = left_parent_kv.merge_tracking_parent();
Some(parent)
} else {
debug_assert!(left_parent_kv.left_child_len() > MIN_LEN);
left_parent_kv.steal_left(0);
left_parent_kv.bulk_steal_left(1);
None
}
}
Ok(Right(right_parent_kv)) => {
Ok(Right(mut right_parent_kv)) => {
debug_assert_eq!(right_parent_kv.left_child_len(), MIN_LEN - 1);
if right_parent_kv.can_merge() {
let parent = right_parent_kv.merge_tracking_parent();
Some(parent)
} else {
debug_assert!(right_parent_kv.right_child_len() > MIN_LEN);
right_parent_kv.steal_right(0);
right_parent_kv.bulk_steal_right(1);
None
}
}
2 changes: 2 additions & 0 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -1842,6 +1842,7 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
#[inline]
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
extern "rust-intrinsic" {
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
}

@@ -1926,6 +1927,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
#[inline]
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
extern "rust-intrinsic" {
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
fn copy<T>(src: *const T, dst: *mut T, count: usize);
}

1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -126,6 +126,7 @@
#![feature(auto_traits)]
#![feature(or_patterns)]
#![feature(prelude_import)]
#![feature(raw_ref_macros)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
2 changes: 1 addition & 1 deletion library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
@@ -633,7 +633,7 @@ impl<T: ?Sized> *const T {
}

/// Calculates the offset from a pointer using wrapping arithmetic.
/// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
3 changes: 0 additions & 3 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
@@ -687,7 +687,6 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
pub const unsafe fn read<T>(src: *const T) -> T {
// `copy_nonoverlapping` takes care of debug_assert.
let mut tmp = MaybeUninit::<T>::uninit();
// SAFETY: the caller must guarantee that `src` is valid for reads.
// `src` cannot overlap `tmp` because `tmp` was just allocated on
@@ -787,7 +786,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
#[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
// `copy_nonoverlapping` takes care of debug_assert.
let mut tmp = MaybeUninit::<T>::uninit();
// SAFETY: the caller must guarantee that `src` is valid for reads.
// `src` cannot overlap `tmp` because `tmp` was just allocated on
@@ -988,7 +986,6 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
// `dst` cannot overlap `src` because the caller has mutable access
// to `dst` while `src` is owned by this function.
unsafe {
// `copy_nonoverlapping` takes care of debug_assert.
copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
}
mem::forget(src);
2 changes: 1 addition & 1 deletion library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
@@ -740,7 +740,7 @@ impl<T: ?Sized> *mut T {
}

/// Calculates the offset from a pointer using wrapping arithmetic.
/// (convenience for `.wrapping_offset((count as isize).wrapping_sub())`)
/// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
///
/// `count` is in units of T; e.g., a `count` of 3 represents a pointer
/// offset of `3 * size_of::<T>()` bytes.
7 changes: 3 additions & 4 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -542,10 +542,9 @@ impl<T> [T] {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn swap(&mut self, a: usize, b: usize) {
// Can't take two mutable loans from one vector, so instead just cast
// them to their raw pointers to do the swap.
let pa: *mut T = &mut self[a];
let pb: *mut T = &mut self[b];
// Can't take two mutable loans from one vector, so instead use raw pointers.
let pa = ptr::raw_mut!(self[a]);
let pb = ptr::raw_mut!(self[b]);
// SAFETY: `pa` and `pb` have been created from safe mutable references and refer
// to elements in the slice and therefore are guaranteed to be valid and aligned.
// Note that accessing the elements behind `a` and `b` is checked and will
5 changes: 1 addition & 4 deletions src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
@@ -111,10 +111,7 @@ crate fn render<T: Print, S: Print>(
<section id=\"search\" class=\"content hidden\"></section>\
<section class=\"footer\"></section>\
{after_content}\
<script>\
window.rootPath = \"{root_path}\";\
window.currentCrate = \"{krate}\";\
</script>\
<div id=\"rustdoc-vars\" data-root-path=\"{root_path}\" data-current-crate=\"{krate}\"></div>
<script src=\"{static_root_path}main{suffix}.js\"></script>\
{static_extra_scripts}\
{extra_scripts}\
2 changes: 2 additions & 0 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
@@ -1313,6 +1313,8 @@ fn init_id_map() -> FxHashMap<String, usize> {
map.insert("toggle-all-docs".to_owned(), 1);
map.insert("all-types".to_owned(), 1);
map.insert("default-settings".to_owned(), 1);
map.insert("rustdoc-vars".to_owned(), 1);
map.insert("sidebar-vars".to_owned(), 1);
// This is the list of IDs used by rustdoc sections.
map.insert("fields".to_owned(), 1);
map.insert("variants".to_owned(), 1);
7 changes: 2 additions & 5 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
@@ -4216,11 +4216,8 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer, cache:
let relpath = if it.is_mod() { "../" } else { "" };
write!(
buffer,
"<script>window.sidebarCurrent = {{\
name: \"{name}\", \
ty: \"{ty}\", \
relpath: \"{path}\"\
}};</script>",
"<div id=\"sidebar-vars\" data-name=\"{name}\" data-ty=\"{ty}\" data-relpath=\"{path}\">\
</div>",
name = it.name.unwrap_or(kw::Empty),
ty = it.type_(),
path = relpath
39 changes: 27 additions & 12 deletions src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// From rust:
/* global ALIASES, currentCrate, rootPath */
/* global ALIASES */

// Local js definitions:
/* global addClass, getCurrentValue, hasClass */
@@ -40,6 +40,21 @@ if (!DOMTokenList.prototype.remove) {
};
}

(function () {
var rustdocVars = document.getElementById("rustdoc-vars");
if (rustdocVars) {
window.rootPath = rustdocVars.attributes["data-root-path"].value;
window.currentCrate = rustdocVars.attributes["data-current-crate"].value;
}
var sidebarVars = document.getElementById("sidebar-vars");
if (sidebarVars) {
window.sidebarCurrent = {
name: sidebarVars.attributes["data-name"].value,
ty: sidebarVars.attributes["data-ty"].value,
relpath: sidebarVars.attributes["data-relpath"].value,
};
}
}());

// Gets the human-readable string for the virtual-key code of the
// given KeyboardEvent, ev.
@@ -565,7 +580,7 @@ function defocusSearchBar() {
var i, match,
url = document.location.href,
stripped = "",
len = rootPath.match(/\.\.\//g).length + 1;
len = window.rootPath.match(/\.\.\//g).length + 1;

for (i = 0; i < len; ++i) {
match = url.match(/\/[^\/]*$/);
@@ -1504,15 +1519,15 @@ function defocusSearchBar() {

if (type === "mod") {
displayPath = path + "::";
href = rootPath + path.replace(/::/g, "/") + "/" +
href = window.rootPath + path.replace(/::/g, "/") + "/" +
name + "/index.html";
} else if (type === "primitive" || type === "keyword") {
displayPath = "";
href = rootPath + path.replace(/::/g, "/") +
href = window.rootPath + path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
} else if (type === "externcrate") {
displayPath = "";
href = rootPath + name + "/index.html";
href = window.rootPath + name + "/index.html";
} else if (item.parent !== undefined) {
var myparent = item.parent;
var anchor = "#" + type + "." + name;
@@ -1535,13 +1550,13 @@ function defocusSearchBar() {
} else {
displayPath = path + "::" + myparent.name + "::";
}
href = rootPath + path.replace(/::/g, "/") +
href = window.rootPath + path.replace(/::/g, "/") +
"/" + pageType +
"." + pageName +
".html" + anchor;
} else {
displayPath = item.path + "::";
href = rootPath + item.path.replace(/::/g, "/") +
href = window.rootPath + item.path.replace(/::/g, "/") +
"/" + type + "." + name + ".html";
}
return [displayPath, href];
@@ -1973,7 +1988,7 @@ function defocusSearchBar() {
startSearch();

// Draw a convenient sidebar of known crates if we have a listing
if (rootPath === "../" || rootPath === "./") {
if (window.rootPath === "../" || window.rootPath === "./") {
var sidebar = document.getElementsByClassName("sidebar-elems")[0];
if (sidebar) {
var div = document.createElement("div");
@@ -1992,11 +2007,11 @@ function defocusSearchBar() {
crates.sort();
for (var i = 0; i < crates.length; ++i) {
var klass = "crate";
if (rootPath !== "./" && crates[i] === window.currentCrate) {
if (window.rootPath !== "./" && crates[i] === window.currentCrate) {
klass += " current";
}
var link = document.createElement("a");
link.href = rootPath + crates[i] + "/index.html";
link.href = window.rootPath + crates[i] + "/index.html";
// The summary in the search index has HTML, so we need to
// dynamically render it as plaintext.
link.title = convertHTMLToPlaintext(rawSearchIndex[crates[i]].doc);
@@ -2118,7 +2133,7 @@ function defocusSearchBar() {

var libs = Object.getOwnPropertyNames(imp);
for (var i = 0, llength = libs.length; i < llength; ++i) {
if (libs[i] === currentCrate) { continue; }
if (libs[i] === window.currentCrate) { continue; }
var structs = imp[libs[i]];

struct_loop:
@@ -2143,7 +2158,7 @@ function defocusSearchBar() {
var href = elem.getAttribute("href");

if (href && href.indexOf("http") !== 0) {
elem.setAttribute("href", rootPath + href);
elem.setAttribute("href", window.rootPath + href);
}
});

17 changes: 17 additions & 0 deletions src/test/ui/consts/intrinsic_without_const_stab.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![feature(intrinsics, staged_api, const_intrinsic_copy)]
#![stable(feature = "core", since = "1.6.0")]

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
#[inline]
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
// Const stability attributes are not inherited from parent items.
extern "rust-intrinsic" {
fn copy<T>(src: *const T, dst: *mut T, count: usize);
}

unsafe { copy(src, dst, count) }
//~^ ERROR calls in constant functions are limited to constant functions
}

fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/consts/intrinsic_without_const_stab.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/intrinsic_without_const_stab.rs:13:14
|
LL | unsafe { copy(src, dst, count) }
| ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0015`.
15 changes: 15 additions & 0 deletions src/test/ui/consts/intrinsic_without_const_stab_fail.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(intrinsics, staged_api, const_intrinsic_copy)]
#![stable(feature = "core", since = "1.6.0")]

extern "rust-intrinsic" {
fn copy<T>(src: *const T, dst: *mut T, count: usize);
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
#[inline]
pub const unsafe fn stuff<T>(src: *const T, dst: *mut T, count: usize) {
unsafe { copy(src, dst, count) } //~ ERROR calls in constant functions are limited
}

fn main() {}
9 changes: 9 additions & 0 deletions src/test/ui/consts/intrinsic_without_const_stab_fail.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/intrinsic_without_const_stab_fail.rs:12:14
|
LL | unsafe { copy(src, dst, count) }
| ^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0015`.
Original file line number Diff line number Diff line change
@@ -32,11 +32,11 @@ LL | Struct { a, _ } = Struct { a: 1, b: 2 };
|
help: include the missing field in the pattern
|
LL | Struct { a, b, _ } = Struct { a: 1, b: 2 };
LL | Struct { a, b _ } = Struct { a: 1, b: 2 };
| ^^^
help: if you don't care about this missing field, you can explicitly ignore it
|
LL | Struct { a, .., _ } = Struct { a: 1, b: 2 };
LL | Struct { a, .. _ } = Struct { a: 1, b: 2 };
| ^^^^

error: aborting due to 5 previous errors
9 changes: 9 additions & 0 deletions src/test/ui/error-codes/E0027.rs
Original file line number Diff line number Diff line change
@@ -3,12 +3,21 @@ struct Dog {
age: u32,
}


fn main() {
let d = Dog { name: "Rusty".to_string(), age: 8 };

match d {
Dog { age: x } => {} //~ ERROR pattern does not mention field `name`
}
match d {
// trailing comma
Dog { name: x, } => {} //~ ERROR pattern does not mention field `age`
}
match d {
// trailing comma with weird whitespace
Dog { name: x , } => {} //~ ERROR pattern does not mention field `age`
}
match d {
Dog {} => {} //~ ERROR pattern does not mention fields `name`, `age`
}
36 changes: 33 additions & 3 deletions src/test/ui/error-codes/E0027.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0027]: pattern does not mention field `name`
--> $DIR/E0027.rs:10:9
--> $DIR/E0027.rs:11:9
|
LL | Dog { age: x } => {}
| ^^^^^^^^^^^^^^ missing field `name`
@@ -13,8 +13,38 @@ help: if you don't care about this missing field, you can explicitly ignore it
LL | Dog { age: x, .. } => {}
| ^^^^

error[E0027]: pattern does not mention field `age`
--> $DIR/E0027.rs:15:9
|
LL | Dog { name: x, } => {}
| ^^^^^^^^^^^^^^^^ missing field `age`
|
help: include the missing field in the pattern
|
LL | Dog { name: x, age } => {}
| ^^^^^
help: if you don't care about this missing field, you can explicitly ignore it
|
LL | Dog { name: x, .. } => {}
| ^^^^

error[E0027]: pattern does not mention field `age`
--> $DIR/E0027.rs:19:9
|
LL | Dog { name: x , } => {}
| ^^^^^^^^^^^^^^^^^^ missing field `age`
|
help: include the missing field in the pattern
|
LL | Dog { name: x, age } => {}
| ^^^^^
help: if you don't care about this missing field, you can explicitly ignore it
|
LL | Dog { name: x, .. } => {}
| ^^^^

error[E0027]: pattern does not mention fields `name`, `age`
--> $DIR/E0027.rs:13:9
--> $DIR/E0027.rs:22:9
|
LL | Dog {} => {}
| ^^^^^^ missing fields `name`, `age`
@@ -28,6 +58,6 @@ help: if you don't care about these missing fields, you can explicitly ignore th
LL | Dog { .. } => {}
| ^^^^^^

error: aborting due to 2 previous errors
error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0027`.
18 changes: 18 additions & 0 deletions src/test/ui/error-codes/E0040.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// run-rustfix
struct Foo {
x: i32,
}

impl Drop for Foo {
fn drop(&mut self) {
println!("kaboom");
}
}

fn main() {
let mut x = Foo { x: -7 };
x.x = 0;
println!("{}", x.x);
drop(x);
//~^ ERROR E0040
}
3 changes: 3 additions & 0 deletions src/test/ui/error-codes/E0040.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// run-rustfix
struct Foo {
x: i32,
}
@@ -10,6 +11,8 @@ impl Drop for Foo {

fn main() {
let mut x = Foo { x: -7 };
x.x = 0;
println!("{}", x.x);
x.drop();
//~^ ERROR E0040
}
10 changes: 5 additions & 5 deletions src/test/ui/error-codes/E0040.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0040]: explicit use of destructor method
--> $DIR/E0040.rs:13:7
--> $DIR/E0040.rs:16:7
|
LL | x.drop();
| ^^^^
| |
| explicit destructor calls not allowed
| help: consider using `drop` function: `drop(x)`
| --^^^^--
| | |
| | explicit destructor calls not allowed
| help: consider using `drop` function: `drop(x)`

error: aborting due to previous error

16 changes: 16 additions & 0 deletions src/test/ui/explicit/explicit-call-to-dtor.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// run-rustfix
struct Foo {
x: isize
}

impl Drop for Foo {
fn drop(&mut self) {
println!("kaboom");
}
}

fn main() {
let x = Foo { x: 3 };
println!("{}", x.x);
drop(x); //~ ERROR explicit use of destructor method
}
2 changes: 2 additions & 0 deletions src/test/ui/explicit/explicit-call-to-dtor.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// run-rustfix
struct Foo {
x: isize
}
@@ -10,5 +11,6 @@ impl Drop for Foo {

fn main() {
let x = Foo { x: 3 };
println!("{}", x.x);
x.drop(); //~ ERROR explicit use of destructor method
}
10 changes: 5 additions & 5 deletions src/test/ui/explicit/explicit-call-to-dtor.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0040]: explicit use of destructor method
--> $DIR/explicit-call-to-dtor.rs:13:7
--> $DIR/explicit-call-to-dtor.rs:15:7
|
LL | x.drop();
| ^^^^
| |
| explicit destructor calls not allowed
| help: consider using `drop` function: `drop(x)`
| --^^^^--
| | |
| | explicit destructor calls not allowed
| help: consider using `drop` function: `drop(x)`

error: aborting due to previous error

26 changes: 26 additions & 0 deletions src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// run-rustfix
struct Foo {
x: isize
}

#[allow(drop_bounds)]
trait Bar: Drop {
fn blah(&self);
}

impl Drop for Foo {
fn drop(&mut self) {
println!("kaboom");
}
}

impl Bar for Foo {
fn blah(&self) {
drop(self); //~ ERROR explicit use of destructor method
}
}

fn main() {
let x = Foo { x: 3 };
println!("{}", x.x);
}
5 changes: 4 additions & 1 deletion src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// run-rustfix
struct Foo {
x: isize
}

trait Bar : Drop {
#[allow(drop_bounds)]
trait Bar: Drop {
fn blah(&self);
}

@@ -20,4 +22,5 @@ impl Bar for Foo {

fn main() {
let x = Foo { x: 3 };
println!("{}", x.x);
}
10 changes: 5 additions & 5 deletions src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0040]: explicit use of destructor method
--> $DIR/explicit-call-to-supertrait-dtor.rs:17:14
--> $DIR/explicit-call-to-supertrait-dtor.rs:19:14
|
LL | self.drop();
| ^^^^
| |
| explicit destructor calls not allowed
| help: consider using `drop` function: `drop(self)`
| -----^^^^--
| | |
| | explicit destructor calls not allowed
| help: consider using `drop` function: `drop(self)`

error: aborting due to previous error

10 changes: 10 additions & 0 deletions src/test/ui/illegal-ufcs-drop.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// run-rustfix
struct Foo;

impl Drop for Foo {
fn drop(&mut self) {}
}

fn main() {
drop(&mut Foo) //~ ERROR explicit use of destructor method
}
1 change: 1 addition & 0 deletions src/test/ui/illegal-ufcs-drop.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// run-rustfix
struct Foo;

impl Drop for Foo {
2 changes: 1 addition & 1 deletion src/test/ui/illegal-ufcs-drop.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0040]: explicit use of destructor method
--> $DIR/illegal-ufcs-drop.rs:8:5
--> $DIR/illegal-ufcs-drop.rs:9:5
|
LL | Drop::drop(&mut Foo)
| ^^^^^^^^^^
5 changes: 5 additions & 0 deletions src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,9 @@ unsafe fn deny_level() {
//~^ ERROR dereference of raw pointer is unsafe and requires unsafe block
VOID = ();
//~^ ERROR use of mutable static is unsafe and requires unsafe block

unsafe {}
//~^ ERROR unnecessary `unsafe` block
}

// Check that `unsafe_op_in_unsafe_fn` works starting from the `warn` level.
@@ -25,6 +28,8 @@ unsafe fn warning_level() {
//~^ ERROR dereference of raw pointer is unsafe and requires unsafe block
VOID = ();
//~^ ERROR use of mutable static is unsafe and requires unsafe block
unsafe {}
//~^ ERROR unnecessary `unsafe` block
}

unsafe fn explicit_block() {
50 changes: 34 additions & 16 deletions src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr
Original file line number Diff line number Diff line change
@@ -27,78 +27,96 @@ LL | VOID = ();
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior

error: unnecessary `unsafe` block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5
|
LL | unsafe {}
| ^^^^^^ unnecessary `unsafe` block
|
note: the lint level is defined here
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9
|
LL | #![deny(unused_unsafe)]
| ^^^^^^^^^^^^^

error: call to unsafe function is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:5
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:5
|
LL | unsf();
| ^^^^^^ call to unsafe function
|
note: the lint level is defined here
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:8
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:23:8
|
LL | #[deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]`
= note: consult the function's documentation for information on how to avoid undefined behavior

error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
|
LL | *PTR;
| ^^^^ dereference of raw pointer
|
= note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior

error: use of mutable static is unsafe and requires unsafe block (error E0133)
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
|
LL | VOID = ();
| ^^^^^^^^^ use of mutable static
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior

error: unnecessary `unsafe` block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:40:14
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
|
LL | unsafe {}
| ^^^^^^ unnecessary `unsafe` block

error: unnecessary `unsafe` block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:45:14
|
LL | unsafe { unsafe { unsf() } }
| ------ ^^^^^^ unnecessary `unsafe` block
| |
| because it's nested under this `unsafe` block
|
note: the lint level is defined here
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:3:9
|
LL | #![deny(unused_unsafe)]
| ^^^^^^^^^^^^^

error: unnecessary `unsafe` block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:51:5
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:56:5
|
LL | unsafe fn allow_level() {
| ----------------------- because it's nested under this `unsafe` fn
...
LL | unsafe { unsf() }
| ^^^^^^ unnecessary `unsafe` block

error: unnecessary `unsafe` block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:63:9
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:68:9
|
LL | unsafe fn nested_allow_level() {
| ------------------------------ because it's nested under this `unsafe` fn
...
LL | unsafe { unsf() }
| ^^^^^^ unnecessary `unsafe` block

error[E0133]: call to unsafe function is unsafe and requires unsafe block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:69:5
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:74:5
|
LL | unsf();
| ^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior

error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:9
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:9
|
LL | unsf();
| ^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior

error: aborting due to 11 previous errors
error: aborting due to 13 previous errors

For more information about this error, try `rustc --explain E0133`.
3 changes: 1 addition & 2 deletions src/tools/rustdoc-js/tester.js
Original file line number Diff line number Diff line change
@@ -263,8 +263,7 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) {
"handleAliases", "getQuery", "buildIndex", "execQuery", "execSearch"];

ALIASES = {};
finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
finalJS += 'var rootPath = "../";\n';
finalJS += 'window = { "currentCrate": "' + crate + '", rootPath: "../" };\n';
finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs);
finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);