Skip to content

Commit 1935645

Browse files
committed
Auto merge of rust-lang#78178 - JohnTitor:rollup-dslazzj, r=JohnTitor
Rollup of 7 pull requests Successful merges: - rust-lang#77726 (Add Pin::static_ref, static_mut.) - rust-lang#78002 (Tweak "object unsafe" errors) - rust-lang#78056 (BTreeMap: split off most code of remove and split_off) - rust-lang#78063 (Improve wording of "cannot multiply" type error) - rust-lang#78094 (rustdoc: Show the correct source filename in page titles, without `.html`) - rust-lang#78101 (fix static_ptr_ty for foreign statics) - rust-lang#78118 (Inline const followups) Failed merges: r? `@ghost`
2 parents f965120 + de24210 commit 1935645

File tree

90 files changed

+1102
-741
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+1102
-741
lines changed

compiler/rustc_hir_pretty/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1138,9 +1138,7 @@ impl<'a> State<'a> {
11381138
fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst) {
11391139
self.ibox(INDENT_UNIT);
11401140
self.s.word_space("const");
1141-
self.s.word("{");
11421141
self.print_anon_const(anon_const);
1143-
self.s.word("}");
11441142
self.end()
11451143
}
11461144

compiler/rustc_infer/src/traits/error_reporting/mod.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ use super::ObjectSafetyViolation;
22

33
use crate::infer::InferCtxt;
44
use rustc_data_structures::fx::FxHashSet;
5-
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
5+
use rustc_errors::{struct_span_err, DiagnosticBuilder};
66
use rustc_hir as hir;
77
use rustc_hir::def_id::DefId;
88
use rustc_middle::ty::TyCtxt;
99
use rustc_span::symbol::Symbol;
10-
use rustc_span::Span;
10+
use rustc_span::{MultiSpan, Span};
1111
use std::fmt;
1212

1313
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
@@ -54,10 +54,11 @@ pub fn report_object_safety_error(
5454
"the trait `{}` cannot be made into an object",
5555
trait_str
5656
);
57-
err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str));
57+
err.span_label(span, format!("`{}` cannot be made into an object", trait_str));
5858

5959
let mut reported_violations = FxHashSet::default();
60-
let mut had_span_label = false;
60+
let mut multi_span = vec![];
61+
let mut messages = vec![];
6162
for violation in violations {
6263
if let ObjectSafetyViolation::SizedSelf(sp) = &violation {
6364
if !sp.is_empty() {
@@ -71,31 +72,37 @@ pub fn report_object_safety_error(
7172
let msg = if trait_span.is_none() || spans.is_empty() {
7273
format!("the trait cannot be made into an object because {}", violation.error_msg())
7374
} else {
74-
had_span_label = true;
7575
format!("...because {}", violation.error_msg())
7676
};
7777
if spans.is_empty() {
7878
err.note(&msg);
7979
} else {
8080
for span in spans {
81-
err.span_label(span, &msg);
81+
multi_span.push(span);
82+
messages.push(msg.clone());
8283
}
8384
}
84-
match (trait_span, violation.solution()) {
85-
(Some(_), Some((note, None))) => {
86-
err.help(&note);
87-
}
88-
(Some(_), Some((note, Some((sugg, span))))) => {
89-
err.span_suggestion(span, &note, sugg, Applicability::MachineApplicable);
90-
}
85+
if trait_span.is_some() {
9186
// Only provide the help if its a local trait, otherwise it's not actionable.
92-
_ => {}
87+
violation.solution(&mut err);
9388
}
9489
}
9590
}
96-
if let (Some(trait_span), true) = (trait_span, had_span_label) {
97-
err.span_label(trait_span, "this trait cannot be made into an object...");
91+
let has_multi_span = !multi_span.is_empty();
92+
let mut note_span = MultiSpan::from_spans(multi_span.clone());
93+
if let (Some(trait_span), true) = (trait_span, has_multi_span) {
94+
note_span
95+
.push_span_label(trait_span, "this trait cannot be made into an object...".to_string());
9896
}
97+
for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) {
98+
note_span.push_span_label(span, msg);
99+
}
100+
err.span_note(
101+
note_span,
102+
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
103+
to be resolvable dynamically; for more information visit \
104+
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
105+
);
99106

100107
if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
101108
// Avoid emitting error caused by non-existing method (#58734)

compiler/rustc_middle/src/mir/mod.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -821,9 +821,6 @@ pub struct LocalDecl<'tcx> {
821821
/// flag drop flags to avoid triggering this check as they are introduced
822822
/// after typeck.
823823
///
824-
/// Unsafety checking will also ignore dereferences of these locals,
825-
/// so they can be used for raw pointers only used in a desugaring.
826-
///
827824
/// This should be sound because the drop flags are fully algebraic, and
828825
/// therefore don't affect the OIBIT or outlives properties of the
829826
/// generator.
@@ -1010,13 +1007,13 @@ impl<'tcx> LocalDecl<'tcx> {
10101007
}
10111008

10121009
/// Returns `Some` if this is a reference to a static item that is used to
1013-
/// access that static
1010+
/// access that static.
10141011
pub fn is_ref_to_static(&self) -> bool {
10151012
matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
10161013
}
10171014

1018-
/// Returns `Some` if this is a reference to a static item that is used to
1019-
/// access that static
1015+
/// Returns `Some` if this is a reference to a thread-local static item that is used to
1016+
/// access that static.
10201017
pub fn is_ref_to_thread_local(&self) -> bool {
10211018
match self.local_info {
10221019
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,

compiler/rustc_middle/src/mir/tcx.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,14 @@ impl<'tcx> Rvalue<'tcx> {
152152
tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
153153
}
154154
Rvalue::ThreadLocalRef(did) => {
155+
let static_ty = tcx.type_of(did);
155156
if tcx.is_mutable_static(did) {
156-
tcx.mk_mut_ptr(tcx.type_of(did))
157+
tcx.mk_mut_ptr(static_ty)
158+
} else if tcx.is_foreign_item(did) {
159+
tcx.mk_imm_ptr(static_ty)
157160
} else {
158-
tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did))
161+
// FIXME: These things don't *really* have 'static lifetime.
162+
tcx.mk_imm_ref(tcx.lifetimes.re_static, static_ty)
159163
}
160164
}
161165
Rvalue::Ref(reg, bk, ref place) => {

compiler/rustc_middle/src/traits/mod.rs

+55-21
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::mir::interpret::ErrorHandled;
1313
use crate::ty::subst::SubstsRef;
1414
use crate::ty::{self, AdtKind, Ty, TyCtxt};
1515

16+
use rustc_errors::{Applicability, DiagnosticBuilder};
1617
use rustc_hir as hir;
1718
use rustc_hir::def_id::DefId;
1819
use rustc_span::symbol::Symbol;
@@ -646,13 +647,13 @@ impl ObjectSafetyViolation {
646647
ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
647648
ObjectSafetyViolation::SupertraitSelf(ref spans) => {
648649
if spans.iter().any(|sp| *sp != DUMMY_SP) {
649-
"it uses `Self` as a type parameter in this".into()
650+
"it uses `Self` as a type parameter".into()
650651
} else {
651652
"it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
652653
.into()
653654
}
654655
}
655-
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
656+
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_, _, _), _) => {
656657
format!("associated function `{}` has no `self` parameter", name).into()
657658
}
658659
ObjectSafetyViolation::Method(
@@ -686,32 +687,65 @@ impl ObjectSafetyViolation {
686687
}
687688
}
688689

689-
pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
690-
Some(match *self {
691-
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
692-
return None;
690+
pub fn solution(&self, err: &mut DiagnosticBuilder<'_>) {
691+
match *self {
692+
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {}
693+
ObjectSafetyViolation::Method(
694+
name,
695+
MethodViolationCode::StaticMethod(sugg, self_span, has_args),
696+
_,
697+
) => {
698+
err.span_suggestion(
699+
self_span,
700+
&format!(
701+
"consider turning `{}` into a method by giving it a `&self` argument",
702+
name
703+
),
704+
format!("&self{}", if has_args { ", " } else { "" }),
705+
Applicability::MaybeIncorrect,
706+
);
707+
match sugg {
708+
Some((sugg, span)) => {
709+
err.span_suggestion(
710+
span,
711+
&format!(
712+
"alternatively, consider constraining `{}` so it does not apply to \
713+
trait objects",
714+
name
715+
),
716+
sugg.to_string(),
717+
Applicability::MaybeIncorrect,
718+
);
719+
}
720+
None => {
721+
err.help(&format!(
722+
"consider turning `{}` into a method by giving it a `&self` \
723+
argument or constraining it so it does not apply to trait objects",
724+
name
725+
));
726+
}
727+
}
693728
}
694-
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => (
695-
format!(
696-
"consider turning `{}` into a method by giving it a `&self` argument or \
697-
constraining it so it does not apply to trait objects",
698-
name
699-
),
700-
sugg.map(|(sugg, sp)| (sugg.to_string(), sp)),
701-
),
702729
ObjectSafetyViolation::Method(
703730
name,
704731
MethodViolationCode::UndispatchableReceiver,
705732
span,
706-
) => (
707-
format!("consider changing method `{}`'s `self` parameter to be `&self`", name),
708-
Some(("&Self".to_string(), span)),
709-
),
733+
) => {
734+
err.span_suggestion(
735+
span,
736+
&format!(
737+
"consider changing method `{}`'s `self` parameter to be `&self`",
738+
name
739+
),
740+
"&Self".to_string(),
741+
Applicability::MachineApplicable,
742+
);
743+
}
710744
ObjectSafetyViolation::AssocConst(name, _)
711745
| ObjectSafetyViolation::Method(name, ..) => {
712-
(format!("consider moving `{}` to another trait", name), None)
746+
err.help(&format!("consider moving `{}` to another trait", name));
713747
}
714-
})
748+
}
715749
}
716750

717751
pub fn spans(&self) -> SmallVec<[Span; 1]> {
@@ -735,7 +769,7 @@ impl ObjectSafetyViolation {
735769
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
736770
pub enum MethodViolationCode {
737771
/// e.g., `fn foo()`
738-
StaticMethod(Option<(&'static str, Span)>),
772+
StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),
739773

740774
/// e.g., `fn foo(&self, x: Self)`
741775
ReferencesSelfInput(usize),

compiler/rustc_middle/src/ty/util.rs

+4
Original file line numberDiff line numberDiff line change
@@ -529,8 +529,12 @@ impl<'tcx> TyCtxt<'tcx> {
529529
// Make sure that any constants in the static's type are evaluated.
530530
let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id));
531531

532+
// Make sure that accesses to unsafe statics end up using raw pointers.
533+
// For thread-locals, this needs to be kept in sync with `Rvalue::ty`.
532534
if self.is_mutable_static(def_id) {
533535
self.mk_mut_ptr(static_ty)
536+
} else if self.is_foreign_item(def_id) {
537+
self.mk_imm_ptr(static_ty)
534538
} else {
535539
self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
536540
}

compiler/rustc_mir/src/transform/check_unsafety.rs

+3
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
204204
if let [] = proj_base {
205205
let decl = &self.body.local_decls[place.local];
206206
if decl.internal {
207+
// If the projection root is an artifical local that we introduced when
208+
// desugaring `static`, give a more specific error message
209+
// (avoid the general "raw pointer" clause below, that would only be confusing).
207210
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
208211
if self.tcx.is_mutable_static(def_id) {
209212
self.require_unsafe(

compiler/rustc_parse/src/parser/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,11 @@ impl<'a> Parser<'a> {
548548

549549
fn check_inline_const(&mut self) -> bool {
550550
self.check_keyword(kw::Const)
551-
&& self.look_ahead(1, |t| t == &token::OpenDelim(DelimToken::Brace))
551+
&& self.look_ahead(1, |t| match t.kind {
552+
token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)),
553+
token::OpenDelim(DelimToken::Brace) => true,
554+
_ => false,
555+
})
552556
}
553557

554558
/// Checks to see if the next token is either `+` or `+=`.

0 commit comments

Comments
 (0)