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 5 pull requests #80138

Merged
merged 14 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 20 additions & 5 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ pub enum DiagnosticId {
Lint { name: String, has_future_breakage: bool },
}

/// For example a note attached to an error.
/// A "sub"-diagnostic attached to a parent diagnostic.
/// For example, a note attached to an error.
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct SubDiagnostic {
pub level: Level,
Expand Down Expand Up @@ -124,6 +125,7 @@ impl Diagnostic {
self.level = Level::Cancelled;
}

/// Check if this diagnostic [was cancelled][Self::cancel()].
pub fn cancelled(&self) -> bool {
self.level == Level::Cancelled
}
Expand Down Expand Up @@ -164,7 +166,7 @@ impl Diagnostic {
self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"")
}

pub fn note_unsuccessfull_coercion(
pub fn note_unsuccessful_coercion(
&mut self,
expected: DiagnosticStyledString,
found: DiagnosticStyledString,
Expand Down Expand Up @@ -241,6 +243,7 @@ impl Diagnostic {
self
}

/// Add a note attached to this diagnostic.
pub fn note(&mut self, msg: &str) -> &mut Self {
self.sub(Level::Note, msg, MultiSpan::new(), None);
self
Expand All @@ -252,33 +255,40 @@ impl Diagnostic {
}

/// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span.
pub fn span_note<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
self.sub(Level::Note, msg, sp.into(), None);
self
}

/// Add a warning attached to this diagnostic.
pub fn warn(&mut self, msg: &str) -> &mut Self {
self.sub(Level::Warning, msg, MultiSpan::new(), None);
self
}

/// Prints the span with a warn above it.
/// Prints the span with a warning above it.
/// This is like [`Diagnostic::warn()`], but it gets its own span.
pub fn span_warn<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
self.sub(Level::Warning, msg, sp.into(), None);
self
}

/// Add a help message attached to this diagnostic.
pub fn help(&mut self, msg: &str) -> &mut Self {
self.sub(Level::Help, msg, MultiSpan::new(), None);
self
}

/// Prints the span with some help above it.
/// This is like [`Diagnostic::help()`], but it gets its own span.
pub fn span_help<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self {
self.sub(Level::Help, msg, sp.into(), None);
self
}

/// Show a suggestion that has multiple parts to it.
/// In other words, multiple changes need to be applied as part of this suggestion.
pub fn multipart_suggestion(
&mut self,
msg: &str,
Expand All @@ -299,6 +309,8 @@ impl Diagnostic {
self
}

/// Show multiple suggestions that have multiple parts.
/// See also [`Diagnostic::multipart_suggestion()`].
pub fn multipart_suggestions(
&mut self,
msg: &str,
Expand Down Expand Up @@ -382,6 +394,7 @@ impl Diagnostic {
self
}

/// [`Diagnostic::span_suggestion()`] but you can set the [`SuggestionStyle`].
pub fn span_suggestion_with_style(
&mut self,
sp: Span,
Expand All @@ -401,6 +414,7 @@ impl Diagnostic {
self
}

/// Always show the suggested change.
pub fn span_suggestion_verbose(
&mut self,
sp: Span,
Expand All @@ -419,6 +433,7 @@ impl Diagnostic {
}

/// Prints out a message with multiple suggested edits of the code.
/// See also [`Diagnostic::span_suggestion()`].
pub fn span_suggestions(
&mut self,
sp: Span,
Expand Down Expand Up @@ -458,7 +473,7 @@ impl Diagnostic {
self
}

/// Prints out a message with for a suggestion without showing the suggested code.
/// Prints out a message for a suggestion without showing the suggested code.
///
/// This is intended to be used for suggestions that are obvious in what the changes need to
/// be from the message, showing the span label inline would be visually unpleasant
Expand All @@ -481,7 +496,7 @@ impl Diagnostic {
self
}

/// Adds a suggestion to the json output, but otherwise remains silent/undisplayed in the cli.
/// Adds a suggestion to the JSON output that will not be shown in the CLI.
///
/// This is intended to be used for suggestions that are *very* obvious in what the changes
/// need to be from the message, but we still want other tools to be able to apply them.
Expand Down
40 changes: 32 additions & 8 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ struct DiagnosticBuilderInner<'a> {
allow_suggestions: bool,
}

/// This is a helper macro for [`forward!`] that allows automatically adding documentation
/// that uses tokens from [`forward!`]'s input.
macro_rules! forward_inner_docs {
($e:expr => $i:item) => {
#[doc = $e]
$i
}
}

/// In general, the `DiagnosticBuilder` uses deref to allow access to
/// the fields and methods of the embedded `diagnostic` in a
/// transparent way. *However,* many of the methods are intended to
Expand All @@ -45,10 +54,11 @@ macro_rules! forward {
pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)?) -> &Self
) => {
$(#[$attrs])*
forward_inner_docs!(concat!("See [`Diagnostic::", stringify!($n), "()`].") =>
pub fn $n(&self, $($name: $ty),*) -> &Self {
self.diagnostic.$n($($name),*);
self
}
});
};

// Forward pattern for &mut self -> &mut Self
Expand All @@ -57,10 +67,11 @@ macro_rules! forward {
pub fn $n:ident(&mut self, $($name:ident: $ty:ty),* $(,)?) -> &mut Self
) => {
$(#[$attrs])*
forward_inner_docs!(concat!("See [`Diagnostic::", stringify!($n), "()`].") =>
pub fn $n(&mut self, $($name: $ty),*) -> &mut Self {
self.0.diagnostic.$n($($name),*);
self
}
});
};

// Forward pattern for &mut self -> &mut Self, with S: Into<MultiSpan>
Expand All @@ -74,10 +85,11 @@ macro_rules! forward {
) -> &mut Self
) => {
$(#[$attrs])*
forward_inner_docs!(concat!("See [`Diagnostic::", stringify!($n), "()`].") =>
pub fn $n<S: Into<MultiSpan>>(&mut self, $($name: $ty),*) -> &mut Self {
self.0.diagnostic.$n($($name),*);
self
}
});
};
}

Expand Down Expand Up @@ -116,7 +128,7 @@ impl<'a> DiagnosticBuilder<'a> {

/// Stashes diagnostic for possible later improvement in a different,
/// later stage of the compiler. The diagnostic can be accessed with
/// the provided `span` and `key` through `.steal_diagnostic` on `Handler`.
/// the provided `span` and `key` through [`Handler::steal_diagnostic()`].
///
/// As with `buffer`, this is unless the handler has disabled such buffering.
pub fn stash(self, span: Span, key: StashKey) {
Expand Down Expand Up @@ -202,7 +214,7 @@ impl<'a> DiagnosticBuilder<'a> {
}

/// Labels all the given spans with the provided label.
/// See `span_label` for more information.
/// See [`Diagnostic::span_label()`] for more information.
pub fn span_labels(
&mut self,
spans: impl IntoIterator<Item = Span>,
Expand Down Expand Up @@ -233,7 +245,7 @@ impl<'a> DiagnosticBuilder<'a> {
found_extra: &dyn fmt::Display,
) -> &mut Self);

forward!(pub fn note_unsuccessfull_coercion(
forward!(pub fn note_unsuccessful_coercion(
&mut self,
expected: DiagnosticStyledString,
found: DiagnosticStyledString,
Expand All @@ -254,6 +266,7 @@ impl<'a> DiagnosticBuilder<'a> {
msg: &str,
) -> &mut Self);

/// See [`Diagnostic::multipart_suggestion()`].
pub fn multipart_suggestion(
&mut self,
msg: &str,
Expand All @@ -267,6 +280,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::multipart_suggestions()`].
pub fn multipart_suggestions(
&mut self,
msg: &str,
Expand All @@ -280,6 +294,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::tool_only_multipart_suggestion()`].
pub fn tool_only_multipart_suggestion(
&mut self,
msg: &str,
Expand All @@ -293,6 +308,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::span_suggestion()`].
pub fn span_suggestion(
&mut self,
sp: Span,
Expand All @@ -307,6 +323,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::span_suggestions()`].
pub fn span_suggestions(
&mut self,
sp: Span,
Expand All @@ -321,6 +338,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::span_suggestion_short()`].
pub fn span_suggestion_short(
&mut self,
sp: Span,
Expand All @@ -335,6 +353,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::span_suggestion_verbose()`].
pub fn span_suggestion_verbose(
&mut self,
sp: Span,
Expand All @@ -349,6 +368,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::span_suggestion_hidden()`].
pub fn span_suggestion_hidden(
&mut self,
sp: Span,
Expand All @@ -363,6 +383,7 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

/// See [`Diagnostic::tool_only_span_suggestion()`] for more information.
pub fn tool_only_span_suggestion(
&mut self,
sp: Span,
Expand All @@ -380,19 +401,22 @@ impl<'a> DiagnosticBuilder<'a> {
forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);

/// Allow attaching suggestions this diagnostic.
/// If this is set to `false`, then any suggestions attached with the `span_suggestion_*`
/// methods after this is set to `false` will be ignored.
pub fn allow_suggestions(&mut self, allow: bool) -> &mut Self {
self.0.allow_suggestions = allow;
self
}

/// Convenience function for internal use, clients should use one of the
/// struct_* methods on Handler.
/// `struct_*` methods on [`Handler`].
crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> {
DiagnosticBuilder::new_with_code(handler, level, None, message)
}

/// Convenience function for internal use, clients should use one of the
/// struct_* methods on Handler.
/// `struct_*` methods on [`Handler`].
crate fn new_with_code(
handler: &'a Handler,
level: Level,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1622,7 +1622,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
(TypeError::ObjectUnsafeCoercion(_), _) => {
diag.note_unsuccessfull_coercion(found, expected);
diag.note_unsuccessful_coercion(found, expected);
}
(_, _) => {
debug!(
Expand Down
18 changes: 17 additions & 1 deletion compiler/rustc_mir/src/borrow_check/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
debug!("approx_universal_upper_bound: ur={:?} lub={:?} new_lub={:?}", ur, lub, new_lub);
// The upper bound of two non-static regions is static: this
// means we know nothing about the relationship between these
// two regions. Pick a 'better' one to use when constructing
// a diagnostic
if ur != static_r && lub != static_r && new_lub == static_r {
lub = std::cmp::min(ur, lub);
// Prefer the region with an `external_name` - this
// indicates that the region is early-bound, so working with
// it can produce a nicer error.
if self.region_definition(ur).external_name.is_some() {
lub = ur;
} else if self.region_definition(lub).external_name.is_some() {
// Leave lub unchanged
} else {
// If we get here, we don't have any reason to prefer
// one region over the other. Just pick the
// one with the lower index for now.
lub = std::cmp::min(ur, lub);
}
} else {
lub = new_lub;
}
Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
err.span_label(base_span, fallback_label);
}
}
if let Some(err_code) = &err.code {
if err_code == &rustc_errors::error_code!(E0425) {
for label_rib in &self.label_ribs {
for (label_ident, _) in &label_rib.bindings {
if format!("'{}", ident) == label_ident.to_string() {
let msg = "a label with a similar name exists";
// FIXME: consider only emitting this suggestion if a label would be valid here
// which is pretty much only the case for `break` expressions.
err.span_suggestion(
span,
&msg,
label_ident.name.to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
}
}

(err, candidates)
}

Expand Down
8 changes: 6 additions & 2 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2793,8 +2793,12 @@ impl<T> From<Vec<T>> for VecDeque<T> {
let len = other.len();

// We need to extend the buf if it's not a power of two, too small
// or doesn't have at least one free space
if !buf.capacity().is_power_of_two()
// or doesn't have at least one free space.
// We check if `T` is a ZST in the first condition,
// because `usize::MAX` (the capacity returned by `capacity()` for ZST)
// is not a power of two and thus it'll always try
// to reserve more memory which will panic for ZST (rust-lang/rust#78532)
if (!buf.capacity().is_power_of_two() && mem::size_of::<T>() != 0)
|| (buf.capacity() < (MINIMUM_CAPACITY + 1))
|| (buf.capacity() == len)
{
Expand Down
7 changes: 7 additions & 0 deletions library/alloc/tests/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1728,3 +1728,10 @@ fn test_zero_sized_push() {
}
}
}

#[test]
fn test_from_zero_sized_vec() {
let v = vec![(); 100];
let queue = VecDeque::from(v);
assert_eq!(queue.len(), 100);
}
Loading