Skip to content

Commit bddb59c

Browse files
committed
Auto merge of #87434 - Manishearth:rollup-b09njin, r=Manishearth
Rollup of 9 pull requests Successful merges: - #87348 (Fix span when suggesting to add an associated type bound) - #87359 (Remove detection of rustup and cargo in 'missing extern crate' diagnostics) - #87370 (Add support for powerpc-unknown-freebsd) - #87389 (Rename `known_attrs` to `expanded_inert_attrs` and move to rustc_expand) - #87395 (Clear up std::env::set_var panic section.) - #87403 (Implement `AssignToDroppingUnionField` in THIR unsafeck) - #87410 (Mark `format_args_nl` as `#[doc(hidden)]`) - #87419 (IEEE 754 is not an RFC) - #87422 (DOC: remove unnecessary feature crate attribute from example code) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 18840b0 + acfa3ac commit bddb59c

File tree

22 files changed

+493
-62
lines changed

22 files changed

+493
-62
lines changed

RELEASES.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Libraries
4444
- [`leading_zeros`, and `trailing_zeros` are now available on all
4545
`NonZero` integer types.][84082]
4646
- [`{f32, f64}::from_str` now parse and print special values
47-
(`NaN`, `-0`) according to IEEE RFC 754.][78618]
47+
(`NaN`, `-0`) according to IEEE 754.][78618]
4848
- [You can now index into slices using `(Bound<usize>, Bound<usize>)`.][77704]
4949
- [Add the `BITS` associated constant to all numeric types.][82565]
5050

compiler/rustc_expand/src/base.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::expand::{self, AstFragment, Invocation};
22
use crate::module::DirOwnership;
33

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

956961
impl<'a> ExtCtxt<'a> {
@@ -977,6 +982,7 @@ impl<'a> ExtCtxt<'a> {
977982
},
978983
force_mode: false,
979984
expansions: FxHashMap::default(),
985+
expanded_inert_attrs: MarkedAttrs::new(),
980986
}
981987
}
982988

compiler/rustc_expand/src/expand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
754754
}
755755
}
756756
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
757-
self.cx.sess.mark_attr_known(&attr);
757+
self.cx.expanded_inert_attrs.mark(&attr);
758758
if *mark_used {
759759
self.cx.sess.mark_attr_used(&attr);
760760
}
@@ -1040,7 +1040,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
10401040
item.visit_attrs(|attrs| {
10411041
attr = attrs
10421042
.iter()
1043-
.position(|a| !self.cx.sess.is_attr_known(a) && !is_builtin_attr(a))
1043+
.position(|a| !self.cx.expanded_inert_attrs.is_marked(a) && !is_builtin_attr(a))
10441044
.map(|attr_pos| {
10451045
let attr = attrs.remove(attr_pos);
10461046
let following_derives = attrs[attr_pos..]

compiler/rustc_metadata/src/locator.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,10 @@ impl CrateError {
10801080
locator.triple
10811081
));
10821082
}
1083-
if missing_core && std::env::var("RUSTUP_HOME").is_ok() {
1083+
// NOTE: this suggests using rustup, even though the user may not have it installed.
1084+
// That's because they could choose to install it; or this may give them a hint which
1085+
// target they need to install from their distro.
1086+
if missing_core {
10841087
err.help(&format!(
10851088
"consider downloading the target with `rustup target add {}`",
10861089
locator.triple
@@ -1097,7 +1100,7 @@ impl CrateError {
10971100
current_crate
10981101
));
10991102
}
1100-
if sess.is_nightly_build() && std::env::var("CARGO").is_ok() {
1103+
if sess.is_nightly_build() {
11011104
err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
11021105
}
11031106
} else if Some(crate_name)

compiler/rustc_middle/src/ty/error.rs

+45-20
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ impl<T> Trait<T> for X {
628628
assoc_substs,
629629
ty,
630630
msg,
631+
false,
631632
) {
632633
return true;
633634
}
@@ -646,6 +647,7 @@ impl<T> Trait<T> for X {
646647
assoc_substs,
647648
ty,
648649
msg,
650+
false,
649651
);
650652
}
651653
}
@@ -771,13 +773,24 @@ fn foo(&self) -> Self::T { String::new() }
771773
) -> bool {
772774
let assoc = self.associated_item(proj_ty.item_def_id);
773775
if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
774-
self.constrain_associated_type_structured_suggestion(
776+
let opaque_local_def_id = def_id.expect_local();
777+
let opaque_hir_id = self.hir().local_def_id_to_hir_id(opaque_local_def_id);
778+
let opaque_hir_ty = match &self.hir().expect_item(opaque_hir_id).kind {
779+
hir::ItemKind::OpaqueTy(opaque_hir_ty) => opaque_hir_ty,
780+
_ => bug!("The HirId comes from a `ty::Opaque`"),
781+
};
782+
783+
let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
784+
785+
self.constrain_generic_bound_associated_type_structured_suggestion(
775786
db,
776-
self.def_span(def_id),
777-
&assoc,
778-
proj_ty.trait_ref_and_own_substs(self).1,
787+
&trait_ref,
788+
opaque_hir_ty.bounds,
789+
assoc,
790+
assoc_substs,
779791
ty,
780-
&msg,
792+
msg,
793+
true,
781794
)
782795
} else {
783796
false
@@ -899,6 +912,11 @@ fn foo(&self) -> Self::T { String::new() }
899912

900913
/// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
901914
/// requirement, provide a structured suggestion to constrain it to a given type `ty`.
915+
///
916+
/// `is_bound_surely_present` indicates whether we know the bound we're looking for is
917+
/// inside `bounds`. If that's the case then we can consider `bounds` containing only one
918+
/// trait bound as the one we're looking for. This can help in cases where the associated
919+
/// type is defined on a supertrait of the one present in the bounds.
902920
fn constrain_generic_bound_associated_type_structured_suggestion(
903921
self,
904922
db: &mut DiagnosticBuilder<'_>,
@@ -908,23 +926,30 @@ fn foo(&self) -> Self::T { String::new() }
908926
assoc_substs: &[ty::GenericArg<'tcx>],
909927
ty: Ty<'tcx>,
910928
msg: &str,
929+
is_bound_surely_present: bool,
911930
) -> bool {
912931
// FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
913-
bounds.iter().any(|bound| match bound {
914-
hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => {
915-
// Relate the type param against `T` in `<A as T>::Foo`.
916-
ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id)
917-
&& self.constrain_associated_type_structured_suggestion(
918-
db,
919-
ptr.span,
920-
assoc,
921-
assoc_substs,
922-
ty,
923-
msg,
924-
)
925-
}
926-
_ => false,
927-
})
932+
933+
let trait_bounds = bounds.iter().filter_map(|bound| match bound {
934+
hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr),
935+
_ => None,
936+
});
937+
938+
let matching_trait_bounds = trait_bounds
939+
.clone()
940+
.filter(|ptr| ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id))
941+
.collect::<Vec<_>>();
942+
943+
let span = match &matching_trait_bounds[..] {
944+
&[ptr] => ptr.span,
945+
&[] if is_bound_surely_present => match &trait_bounds.collect::<Vec<_>>()[..] {
946+
&[ptr] => ptr.span,
947+
_ => return false,
948+
},
949+
_ => return false,
950+
};
951+
952+
self.constrain_associated_type_structured_suggestion(db, span, assoc, assoc_substs, ty, msg)
928953
}
929954

930955
/// Given a span corresponding to a bound, provide a structured suggestion to set an

compiler/rustc_mir_build/src/check_unsafety.rs

+31-17
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_errors::struct_span_err;
55
use rustc_hir as hir;
66
use rustc_middle::mir::BorrowKind;
77
use rustc_middle::thir::*;
8-
use rustc_middle::ty::{self, ParamEnv, TyCtxt};
8+
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
99
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
1010
use rustc_session::lint::Level;
1111
use rustc_span::def_id::{DefId, LocalDefId};
@@ -27,7 +27,9 @@ struct UnsafetyVisitor<'a, 'tcx> {
2727
/// The `#[target_feature]` attributes of the body. Used for checking
2828
/// calls to functions with `#[target_feature]` (RFC 2396).
2929
body_target_features: &'tcx Vec<Symbol>,
30-
in_possible_lhs_union_assign: bool,
30+
/// When inside the LHS of an assignment to a field, this is the type
31+
/// of the LHS and the span of the assignment expression.
32+
assignment_info: Option<(Ty<'tcx>, Span)>,
3133
in_union_destructure: bool,
3234
param_env: ParamEnv<'tcx>,
3335
inside_adt: bool,
@@ -287,7 +289,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
287289
}
288290

289291
fn visit_expr(&mut self, expr: &Expr<'tcx>) {
290-
// could we be in a the LHS of an assignment of a union?
292+
// could we be in the LHS of an assignment to a field?
291293
match expr.kind {
292294
ExprKind::Field { .. }
293295
| ExprKind::VarRef { .. }
@@ -329,7 +331,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
329331
| ExprKind::InlineAsm { .. }
330332
| ExprKind::LlvmInlineAsm { .. }
331333
| ExprKind::LogicalOp { .. }
332-
| ExprKind::Use { .. } => self.in_possible_lhs_union_assign = false,
334+
| ExprKind::Use { .. } => {
335+
// We don't need to save the old value and restore it
336+
// because all the place expressions can't have more
337+
// than one child.
338+
self.assignment_info = None;
339+
}
333340
};
334341
match expr.kind {
335342
ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
@@ -409,32 +416,42 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
409416
self.safety_context = closure_visitor.safety_context;
410417
}
411418
ExprKind::Field { lhs, .. } => {
412-
// assigning to union field is okay for AccessToUnionField
413-
if let ty::Adt(adt_def, _) = &self.thir[lhs].ty.kind() {
419+
let lhs = &self.thir[lhs];
420+
if let ty::Adt(adt_def, _) = lhs.ty.kind() {
414421
if adt_def.is_union() {
415-
if self.in_possible_lhs_union_assign {
416-
// FIXME: trigger AssignToDroppingUnionField unsafety if needed
422+
if let Some((assigned_ty, assignment_span)) = self.assignment_info {
423+
// To avoid semver hazard, we only consider `Copy` and `ManuallyDrop` non-dropping.
424+
if !(assigned_ty
425+
.ty_adt_def()
426+
.map_or(false, |adt| adt.is_manually_drop())
427+
|| assigned_ty
428+
.is_copy_modulo_regions(self.tcx.at(expr.span), self.param_env))
429+
{
430+
self.requires_unsafe(assignment_span, AssignToDroppingUnionField);
431+
} else {
432+
// write to non-drop union field, safe
433+
}
417434
} else {
418435
self.requires_unsafe(expr.span, AccessToUnionField);
419436
}
420437
}
421438
}
422439
}
423440
ExprKind::Assign { lhs, rhs } | ExprKind::AssignOp { lhs, rhs, .. } => {
441+
let lhs = &self.thir[lhs];
424442
// First, check whether we are mutating a layout constrained field
425443
let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
426-
visit::walk_expr(&mut visitor, &self.thir[lhs]);
444+
visit::walk_expr(&mut visitor, lhs);
427445
if visitor.found {
428446
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
429447
}
430448

431449
// Second, check for accesses to union fields
432450
// don't have any special handling for AssignOp since it causes a read *and* write to lhs
433451
if matches!(expr.kind, ExprKind::Assign { .. }) {
434-
// assigning to a union is safe, check here so it doesn't get treated as a read later
435-
self.in_possible_lhs_union_assign = true;
436-
visit::walk_expr(self, &self.thir()[lhs]);
437-
self.in_possible_lhs_union_assign = false;
452+
self.assignment_info = Some((lhs.ty, expr.span));
453+
visit::walk_expr(self, lhs);
454+
self.assignment_info = None;
438455
visit::walk_expr(self, &self.thir()[rhs]);
439456
return; // we have already visited everything by now
440457
}
@@ -506,12 +523,9 @@ enum UnsafeOpKind {
506523
UseOfMutableStatic,
507524
UseOfExternStatic,
508525
DerefOfRawPointer,
509-
#[allow(dead_code)] // FIXME
510526
AssignToDroppingUnionField,
511527
AccessToUnionField,
512-
#[allow(dead_code)] // FIXME
513528
MutationOfLayoutConstrainedField,
514-
#[allow(dead_code)] // FIXME
515529
BorrowOfLayoutConstrainedField,
516530
CallToFunctionWith,
517531
}
@@ -619,7 +633,7 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
619633
hir_context: hir_id,
620634
body_unsafety,
621635
body_target_features,
622-
in_possible_lhs_union_assign: false,
636+
assignment_info: None,
623637
in_union_destructure: false,
624638
param_env: tcx.param_env(def.did),
625639
inside_adt: false,

compiler/rustc_session/src/session.rs

-10
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ pub struct Session {
219219
/// Set of enabled features for the current target.
220220
pub target_features: FxHashSet<Symbol>,
221221

222-
known_attrs: Lock<MarkedAttrs>,
223222
used_attrs: Lock<MarkedAttrs>,
224223

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

1079-
pub fn mark_attr_known(&self, attr: &Attribute) {
1080-
self.known_attrs.lock().mark(attr)
1081-
}
1082-
1083-
pub fn is_attr_known(&self, attr: &Attribute) -> bool {
1084-
self.known_attrs.lock().is_marked(attr)
1085-
}
1086-
10871078
pub fn mark_attr_used(&self, attr: &Attribute) {
10881079
self.used_attrs.lock().mark(attr)
10891080
}
@@ -1389,7 +1380,6 @@ pub fn build_session(
13891380
miri_unleashed_features: Lock::new(Default::default()),
13901381
asm_arch,
13911382
target_features: FxHashSet::default(),
1392-
known_attrs: Lock::new(MarkedAttrs::new()),
13931383
used_attrs: Lock::new(MarkedAttrs::new()),
13941384
if_let_suggestions: Default::default(),
13951385
};

compiler/rustc_target/src/spec/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ supported_targets! {
802802
("armv6-unknown-freebsd", armv6_unknown_freebsd),
803803
("armv7-unknown-freebsd", armv7_unknown_freebsd),
804804
("i686-unknown-freebsd", i686_unknown_freebsd),
805+
("powerpc-unknown-freebsd", powerpc_unknown_freebsd),
805806
("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
806807
("powerpc64le-unknown-freebsd", powerpc64le_unknown_freebsd),
807808
("x86_64-unknown-freebsd", x86_64_unknown_freebsd),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::abi::Endian;
2+
use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions};
3+
4+
pub fn target() -> Target {
5+
let mut base = super::freebsd_base::opts();
6+
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m32".to_string());
7+
// Extra hint to linker that we are generating secure-PLT code.
8+
base.pre_link_args
9+
.entry(LinkerFlavor::Gcc)
10+
.or_default()
11+
.push("--target=powerpc-unknown-freebsd13.0".to_string());
12+
base.max_atomic_width = Some(32);
13+
14+
Target {
15+
llvm_target: "powerpc-unknown-freebsd13.0".to_string(),
16+
pointer_width: 32,
17+
data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
18+
arch: "powerpc".to_string(),
19+
options: TargetOptions {
20+
endian: Endian::Big,
21+
features: "+secure-plt".to_string(),
22+
relocation_model: RelocModel::Pic,
23+
mcount: "_mcount".to_string(),
24+
..base
25+
},
26+
}
27+
}

library/core/src/macros/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,7 @@ pub(crate) mod builtin {
845845
language use and is subject to change"
846846
)]
847847
#[allow_internal_unstable(fmt_internals)]
848+
#[doc(hidden)]
848849
#[rustc_builtin_macro]
849850
#[macro_export]
850851
macro_rules! format_args_nl {

library/core/src/mem/maybe_uninit.rs

-1
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,6 @@ impl<T> MaybeUninit<T> {
461461
/// With `write`, we can avoid the need to write through a raw pointer:
462462
///
463463
/// ```rust
464-
/// #![feature(maybe_uninit_extra)]
465464
/// use core::pin::Pin;
466465
/// use core::mem::MaybeUninit;
467466
///

library/std/src/env.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ impl Error for VarError {
294294
}
295295
}
296296

297-
/// Sets the environment variable `k` to the value `v` for the currently running
297+
/// Sets the environment variable `key` to the value `value` for the currently running
298298
/// process.
299299
///
300300
/// Note that while concurrent access to environment variables is safe in Rust,
@@ -310,9 +310,8 @@ impl Error for VarError {
310310
///
311311
/// # Panics
312312
///
313-
/// This function may panic if `key` is empty, contains an ASCII equals sign
314-
/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
315-
/// character.
313+
/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
314+
/// or the NUL character `'\0'`, or when `value` contains the NUL character.
316315
///
317316
/// # Examples
318317
///

0 commit comments

Comments
 (0)