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 #72612

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
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
35 changes: 26 additions & 9 deletions src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,12 +867,10 @@ impl<T: ?Sized> Arc<T> {
unsafe fn drop_slow(&mut self) {
// Destroy the data at this time, even though we may not free the box
// allocation itself (there may still be weak pointers lying around).
ptr::drop_in_place(&mut self.ptr.as_mut().data);
ptr::drop_in_place(Self::get_mut_unchecked(self));

if self.inner().weak.fetch_sub(1, Release) == 1 {
acquire!(self.inner().weak);
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
}
// Drop the weak ref collectively held by all strong references
drop(Weak { ptr: self.ptr });
}

#[inline]
Expand Down Expand Up @@ -1204,7 +1202,7 @@ impl<T: Clone> Arc<T> {

// As with `get_mut()`, the unsafety is ok because our reference was
// either unique to begin with, or became one upon cloning the contents.
unsafe { &mut this.ptr.as_mut().data }
unsafe { Self::get_mut_unchecked(this) }
}
}

Expand Down Expand Up @@ -1280,7 +1278,9 @@ impl<T: ?Sized> Arc<T> {
#[inline]
#[unstable(feature = "get_mut_unchecked", issue = "63292")]
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
&mut this.ptr.as_mut().data
// We are careful to *not* create a reference covering the "count" fields, as
// this would alias with concurrent access to the reference counts (e.g. by `Weak`).
&mut (*this.ptr.as_ptr()).data
}

/// Determine whether this is the unique reference (including weak refs) to
Expand Down Expand Up @@ -1571,6 +1571,13 @@ impl<T> Weak<T> {
}
}

/// Helper type to allow accessing the reference counts without
/// making any assertions about the data field.
struct WeakInner<'a> {
weak: &'a atomic::AtomicUsize,
strong: &'a atomic::AtomicUsize,
}

impl<T: ?Sized> Weak<T> {
/// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying
/// dropping of the inner value if successful.
Expand Down Expand Up @@ -1678,8 +1685,18 @@ impl<T: ?Sized> Weak<T> {
/// Returns `None` when the pointer is dangling and there is no allocated `ArcInner`,
/// (i.e., when this `Weak` was created by `Weak::new`).
#[inline]
fn inner(&self) -> Option<&ArcInner<T>> {
if is_dangling(self.ptr) { None } else { Some(unsafe { self.ptr.as_ref() }) }
fn inner(&self) -> Option<WeakInner<'_>> {
if is_dangling(self.ptr) {
None
} else {
// We are careful to *not* create a reference covering the "data" field, as
// the field may be mutated concurrently (for example, if the last `Arc`
// is dropped, the data field will be dropped in-place).
Some(unsafe {
let ptr = self.ptr.as_ptr();
WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak }
})
}
}

/// Returns `true` if the two `Weak`s point to the same allocation (similar to
Expand Down
70 changes: 36 additions & 34 deletions src/librustc_ast_lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,20 +974,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

fn lower_expr_asm(&mut self, sp: Span, asm: &InlineAsm) -> hir::ExprKind<'hir> {
let asm_arch = if let Some(asm_arch) = self.sess.asm_arch {
asm_arch
} else {
if self.sess.asm_arch.is_none() {
struct_span_err!(self.sess, sp, E0472, "asm! is unsupported on this target").emit();
return hir::ExprKind::Err;
};
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
match asm_arch {
asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64 => {}
_ => self
.sess
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
.emit(),
}
}
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
&& !matches!(
self.sess.asm_arch,
Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)
)
{
self.sess
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
.emit();
}

// Lower operands to HIR, filter_map skips any operands with invalid
Expand All @@ -1001,10 +999,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(match reg {
InlineAsmRegOrRegClass::Reg(s) => asm::InlineAsmRegOrRegClass::Reg(
asm::InlineAsmReg::parse(
asm_arch,
|feature| {
self.sess.target_features.contains(&Symbol::intern(feature))
},
sess.asm_arch?,
|feature| sess.target_features.contains(&Symbol::intern(feature)),
s,
)
.map_err(|e| {
Expand All @@ -1015,7 +1011,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
),
InlineAsmRegOrRegClass::RegClass(s) => {
asm::InlineAsmRegOrRegClass::RegClass(
asm::InlineAsmRegClass::parse(asm_arch, s)
asm::InlineAsmRegClass::parse(sess.asm_arch?, s)
.map_err(|e| {
let msg = format!(
"invalid register class `{}`: {}",
Expand All @@ -1029,33 +1025,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
})
};
let op = match op {
InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In {
reg: lower_reg(*reg)?,

// lower_reg is executed last because we need to lower all
// sub-expressions even if we throw them away later.
let op = match *op {
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
expr: self.lower_expr_mut(expr),
reg: lower_reg(reg)?,
},
InlineAsmOperand::Out { reg, late, expr } => hir::InlineAsmOperand::Out {
reg: lower_reg(*reg)?,
late: *late,
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
late,
expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
reg: lower_reg(reg)?,
},
InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut {
reg: lower_reg(*reg)?,
late: *late,
expr: self.lower_expr_mut(expr),
},
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
InlineAsmOperand::InOut { reg, late, ref expr } => {
hir::InlineAsmOperand::InOut {
late,
expr: self.lower_expr_mut(expr),
reg: lower_reg(reg)?,
}
}
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
hir::InlineAsmOperand::SplitInOut {
reg: lower_reg(*reg)?,
late: *late,
late,
in_expr: self.lower_expr_mut(in_expr),
out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
reg: lower_reg(reg)?,
}
}
InlineAsmOperand::Const { expr } => {
InlineAsmOperand::Const { ref expr } => {
hir::InlineAsmOperand::Const { expr: self.lower_expr_mut(expr) }
}
InlineAsmOperand::Sym { expr } => {
InlineAsmOperand::Sym { ref expr } => {
hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
}
};
Expand All @@ -1069,6 +1070,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

// Validate template modifiers against the register classes for the operands
let asm_arch = sess.asm_arch.unwrap();
for p in &asm.template {
if let InlineAsmTemplatePiece::Placeholder {
operand_idx,
Expand Down
11 changes: 11 additions & 0 deletions src/librustc_error_codes/error_codes/E0617.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ Certain Rust types must be cast before passing them to a variadic function,
because of arcane ABI rules dictated by the C standard. To fix the error,
cast the value to the type specified by the error message (which you may need
to import from `std::os::raw`).

In this case, `c_double` has the same size as `f64` so we can use it directly:

```
# extern {
# fn printf(c: *const i8, ...);
# }
unsafe {
printf(::std::ptr::null(), 0f64); // ok!
}
```
1 change: 1 addition & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
UNUSED_ALLOCATION,
UNUSED_DOC_COMMENTS,
UNUSED_EXTERN_CRATES,
UNUSED_CRATE_DEPENDENCIES,
UNUSED_FEATURES,
UNUSED_LABELS,
UNUSED_PARENS,
Expand Down
29 changes: 29 additions & 0 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob

use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind};
use rustc_ast::{ast, attr};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_errors::struct_span_err;
Expand All @@ -18,6 +19,7 @@ use rustc_middle::middle::cstore::{
};
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, CrateType};
use rustc_session::lint;
use rustc_session::output::validate_crate_name;
use rustc_session::search_paths::PathKind;
use rustc_session::{CrateDisambiguator, Session};
Expand Down Expand Up @@ -49,6 +51,7 @@ pub struct CrateLoader<'a> {
local_crate_name: Symbol,
// Mutable output.
cstore: CStore,
used_extern_options: FxHashSet<Symbol>,
}

pub enum LoadedMacro {
Expand Down Expand Up @@ -205,6 +208,7 @@ impl<'a> CrateLoader<'a> {
allocator_kind: None,
has_global_allocator: false,
},
used_extern_options: Default::default(),
}
}

Expand Down Expand Up @@ -445,6 +449,9 @@ impl<'a> CrateLoader<'a> {
dep_kind: DepKind,
dep: Option<(&'b CratePaths, &'b CrateDep)>,
) -> CrateNum {
if dep.is_none() {
self.used_extern_options.insert(name);
}
self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
}

Expand Down Expand Up @@ -839,6 +846,26 @@ impl<'a> CrateLoader<'a> {
});
}

fn report_unused_deps(&mut self, krate: &ast::Crate) {
// Make a point span rather than covering the whole file
let span = krate.span.shrink_to_lo();
// Complain about anything left over
for (name, _) in self.sess.opts.externs.iter() {
if !self.used_extern_options.contains(&Symbol::intern(name)) {
self.sess.parse_sess.buffer_lint(
lint::builtin::UNUSED_CRATE_DEPENDENCIES,
span,
ast::CRATE_NODE_ID,
&format!(
"external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`",
name,
self.local_crate_name,
name),
);
}
}
}

pub fn postprocess(&mut self, krate: &ast::Crate) {
self.inject_profiler_runtime();
self.inject_allocator_crate(krate);
Expand All @@ -847,6 +874,8 @@ impl<'a> CrateLoader<'a> {
if log_enabled!(log::Level::Info) {
dump_crates(&self.cstore);
}

self.report_unused_deps(krate);
}

pub fn process_extern_crate(
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_passes/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::Span;

#[derive(Clone, Copy, Debug, PartialEq)]
Expand Down Expand Up @@ -203,7 +204,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
label: &Destination,
cf_type: &str,
) -> bool {
if self.cx == LabeledBlock {
if !span.is_desugaring(DesugaringKind::QuestionMark) && self.cx == LabeledBlock {
if label.label.is_none() {
struct_span_err!(
self.sess,
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_session/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ declare_lint! {
"extern crates that are never used"
}

declare_lint! {
pub UNUSED_CRATE_DEPENDENCIES,
Allow,
"crate dependencies that are never used"
}

declare_lint! {
pub UNUSED_QUALIFICATIONS,
Allow,
Expand Down Expand Up @@ -523,6 +529,7 @@ declare_lint_pass! {
UNCONDITIONAL_PANIC,
UNUSED_IMPORTS,
UNUSED_EXTERN_CRATES,
UNUSED_CRATE_DEPENDENCIES,
UNUSED_QUALIFICATIONS,
UNKNOWN_LINTS,
UNUSED_VARIABLES,
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/asm/issue-72570.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// only-x86_64

#![feature(asm)]

fn main() {
unsafe {
asm!("", in("invalid") "".len());
//~^ ERROR: invalid register `invalid`: unknown register
}
}
8 changes: 8 additions & 0 deletions src/test/ui/asm/issue-72570.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: invalid register `invalid`: unknown register
--> $DIR/issue-72570.rs:7:18
|
LL | asm!("", in("invalid") "".len());
| ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

12 changes: 12 additions & 0 deletions src/test/ui/label/label_break_value_desugared_break.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// compile-flags: --edition 2018
#![feature(label_break_value, try_blocks)]

// run-pass
fn main() {
let _: Result<(), ()> = try {
'foo: {
Err(())?;
break 'foo;
}
};
}
1 change: 1 addition & 0 deletions src/test/ui/unused-crate-deps/auxiliary/bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub const BAR: &str = "bar";
5 changes: 5 additions & 0 deletions src/test/ui/unused-crate-deps/auxiliary/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// edition:2018
// aux-crate:bar=bar.rs

pub const FOO: &str = "foo";
pub use bar::BAR;
Loading