Skip to content

Commit

Permalink
Auto merge of rust-lang#87434 - Manishearth:rollup-b09njin, r=Manishe…
Browse files Browse the repository at this point in the history
…arth

Rollup of 9 pull requests

Successful merges:

 - rust-lang#87348 (Fix span when suggesting to add an associated type bound)
 - rust-lang#87359 (Remove detection of rustup and cargo in 'missing extern crate' diagnostics)
 - rust-lang#87370 (Add support for powerpc-unknown-freebsd)
 - rust-lang#87389 (Rename `known_attrs` to `expanded_inert_attrs` and move to rustc_expand)
 - rust-lang#87395 (Clear up std::env::set_var panic section.)
 - rust-lang#87403 (Implement `AssignToDroppingUnionField` in THIR unsafeck)
 - rust-lang#87410 (Mark `format_args_nl` as `#[doc(hidden)]`)
 - rust-lang#87419 (IEEE 754 is not an RFC)
 - rust-lang#87422 (DOC: remove unnecessary feature crate attribute from example code)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 24, 2021
2 parents 18840b0 + acfa3ac commit bddb59c
Show file tree
Hide file tree
Showing 22 changed files with 493 additions and 62 deletions.
2 changes: 1 addition & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Libraries
- [`leading_zeros`, and `trailing_zeros` are now available on all
`NonZero` integer types.][84082]
- [`{f32, f64}::from_str` now parse and print special values
(`NaN`, `-0`) according to IEEE RFC 754.][78618]
(`NaN`, `-0`) according to IEEE 754.][78618]
- [You can now index into slices using `(Bound<usize>, Bound<usize>)`.][77704]
- [Add the `BITS` associated constant to all numeric types.][82565]

Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::expand::{self, AstFragment, Invocation};
use crate::module::DirOwnership;

use rustc_ast::attr::MarkedAttrs;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
Expand Down Expand Up @@ -951,6 +952,10 @@ pub struct ExtCtxt<'a> {
///
/// `Ident` is the module name.
pub(super) extern_mod_loaded: OnExternModLoaded<'a>,
/// When we 'expand' an inert attribute, we leave it
/// in the AST, but insert it here so that we know
/// not to expand it again.
pub(super) expanded_inert_attrs: MarkedAttrs,
}

impl<'a> ExtCtxt<'a> {
Expand All @@ -977,6 +982,7 @@ impl<'a> ExtCtxt<'a> {
},
force_mode: false,
expansions: FxHashMap::default(),
expanded_inert_attrs: MarkedAttrs::new(),
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
}
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
self.cx.sess.mark_attr_known(&attr);
self.cx.expanded_inert_attrs.mark(&attr);
if *mark_used {
self.cx.sess.mark_attr_used(&attr);
}
Expand Down Expand Up @@ -1040,7 +1040,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
item.visit_attrs(|attrs| {
attr = attrs
.iter()
.position(|a| !self.cx.sess.is_attr_known(a) && !is_builtin_attr(a))
.position(|a| !self.cx.expanded_inert_attrs.is_marked(a) && !is_builtin_attr(a))
.map(|attr_pos| {
let attr = attrs.remove(attr_pos);
let following_derives = attrs[attr_pos..]
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,10 @@ impl CrateError {
locator.triple
));
}
if missing_core && std::env::var("RUSTUP_HOME").is_ok() {
// NOTE: this suggests using rustup, even though the user may not have it installed.
// That's because they could choose to install it; or this may give them a hint which
// target they need to install from their distro.
if missing_core {
err.help(&format!(
"consider downloading the target with `rustup target add {}`",
locator.triple
Expand All @@ -1097,7 +1100,7 @@ impl CrateError {
current_crate
));
}
if sess.is_nightly_build() && std::env::var("CARGO").is_ok() {
if sess.is_nightly_build() {
err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
}
} else if Some(crate_name)
Expand Down
65 changes: 45 additions & 20 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ impl<T> Trait<T> for X {
assoc_substs,
ty,
msg,
false,
) {
return true;
}
Expand All @@ -646,6 +647,7 @@ impl<T> Trait<T> for X {
assoc_substs,
ty,
msg,
false,
);
}
}
Expand Down Expand Up @@ -771,13 +773,24 @@ fn foo(&self) -> Self::T { String::new() }
) -> bool {
let assoc = self.associated_item(proj_ty.item_def_id);
if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
self.constrain_associated_type_structured_suggestion(
let opaque_local_def_id = def_id.expect_local();
let opaque_hir_id = self.hir().local_def_id_to_hir_id(opaque_local_def_id);
let opaque_hir_ty = match &self.hir().expect_item(opaque_hir_id).kind {
hir::ItemKind::OpaqueTy(opaque_hir_ty) => opaque_hir_ty,
_ => bug!("The HirId comes from a `ty::Opaque`"),
};

let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);

self.constrain_generic_bound_associated_type_structured_suggestion(
db,
self.def_span(def_id),
&assoc,
proj_ty.trait_ref_and_own_substs(self).1,
&trait_ref,
opaque_hir_ty.bounds,
assoc,
assoc_substs,
ty,
&msg,
msg,
true,
)
} else {
false
Expand Down Expand Up @@ -899,6 +912,11 @@ fn foo(&self) -> Self::T { String::new() }

/// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
/// requirement, provide a structured suggestion to constrain it to a given type `ty`.
///
/// `is_bound_surely_present` indicates whether we know the bound we're looking for is
/// inside `bounds`. If that's the case then we can consider `bounds` containing only one
/// trait bound as the one we're looking for. This can help in cases where the associated
/// type is defined on a supertrait of the one present in the bounds.
fn constrain_generic_bound_associated_type_structured_suggestion(
self,
db: &mut DiagnosticBuilder<'_>,
Expand All @@ -908,23 +926,30 @@ fn foo(&self) -> Self::T { String::new() }
assoc_substs: &[ty::GenericArg<'tcx>],
ty: Ty<'tcx>,
msg: &str,
is_bound_surely_present: bool,
) -> bool {
// FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
bounds.iter().any(|bound| match bound {
hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => {
// Relate the type param against `T` in `<A as T>::Foo`.
ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id)
&& self.constrain_associated_type_structured_suggestion(
db,
ptr.span,
assoc,
assoc_substs,
ty,
msg,
)
}
_ => false,
})

let trait_bounds = bounds.iter().filter_map(|bound| match bound {
hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr),
_ => None,
});

let matching_trait_bounds = trait_bounds
.clone()
.filter(|ptr| ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id))
.collect::<Vec<_>>();

let span = match &matching_trait_bounds[..] {
&[ptr] => ptr.span,
&[] if is_bound_surely_present => match &trait_bounds.collect::<Vec<_>>()[..] {
&[ptr] => ptr.span,
_ => return false,
},
_ => return false,
};

self.constrain_associated_type_structured_suggestion(db, span, assoc, assoc_substs, ty, msg)
}

/// Given a span corresponding to a bound, provide a structured suggestion to set an
Expand Down
48 changes: 31 additions & 17 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_middle::mir::BorrowKind;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::Level;
use rustc_span::def_id::{DefId, LocalDefId};
Expand All @@ -27,7 +27,9 @@ struct UnsafetyVisitor<'a, 'tcx> {
/// The `#[target_feature]` attributes of the body. Used for checking
/// calls to functions with `#[target_feature]` (RFC 2396).
body_target_features: &'tcx Vec<Symbol>,
in_possible_lhs_union_assign: bool,
/// When inside the LHS of an assignment to a field, this is the type
/// of the LHS and the span of the assignment expression.
assignment_info: Option<(Ty<'tcx>, Span)>,
in_union_destructure: bool,
param_env: ParamEnv<'tcx>,
inside_adt: bool,
Expand Down Expand Up @@ -287,7 +289,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
}

fn visit_expr(&mut self, expr: &Expr<'tcx>) {
// could we be in a the LHS of an assignment of a union?
// could we be in the LHS of an assignment to a field?
match expr.kind {
ExprKind::Field { .. }
| ExprKind::VarRef { .. }
Expand Down Expand Up @@ -329,7 +331,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
| ExprKind::InlineAsm { .. }
| ExprKind::LlvmInlineAsm { .. }
| ExprKind::LogicalOp { .. }
| ExprKind::Use { .. } => self.in_possible_lhs_union_assign = false,
| ExprKind::Use { .. } => {
// We don't need to save the old value and restore it
// because all the place expressions can't have more
// than one child.
self.assignment_info = None;
}
};
match expr.kind {
ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
Expand Down Expand Up @@ -409,32 +416,42 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
self.safety_context = closure_visitor.safety_context;
}
ExprKind::Field { lhs, .. } => {
// assigning to union field is okay for AccessToUnionField
if let ty::Adt(adt_def, _) = &self.thir[lhs].ty.kind() {
let lhs = &self.thir[lhs];
if let ty::Adt(adt_def, _) = lhs.ty.kind() {
if adt_def.is_union() {
if self.in_possible_lhs_union_assign {
// FIXME: trigger AssignToDroppingUnionField unsafety if needed
if let Some((assigned_ty, assignment_span)) = self.assignment_info {
// To avoid semver hazard, we only consider `Copy` and `ManuallyDrop` non-dropping.
if !(assigned_ty
.ty_adt_def()
.map_or(false, |adt| adt.is_manually_drop())
|| assigned_ty
.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env))
{
self.requires_unsafe(assignment_span, AssignToDroppingUnionField);
} else {
// write to non-drop union field, safe
}
} else {
self.requires_unsafe(expr.span, AccessToUnionField);
}
}
}
}
ExprKind::Assign { lhs, rhs } | ExprKind::AssignOp { lhs, rhs, .. } => {
let lhs = &self.thir[lhs];
// First, check whether we are mutating a layout constrained field
let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
visit::walk_expr(&mut visitor, &self.thir[lhs]);
visit::walk_expr(&mut visitor, lhs);
if visitor.found {
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
}

// Second, check for accesses to union fields
// don't have any special handling for AssignOp since it causes a read *and* write to lhs
if matches!(expr.kind, ExprKind::Assign { .. }) {
// assigning to a union is safe, check here so it doesn't get treated as a read later
self.in_possible_lhs_union_assign = true;
visit::walk_expr(self, &self.thir()[lhs]);
self.in_possible_lhs_union_assign = false;
self.assignment_info = Some((lhs.ty, expr.span));
visit::walk_expr(self, lhs);
self.assignment_info = None;
visit::walk_expr(self, &self.thir()[rhs]);
return; // we have already visited everything by now
}
Expand Down Expand Up @@ -506,12 +523,9 @@ enum UnsafeOpKind {
UseOfMutableStatic,
UseOfExternStatic,
DerefOfRawPointer,
#[allow(dead_code)] // FIXME
AssignToDroppingUnionField,
AccessToUnionField,
#[allow(dead_code)] // FIXME
MutationOfLayoutConstrainedField,
#[allow(dead_code)] // FIXME
BorrowOfLayoutConstrainedField,
CallToFunctionWith,
}
Expand Down Expand Up @@ -619,7 +633,7 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
hir_context: hir_id,
body_unsafety,
body_target_features,
in_possible_lhs_union_assign: false,
assignment_info: None,
in_union_destructure: false,
param_env: tcx.param_env(def.did),
inside_adt: false,
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ pub struct Session {
/// Set of enabled features for the current target.
pub target_features: FxHashSet<Symbol>,

known_attrs: Lock<MarkedAttrs>,
used_attrs: Lock<MarkedAttrs>,

/// `Span`s for `if` conditions that we have suggested turning into `if let`.
Expand Down Expand Up @@ -1076,14 +1075,6 @@ impl Session {
== config::InstrumentCoverage::ExceptUnusedFunctions
}

pub fn mark_attr_known(&self, attr: &Attribute) {
self.known_attrs.lock().mark(attr)
}

pub fn is_attr_known(&self, attr: &Attribute) -> bool {
self.known_attrs.lock().is_marked(attr)
}

pub fn mark_attr_used(&self, attr: &Attribute) {
self.used_attrs.lock().mark(attr)
}
Expand Down Expand Up @@ -1389,7 +1380,6 @@ pub fn build_session(
miri_unleashed_features: Lock::new(Default::default()),
asm_arch,
target_features: FxHashSet::default(),
known_attrs: Lock::new(MarkedAttrs::new()),
used_attrs: Lock::new(MarkedAttrs::new()),
if_let_suggestions: Default::default(),
};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@ supported_targets! {
("armv6-unknown-freebsd", armv6_unknown_freebsd),
("armv7-unknown-freebsd", armv7_unknown_freebsd),
("i686-unknown-freebsd", i686_unknown_freebsd),
("powerpc-unknown-freebsd", powerpc_unknown_freebsd),
("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
("powerpc64le-unknown-freebsd", powerpc64le_unknown_freebsd),
("x86_64-unknown-freebsd", x86_64_unknown_freebsd),
Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::abi::Endian;
use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::freebsd_base::opts();
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string());
// Extra hint to linker that we are generating secure-PLT code.
base.pre_link_args
.entry(LinkerFlavor::Gcc)
.or_default()
.push("--target=powerpc-unknown-freebsd13.0".to_string());
base.max_atomic_width = Some(32);

Target {
llvm_target: "powerpc-unknown-freebsd13.0".to_string(),
pointer_width: 32,
data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
arch: "powerpc".to_string(),
options: TargetOptions {
endian: Endian::Big,
features: "+secure-plt".to_string(),
relocation_model: RelocModel::Pic,
mcount: "_mcount".to_string(),
..base
},
}
}
1 change: 1 addition & 0 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ pub(crate) mod builtin {
language use and is subject to change"
)]
#[allow_internal_unstable(fmt_internals)]
#[doc(hidden)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args_nl {
Expand Down
1 change: 0 additions & 1 deletion library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,6 @@ impl<T> MaybeUninit<T> {
/// With `write`, we can avoid the need to write through a raw pointer:
///
/// ```rust
/// #![feature(maybe_uninit_extra)]
/// use core::pin::Pin;
/// use core::mem::MaybeUninit;
///
Expand Down
7 changes: 3 additions & 4 deletions library/std/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ impl Error for VarError {
}
}

/// Sets the environment variable `k` to the value `v` for the currently running
/// Sets the environment variable `key` to the value `value` for the currently running
/// process.
///
/// Note that while concurrent access to environment variables is safe in Rust,
Expand All @@ -310,9 +310,8 @@ impl Error for VarError {
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign
/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
/// character.
/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
/// or the NUL character `'\0'`, or when `value` contains the NUL character.
///
/// # Examples
///
Expand Down
Loading

0 comments on commit bddb59c

Please sign in to comment.