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 7 pull requests #78178

Merged
merged 25 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
64839ee
Add Pin::new_static.
m-ou-se Oct 8, 2020
390883e
Make Pin::new_static const.
m-ou-se Oct 8, 2020
104c0f0
Rename Pin::new_static to Pin::static_ref.
m-ou-se Oct 12, 2020
2c71f68
Add Pin::static_mut.
m-ou-se Oct 12, 2020
f83446b
Reword safety guarantee of Pin::static_{ref,mut}.
m-ou-se Oct 13, 2020
df95dce
Add missing `mut`.
m-ou-se Oct 15, 2020
7b33ae6
Improve wording of "cannot multiply" type error
camelid Oct 18, 2020
003516f
BTreeMap: split off most code of remove and split_off
ssomers Oct 17, 2020
48060f1
rustdoc: Show the correct source filename, without `.html`
camelid Oct 19, 2020
cb33f95
remove what seems to be an outdated comment
RalfJung Oct 19, 2020
c1766c6
fix static_ptr_ty for foreign statics, and more comments in check_uns…
RalfJung Oct 19, 2020
153e843
fix Rvalue::ty for ThreadLocalRef
RalfJung Oct 19, 2020
9dd0bb6
Do not print braces again print_anon_const already does it
spastorino Oct 19, 2020
d641cb8
Allow NtBlock to parse on check inline const next token
spastorino Oct 19, 2020
dcd2d91
Add inline const macro test
spastorino Oct 19, 2020
ae0e3d0
Tweak "object unsafe" errors
estebank Oct 16, 2020
88f5e11
review comments
estebank Oct 20, 2020
243c8e9
Apply some review suggestions
camelid Oct 20, 2020
ff3c8cb
Rollup merge of #77726 - fusion-engineering-forks:static-pin, r=dtolnay
JohnTitor Oct 21, 2020
9583029
Rollup merge of #78002 - estebank:issue-77598, r=oli-obk
JohnTitor Oct 21, 2020
f8bae8b
Rollup merge of #78056 - ssomers:btree_chop_up_1, r=dtolnay
JohnTitor Oct 21, 2020
89c98cd
Rollup merge of #78063 - camelid:improve-cannot-multiply-error, r=est…
JohnTitor Oct 21, 2020
72ae00b
Rollup merge of #78094 - camelid:rustdoc-fix-source-title, r=jyn514
JohnTitor Oct 21, 2020
83f126b
Rollup merge of #78101 - RalfJung:foreign-static, r=oli-obk
JohnTitor Oct 21, 2020
de24210
Rollup merge of #78118 - spastorino:inline-const-followups, r=petroch…
JohnTitor Oct 21, 2020
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
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
Loading