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 #96792

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a26cb61
Fix regression in link-to-definition introduced in #93803
GuillaumeGomez May 2, 2022
436c0e1
Fix an ICE on #96738
JohnTitor May 5, 2022
3dac70f
typeck: port "unconstrained opaque type" diag
davidtwco May 4, 2022
859079f
macros: allow `Vec` fields in diagnostic derive
davidtwco May 6, 2022
3f413d2
sess: add `create_{err,warning}`
davidtwco May 6, 2022
af47257
typeck: port "explicit generic args w/ impl trait"
davidtwco May 6, 2022
bd31ba0
make Size and Align debug-printing a bit more compact
RalfJung Apr 30, 2022
22cc6c3
don't debug-print ConstValue in MIR pretty-printer
RalfJung May 6, 2022
d455752
bless mir-opt
RalfJung May 6, 2022
35d77c1
Also suggest calling constructors for external DefIds
JohnTitor May 6, 2022
7b773e8
Remove closures on `expect_local` to apply `#[track_caller]`
JohnTitor May 6, 2022
d6c64f4
Fix an incorrect link in The Unstable Book
koic May 6, 2022
d7d928e
Link to correct issue in issue-95034 test
aliemjay May 6, 2022
5c7ce84
Remove unneeded SpanMapVisitor::visit_generics function
GuillaumeGomez May 6, 2022
fd6b01f
Add regression test for jump-to-def
GuillaumeGomez May 2, 2022
3bfa2eb
Add rustdoc documentation about unstable feature "jump to def"
GuillaumeGomez May 2, 2022
a5eaef5
Rollup merge of #96581 - RalfJung:debug-size-align, r=oli-obk
GuillaumeGomez May 6, 2022
b841f66
Rollup merge of #96636 - GuillaumeGomez:fix-jump-to-def-regression, r…
GuillaumeGomez May 6, 2022
3da6e0a
Rollup merge of #96746 - JohnTitor:issue-96738, r=petrochenkov
GuillaumeGomez May 6, 2022
bb7c8f9
Rollup merge of #96760 - davidtwco:diagnostic-translation-vec, r=oli-obk
GuillaumeGomez May 6, 2022
633cd5e
Rollup merge of #96778 - JohnTitor:expect-local-track-caller-take-2, …
GuillaumeGomez May 6, 2022
1bab41d
Rollup merge of #96781 - koic:fix_an_incorrect_link_in_the_unstable_b…
GuillaumeGomez May 6, 2022
095bd05
Rollup merge of #96783 - aliemjay:typo-issue-95034, r=compiler-errors
GuillaumeGomez May 6, 2022
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
11 changes: 11 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/typeck.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,14 @@ typeck-add-return-type-missing-here = a return type might be missing here
typeck-expected-default-return-type = expected `()` because of default return type

typeck-expected-return-type = expected `{$expected}` because of return type

typeck-unconstrained-opaque-type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same module

typeck-explicit-generic-args-with-impl-trait =
cannot provide explicit generic arguments when `impl Trait` is used in argument position
.label = explicit generic argument not allowed
.note = see issue #83701 <https://github.com/rust-lang/rust/issues/83701> for more information

typeck-explicit-generic-args-with-impl-trait-feature =
add `#![feature(explicit_generic_args_with_impl_trait)]` to the crate attributes to enable
45 changes: 25 additions & 20 deletions compiler/rustc_macros/src/diagnostics/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::diagnostics::error::{
SessionDiagnosticDeriveError,
};
use crate::diagnostics::utils::{
option_inner_ty, report_error_if_not_applied_to_span, type_matches_path, Applicability,
FieldInfo, HasFieldMap, SetOnce,
report_error_if_not_applied_to_span, type_matches_path, Applicability, FieldInfo, FieldInnerTy,
HasFieldMap, SetOnce,
};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
Expand Down Expand Up @@ -353,35 +353,40 @@ impl SessionDiagnosticDeriveBuilder {
info: FieldInfo<'_>,
) -> Result<TokenStream, SessionDiagnosticDeriveError> {
let field_binding = &info.binding.binding;
let option_ty = option_inner_ty(&info.ty);
let generated_code = self.generate_non_option_field_code(

let inner_ty = FieldInnerTy::from_type(&info.ty);
let name = attr.path.segments.last().unwrap().ident.to_string();
let (binding, needs_destructure) = match (name.as_str(), &inner_ty) {
// `primary_span` can accept a `Vec<Span>` so don't destructure that.
("primary_span", FieldInnerTy::Vec(_)) => (quote! { #field_binding.clone() }, false),
_ => (quote! { *#field_binding }, true),
};

let generated_code = self.generate_inner_field_code(
attr,
FieldInfo {
vis: info.vis,
binding: info.binding,
ty: option_ty.unwrap_or(&info.ty),
ty: inner_ty.inner_type().unwrap_or(&info.ty),
span: info.span,
},
binding,
)?;

if option_ty.is_none() {
Ok(quote! { #generated_code })
if needs_destructure {
Ok(inner_ty.with(field_binding, generated_code))
} else {
Ok(quote! {
if let Some(#field_binding) = #field_binding {
#generated_code
}
})
Ok(generated_code)
}
}

fn generate_non_option_field_code(
fn generate_inner_field_code(
&mut self,
attr: &Attribute,
info: FieldInfo<'_>,
binding: TokenStream,
) -> Result<TokenStream, SessionDiagnosticDeriveError> {
let diag = &self.diag;
let field_binding = &info.binding.binding;

let name = attr.path.segments.last().unwrap().ident.to_string();
let name = name.as_str();
Expand All @@ -397,14 +402,14 @@ impl SessionDiagnosticDeriveBuilder {
"primary_span" => {
report_error_if_not_applied_to_span(attr, &info)?;
Ok(quote! {
#diag.set_span(*#field_binding);
#diag.set_span(#binding);
})
}
"label" | "note" | "help" => {
report_error_if_not_applied_to_span(attr, &info)?;
Ok(self.add_subdiagnostic(field_binding, name, name))
Ok(self.add_subdiagnostic(binding, name, name))
}
"subdiagnostic" => Ok(quote! { #diag.subdiagnostic(*#field_binding); }),
"subdiagnostic" => Ok(quote! { #diag.subdiagnostic(#binding); }),
_ => throw_invalid_attr!(attr, &meta, |diag| {
diag
.help("only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes")
Expand All @@ -413,7 +418,7 @@ impl SessionDiagnosticDeriveBuilder {
Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(ref s), .. }) => match name {
"label" | "note" | "help" => {
report_error_if_not_applied_to_span(attr, &info)?;
Ok(self.add_subdiagnostic(field_binding, name, &s.value()))
Ok(self.add_subdiagnostic(binding, name, &s.value()))
}
_ => throw_invalid_attr!(attr, &meta, |diag| {
diag.help("only `label`, `note` and `help` are valid field attributes")
Expand Down Expand Up @@ -509,7 +514,7 @@ impl SessionDiagnosticDeriveBuilder {
/// `fluent_attr_identifier`.
fn add_subdiagnostic(
&self,
field_binding: &proc_macro2::Ident,
field_binding: TokenStream,
kind: &str,
fluent_attr_identifier: &str,
) -> TokenStream {
Expand All @@ -520,7 +525,7 @@ impl SessionDiagnosticDeriveBuilder {
let fn_name = format_ident!("span_{}", kind);
quote! {
#diag.#fn_name(
*#field_binding,
#field_binding,
rustc_errors::DiagnosticMessage::fluent_attr(#slug, #fluent_attr_identifier)
);
}
Expand Down
18 changes: 5 additions & 13 deletions compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::diagnostics::error::{
SessionDiagnosticDeriveError,
};
use crate::diagnostics::utils::{
option_inner_ty, report_error_if_not_applied_to_applicability,
report_error_if_not_applied_to_span, Applicability, FieldInfo, HasFieldMap, SetOnce,
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span,
Applicability, FieldInfo, FieldInnerTy, HasFieldMap, SetOnce,
};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
Expand Down Expand Up @@ -301,11 +301,11 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
) -> Result<TokenStream, SessionDiagnosticDeriveError> {
let ast = binding.ast();

let option_ty = option_inner_ty(&ast.ty);
let inner_ty = FieldInnerTy::from_type(&ast.ty);
let info = FieldInfo {
vis: &ast.vis,
binding: binding,
ty: option_ty.unwrap_or(&ast.ty),
ty: inner_ty.inner_type().unwrap_or(&ast.ty),
span: &ast.span(),
};

Expand Down Expand Up @@ -353,15 +353,7 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> {
);
};

if option_ty.is_none() {
Ok(quote! { #generated })
} else {
Ok(quote! {
if let Some(#binding) = #binding {
#generated
}
})
}
Ok(inner_ty.with(binding, generated))
}

fn into_tokens(&mut self) -> Result<TokenStream, SessionDiagnosticDeriveError> {
Expand Down
61 changes: 55 additions & 6 deletions compiler/rustc_macros/src/diagnostics/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::diagnostics::error::{span_err, throw_span_err, SessionDiagnosticDeriveError};
use proc_macro::Span;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use quote::{format_ident, quote, ToTokens};
use std::collections::BTreeSet;
use std::str::FromStr;
use syn::{spanned::Spanned, Attribute, Meta, Type, Visibility};
Expand Down Expand Up @@ -76,22 +76,71 @@ pub(crate) fn report_error_if_not_applied_to_span(
report_error_if_not_applied_to_ty(attr, info, &["rustc_span", "Span"], "Span")
}

/// If `ty` is an Option, returns `Some(inner type)`, otherwise returns `None`.
pub(crate) fn option_inner_ty(ty: &Type) -> Option<&Type> {
if type_matches_path(ty, &["std", "option", "Option"]) {
/// Inner type of a field and type of wrapper.
pub(crate) enum FieldInnerTy<'ty> {
/// Field is wrapped in a `Option<$inner>`.
Option(&'ty Type),
/// Field is wrapped in a `Vec<$inner>`.
Vec(&'ty Type),
/// Field isn't wrapped in an outer type.
None,
}

impl<'ty> FieldInnerTy<'ty> {
/// Returns inner type for a field, if there is one.
///
/// - If `ty` is an `Option`, returns `FieldInnerTy::Option { inner: (inner type) }`.
/// - If `ty` is a `Vec`, returns `FieldInnerTy::Vec { inner: (inner type) }`.
/// - Otherwise returns `None`.
pub(crate) fn from_type(ty: &'ty Type) -> Self {
let variant: &dyn Fn(&'ty Type) -> FieldInnerTy<'ty> =
if type_matches_path(ty, &["std", "option", "Option"]) {
&FieldInnerTy::Option
} else if type_matches_path(ty, &["std", "vec", "Vec"]) {
&FieldInnerTy::Vec
} else {
return FieldInnerTy::None;
};

if let Type::Path(ty_path) = ty {
let path = &ty_path.path;
let ty = path.segments.iter().last().unwrap();
if let syn::PathArguments::AngleBracketed(bracketed) = &ty.arguments {
if bracketed.args.len() == 1 {
if let syn::GenericArgument::Type(ty) = &bracketed.args[0] {
return Some(ty);
return variant(ty);
}
}
}
}

unreachable!();
}

/// Returns `Option` containing inner type if there is one.
pub(crate) fn inner_type(&self) -> Option<&'ty Type> {
match self {
FieldInnerTy::Option(inner) | FieldInnerTy::Vec(inner) => Some(inner),
FieldInnerTy::None => None,
}
}

/// Surrounds `inner` with destructured wrapper type, exposing inner type as `binding`.
pub(crate) fn with(&self, binding: impl ToTokens, inner: impl ToTokens) -> TokenStream {
match self {
FieldInnerTy::Option(..) => quote! {
if let Some(#binding) = #binding {
#inner
}
},
FieldInnerTy::Vec(..) => quote! {
for #binding in #binding {
#inner
}
},
FieldInnerTy::None => quote! { #inner },
}
}
None
}

/// Field information passed to the builder. Deliberately omits attrs to discourage the
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
self.push(&format!("+ user_ty: {:?}", user_ty));
}

let fmt_val = |val: &ConstValue<'tcx>| match val {
ConstValue::Scalar(s) => format!("Scalar({:?})", s),
ConstValue::Slice { .. } => format!("Slice(..)"),
ConstValue::ByRef { .. } => format!("ByRef(..)"),
};

let val = match literal {
ConstantKind::Ty(ct) => match ct.val() {
ty::ConstKind::Param(p) => format!("Param({})", p),
Expand All @@ -457,7 +463,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
uv.substs,
uv.promoted,
),
ty::ConstKind::Value(val) => format!("Value({:?})", val),
ty::ConstKind::Value(val) => format!("Value({})", fmt_val(&val)),
ty::ConstKind::Error(_) => "Error".to_string(),
// These variants shouldn't exist in the MIR.
ty::ConstKind::Placeholder(_)
Expand All @@ -467,7 +473,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
// To keep the diffs small, we render this like we render `ty::Const::Value`.
//
// This changes once `ty::Const::Value` is represented using valtrees.
ConstantKind::Val(val, _) => format!("Value({:?})", val),
ConstantKind::Val(val, _) => format!("Value({})", fmt_val(&val)),
};

self.push(&format!("+ literal: Const {{ ty: {}, val: {} }}", literal.ty(), val));
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,26 @@ impl ParseSess {
self.proc_macro_quoted_spans.lock().clone()
}

pub fn create_err<'a>(
&'a self,
err: impl SessionDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
err.into_diagnostic(self)
}

pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed {
err.into_diagnostic(self).emit()
self.create_err(err).emit()
}

pub fn create_warning<'a>(
&'a self,
warning: impl SessionDiagnostic<'a, ()>,
) -> DiagnosticBuilder<'a, ()> {
warning.into_diagnostic(self)
}

pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
warning.into_diagnostic(self).emit()
self.create_warning(warning).emit()
}

pub fn struct_err(
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,21 @@ impl Session {
pub fn err(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
self.diagnostic().err(msg)
}
pub fn create_err<'a>(
&'a self,
err: impl SessionDiagnostic<'a>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
self.parse_sess.create_err(err)
}
pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed {
self.parse_sess.emit_err(err)
}
pub fn create_warning<'a>(
&'a self,
err: impl SessionDiagnostic<'a, ()>,
) -> DiagnosticBuilder<'a, ()> {
self.parse_sess.create_warning(err)
}
pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
self.parse_sess.emit_warning(warning)
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_span/src/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,12 @@ impl DefId {
#[inline]
#[track_caller]
pub fn expect_local(self) -> LocalDefId {
self.as_local().unwrap_or_else(|| panic!("DefId::expect_local: `{:?}` isn't local", self))
// NOTE: `match` below is required to apply `#[track_caller]`,
// i.e. don't use closures.
match self.as_local() {
Some(local_def_id) => local_def_id,
None => panic!("DefId::expect_local: `{:?}` isn't local", self),
}
}

#[inline]
Expand Down
18 changes: 16 additions & 2 deletions compiler/rustc_target/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,19 @@ impl ToJson for Endian {
}

/// Size of a type in bytes.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
#[derive(HashStable_Generic)]
pub struct Size {
raw: u64,
}

// This is debug-printed a lot in larger structs, don't waste too much space there
impl fmt::Debug for Size {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Size({} bytes)", self.bytes())
}
}

impl Size {
pub const ZERO: Size = Size { raw: 0 };

Expand Down Expand Up @@ -485,12 +492,19 @@ impl Step for Size {
}

/// Alignment of a type in bytes (always a power of two).
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
#[derive(HashStable_Generic)]
pub struct Align {
pow2: u8,
}

// This is debug-printed a lot in larger structs, don't waste too much space there
impl fmt::Debug for Align {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Align({} bytes)", self.bytes())
}
}

impl Align {
pub const ONE: Align = Align { pow2: 0 };

Expand Down
Loading