Skip to content

Commit

Permalink
Auto merge of rust-lang#78178 - JohnTitor:rollup-dslazzj, r=JohnTitor
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Oct 21, 2020
2 parents f965120 + de24210 commit 1935645
Show file tree
Hide file tree
Showing 90 changed files with 1,102 additions and 741 deletions.
2 changes: 0 additions & 2 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,9 +1138,7 @@ impl<'a> State<'a> {
fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst) {
self.ibox(INDENT_UNIT);
self.s.word_space("const");
self.s.word("{");
self.print_anon_const(anon_const);
self.s.word("}");
self.end()
}

Expand Down
39 changes: 23 additions & 16 deletions compiler/rustc_infer/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use super::ObjectSafetyViolation;

use crate::infer::InferCtxt;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
use rustc_span::Span;
use rustc_span::{MultiSpan, Span};
use std::fmt;

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

let mut reported_violations = FxHashSet::default();
let mut had_span_label = false;
let mut multi_span = vec![];
let mut messages = vec![];
for violation in violations {
if let ObjectSafetyViolation::SizedSelf(sp) = &violation {
if !sp.is_empty() {
Expand All @@ -71,31 +72,37 @@ pub fn report_object_safety_error(
let msg = if trait_span.is_none() || spans.is_empty() {
format!("the trait cannot be made into an object because {}", violation.error_msg())
} else {
had_span_label = true;
format!("...because {}", violation.error_msg())
};
if spans.is_empty() {
err.note(&msg);
} else {
for span in spans {
err.span_label(span, &msg);
multi_span.push(span);
messages.push(msg.clone());
}
}
match (trait_span, violation.solution()) {
(Some(_), Some((note, None))) => {
err.help(&note);
}
(Some(_), Some((note, Some((sugg, span))))) => {
err.span_suggestion(span, &note, sugg, Applicability::MachineApplicable);
}
if trait_span.is_some() {
// Only provide the help if its a local trait, otherwise it's not actionable.
_ => {}
violation.solution(&mut err);
}
}
}
if let (Some(trait_span), true) = (trait_span, had_span_label) {
err.span_label(trait_span, "this trait cannot be made into an object...");
let has_multi_span = !multi_span.is_empty();
let mut note_span = MultiSpan::from_spans(multi_span.clone());
if let (Some(trait_span), true) = (trait_span, has_multi_span) {
note_span
.push_span_label(trait_span, "this trait cannot be made into an object...".to_string());
}
for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) {
note_span.push_span_label(span, msg);
}
err.span_note(
note_span,
"for a trait to be \"object safe\" it needs to allow building a vtable to allow the call \
to be resolvable dynamically; for more information visit \
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
);

if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
// Avoid emitting error caused by non-existing method (#58734)
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,6 @@ pub struct LocalDecl<'tcx> {
/// flag drop flags to avoid triggering this check as they are introduced
/// after typeck.
///
/// Unsafety checking will also ignore dereferences of these locals,
/// so they can be used for raw pointers only used in a desugaring.
///
/// This should be sound because the drop flags are fully algebraic, and
/// therefore don't affect the OIBIT or outlives properties of the
/// generator.
Expand Down Expand Up @@ -1010,13 +1007,13 @@ impl<'tcx> LocalDecl<'tcx> {
}

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

/// Returns `Some` if this is a reference to a static item that is used to
/// access that static
/// Returns `Some` if this is a reference to a thread-local static item that is used to
/// access that static.
pub fn is_ref_to_thread_local(&self) -> bool {
match self.local_info {
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_middle/src/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,14 @@ impl<'tcx> Rvalue<'tcx> {
tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
}
Rvalue::ThreadLocalRef(did) => {
let static_ty = tcx.type_of(did);
if tcx.is_mutable_static(did) {
tcx.mk_mut_ptr(tcx.type_of(did))
tcx.mk_mut_ptr(static_ty)
} else if tcx.is_foreign_item(did) {
tcx.mk_imm_ptr(static_ty)
} else {
tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did))
// FIXME: These things don't *really* have 'static lifetime.
tcx.mk_imm_ref(tcx.lifetimes.re_static, static_ty)
}
}
Rvalue::Ref(reg, bk, ref place) => {
Expand Down
76 changes: 55 additions & 21 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::mir::interpret::ErrorHandled;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, AdtKind, Ty, TyCtxt};

use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_span::symbol::Symbol;
Expand Down Expand Up @@ -646,13 +647,13 @@ impl ObjectSafetyViolation {
ObjectSafetyViolation::SizedSelf(_) => "it requires `Self: Sized`".into(),
ObjectSafetyViolation::SupertraitSelf(ref spans) => {
if spans.iter().any(|sp| *sp != DUMMY_SP) {
"it uses `Self` as a type parameter in this".into()
"it uses `Self` as a type parameter".into()
} else {
"it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
.into()
}
}
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_, _, _), _) => {
format!("associated function `{}` has no `self` parameter", name).into()
}
ObjectSafetyViolation::Method(
Expand Down Expand Up @@ -686,32 +687,65 @@ impl ObjectSafetyViolation {
}
}

pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
Some(match *self {
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
return None;
pub fn solution(&self, err: &mut DiagnosticBuilder<'_>) {
match *self {
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {}
ObjectSafetyViolation::Method(
name,
MethodViolationCode::StaticMethod(sugg, self_span, has_args),
_,
) => {
err.span_suggestion(
self_span,
&format!(
"consider turning `{}` into a method by giving it a `&self` argument",
name
),
format!("&self{}", if has_args { ", " } else { "" }),
Applicability::MaybeIncorrect,
);
match sugg {
Some((sugg, span)) => {
err.span_suggestion(
span,
&format!(
"alternatively, consider constraining `{}` so it does not apply to \
trait objects",
name
),
sugg.to_string(),
Applicability::MaybeIncorrect,
);
}
None => {
err.help(&format!(
"consider turning `{}` into a method by giving it a `&self` \
argument or constraining it so it does not apply to trait objects",
name
));
}
}
}
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => (
format!(
"consider turning `{}` into a method by giving it a `&self` argument or \
constraining it so it does not apply to trait objects",
name
),
sugg.map(|(sugg, sp)| (sugg.to_string(), sp)),
),
ObjectSafetyViolation::Method(
name,
MethodViolationCode::UndispatchableReceiver,
span,
) => (
format!("consider changing method `{}`'s `self` parameter to be `&self`", name),
Some(("&Self".to_string(), span)),
),
) => {
err.span_suggestion(
span,
&format!(
"consider changing method `{}`'s `self` parameter to be `&self`",
name
),
"&Self".to_string(),
Applicability::MachineApplicable,
);
}
ObjectSafetyViolation::AssocConst(name, _)
| ObjectSafetyViolation::Method(name, ..) => {
(format!("consider moving `{}` to another trait", name), None)
err.help(&format!("consider moving `{}` to another trait", name));
}
})
}
}

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

/// e.g., `fn foo(&self, x: Self)`
ReferencesSelfInput(usize),
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,12 @@ impl<'tcx> TyCtxt<'tcx> {
// Make sure that any constants in the static's type are evaluated.
let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id));

// Make sure that accesses to unsafe statics end up using raw pointers.
// For thread-locals, this needs to be kept in sync with `Rvalue::ty`.
if self.is_mutable_static(def_id) {
self.mk_mut_ptr(static_ty)
} else if self.is_foreign_item(def_id) {
self.mk_imm_ptr(static_ty)
} else {
self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir/src/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
if let [] = proj_base {
let decl = &self.body.local_decls[place.local];
if decl.internal {
// If the projection root is an artifical local that we introduced when
// desugaring `static`, give a more specific error message
// (avoid the general "raw pointer" clause below, that would only be confusing).
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
if self.tcx.is_mutable_static(def_id) {
self.require_unsafe(
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,11 @@ impl<'a> Parser<'a> {

fn check_inline_const(&mut self) -> bool {
self.check_keyword(kw::Const)
&& self.look_ahead(1, |t| t == &token::OpenDelim(DelimToken::Brace))
&& self.look_ahead(1, |t| match t.kind {
token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)),
token::OpenDelim(DelimToken::Brace) => true,
_ => false,
})
}

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

0 comments on commit 1935645

Please sign in to comment.