Skip to content

Commit

Permalink
Auto merge of #114673 - matthiaskrgr:rollup-9kroqpp, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #110435 (rustdoc-json: Add test for field ordering.)
 - #111891 (feat: `riscv-interrupt-{m,s}` calling conventions)
 - #114377 (test_get_dbpath_for_term(): handle non-utf8 paths (fix FIXME))
 - #114469 (Detect method not found on arbitrary self type with different mutability)
 - #114587 (Convert Const to Allocation in smir)
 - #114670 (Don't use `type_of` to determine if item has intrinsic shim)

Failed merges:

 - #114599 (Add impl trait declarations to SMIR)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Aug 9, 2023
2 parents 08d00b4 + a87dda3 commit 832db2f
Show file tree
Hide file tree
Showing 55 changed files with 1,173 additions and 155 deletions.
17 changes: 17 additions & 0 deletions compiler/rustc_ast_lowering/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,26 @@ pub struct InvalidAbi {
pub abi: Symbol,
pub command: String,
#[subdiagnostic]
pub explain: Option<InvalidAbiReason>,
#[subdiagnostic]
pub suggestion: Option<InvalidAbiSuggestion>,
}

pub struct InvalidAbiReason(pub &'static str);

impl rustc_errors::AddToDiagnostic for InvalidAbiReason {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
#[allow(rustc::untranslatable_diagnostic)]
diag.note(self.0);
}
}

#[derive(Subdiagnostic)]
#[suggestion(
ast_lowering_invalid_abi_suggestion,
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound};
use super::ResolverAstLoweringExt;
use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
use super::{FnDeclKind, LoweringContext, ParamMode};
Expand Down Expand Up @@ -1271,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
}

pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
self.error_on_invalid_abi(abi);
abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| {
self.error_on_invalid_abi(abi, err);
abi::Abi::Rust
})
}
Expand All @@ -1285,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn error_on_invalid_abi(&self, abi: StrLit) {
fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) {
let abi_names = abi::enabled_names(self.tcx.features(), abi.span)
.iter()
.map(|s| Symbol::intern(s))
Expand All @@ -1294,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.tcx.sess.emit_err(InvalidAbi {
abi: abi.symbol_unescaped,
span: abi.span,
explain: match err {
abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)),
_ => None,
},
suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion {
span: abi.span,
suggestion: format!("\"{suggested_name}\""),
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
default_call_conv
}

Conv::X86Intr => sess.fatal("x86-interrupt call conv not yet implemented"),
Conv::X86Intr | Conv::RiscvInterrupt { .. } => {
sess.fatal(format!("interrupt call conv {c:?} not yet implemented"))
}

Conv::ArmAapcs => sess.fatal("aapcs call conv not yet implemented"),
Conv::CCmseNonSecureCall => {
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,13 +383,16 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}

fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
let mut func_attrs = SmallVec::<[_; 2]>::new();
let mut func_attrs = SmallVec::<[_; 3]>::new();
if self.ret.layout.abi.is_uninhabited() {
func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx));
}
if !self.can_unwind {
func_attrs.push(llvm::AttributeKind::NoUnwind.create_attr(cx.llcx));
}
if let Conv::RiscvInterrupt { kind } = self.conv {
func_attrs.push(llvm::CreateAttrStringValue(cx.llcx, "interrupt", kind.as_str()));
}
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &{ func_attrs });

let mut i = 0;
Expand Down Expand Up @@ -565,7 +568,9 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
impl From<Conv> for llvm::CallConv {
fn from(conv: Conv) -> Self {
match conv {
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall | Conv::RiscvInterrupt { .. } => {
llvm::CCallConv
}
Conv::RustCold => llvm::ColdCallConv,
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
Conv::AvrInterrupt => llvm::AvrInterrupt,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ declare_features! (
(active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
/// Allows `extern "ptx-*" fn()`.
(active, abi_ptx, "1.15.0", Some(38788), None),
/// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`.
(active, abi_riscv_interrupt, "CURRENT_RUSTC_VERSION", Some(111889), None),
/// Allows `extern "x86-interrupt" fn()`.
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
/// Allows additional const parameter types, such as `&'static str` or user defined types
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::errors::{
YieldExprOutsideOfGenerator,
};
use crate::fatally_break_rust;
use crate::method::SelfSource;
use crate::method::{MethodCallComponents, SelfSource};
use crate::type_error_struct;
use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
use crate::{
Expand Down Expand Up @@ -1281,7 +1281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
segment.ident,
SelfSource::MethodCall(rcvr),
error,
Some((rcvr, args)),
Some(MethodCallComponents { receiver: rcvr, args, full_expr: expr }),
expected,
false,
) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mod prelude2021;
pub mod probe;
mod suggest;

pub use self::suggest::SelfSource;
pub use self::suggest::{MethodCallComponents, SelfSource};
pub use self::MethodError::*;

use crate::errors::OpMethodGenericParams;
Expand Down
79 changes: 65 additions & 14 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ use rustc_hir::intravisit::Visitor;
use std::cmp::{self, Ordering};
use std::iter;

/// After identifying that `full_expr` is a method call, we use this type to keep the expression's
/// components readily available to us to point at the right place in diagnostics.
#[derive(Debug, Clone, Copy)]
pub struct MethodCallComponents<'tcx> {
pub receiver: &'tcx hir::Expr<'tcx>,
pub args: &'tcx [hir::Expr<'tcx>],
pub full_expr: &'tcx hir::Expr<'tcx>,
}

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
let tcx = self.tcx;
Expand Down Expand Up @@ -115,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_name: Ident,
source: SelfSource<'tcx>,
error: MethodError<'tcx>,
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
args: Option<MethodCallComponents<'tcx>>,
expected: Expectation<'tcx>,
trait_missing_method: bool,
) -> Option<DiagnosticBuilder<'_, ErrorGuaranteed>> {
Expand Down Expand Up @@ -257,18 +266,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_missing_writer(
&self,
rcvr_ty: Ty<'tcx>,
args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]),
args: MethodCallComponents<'tcx>,
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
let mut err =
struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str);
let mut err = struct_span_err!(
self.tcx.sess,
args.receiver.span,
E0599,
"cannot write into `{}`",
ty_str
);
err.span_note(
args.0.span,
args.receiver.span,
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
);
if let ExprKind::Lit(_) = args.0.kind {
if let ExprKind::Lit(_) = args.receiver.kind {
err.span_help(
args.0.span.shrink_to_lo(),
args.receiver.span.shrink_to_lo(),
"a writer is needed before this format string",
);
};
Expand All @@ -282,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>,
item_name: Ident,
source: SelfSource<'tcx>,
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
args: Option<MethodCallComponents<'tcx>>,
sugg_span: Span,
no_match_data: &mut NoMatchData<'tcx>,
expected: Expectation<'tcx>,
Expand Down Expand Up @@ -953,6 +967,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

unsatisfied_bounds = true;
}
} else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some(args) = args {
// This is useful for methods on arbitrary self types that might have a simple
// mutability difference, like calling a method on `Pin<&mut Self>` that is on
// `Pin<&Self>`.
if targs.len() == 1 {
let mut item_segment = hir::PathSegment::invalid();
item_segment.ident = item_name;
for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] {
let new_args = tcx.mk_args_from_iter(
targs
.iter()
.map(|arg| match arg.as_type() {
Some(ty) => ty::GenericArg::from(
t(tcx, tcx.lifetimes.re_erased, ty.peel_refs()),
),
_ => arg,
})
);
let rcvr_ty = Ty::new_adt(tcx, *def, new_args);
if let Ok(method) = self.lookup_method_for_diagnostic(
rcvr_ty,
&item_segment,
span,
args.full_expr,
args.receiver,
) {
err.span_note(
tcx.def_span(method.def_id),
format!("{item_kind} is available for `{rcvr_ty}`"),
);
}
}
}
}

let label_span_not_found = |err: &mut Diagnostic| {
Expand Down Expand Up @@ -1111,7 +1158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
rcvr_ty,
item_name,
args.map(|(_, args)| args.len() + 1),
args.map(|MethodCallComponents { args, .. }| args.len() + 1),
source,
no_match_data.out_of_scope_traits.clone(),
&unsatisfied_predicates,
Expand Down Expand Up @@ -1192,7 +1239,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
rcvr_ty: Ty<'tcx>,
item_name: Ident,
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
args: Option<MethodCallComponents<'tcx>>,
span: Span,
err: &mut Diagnostic,
sources: &mut Vec<CandidateSource>,
Expand Down Expand Up @@ -1343,7 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>,
source: SelfSource<'tcx>,
item_name: Ident,
args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>])>,
args: Option<MethodCallComponents<'tcx>>,
sugg_span: Span,
) {
let mut has_unsuggestable_args = false;
Expand Down Expand Up @@ -1415,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
};
let mut applicability = Applicability::MachineApplicable;
let args = if let Some((receiver, args)) = args {
let args = if let Some(MethodCallComponents { receiver, args, .. }) = args {
// The first arg is the same kind as the receiver
let explicit_args = if first_arg.is_some() {
std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
Expand Down Expand Up @@ -2995,7 +3042,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {

fn print_disambiguation_help<'tcx>(
item_name: Ident,
args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>,
args: Option<MethodCallComponents<'tcx>>,
err: &mut Diagnostic,
trait_name: String,
rcvr_ty: Ty<'_>,
Expand All @@ -3007,7 +3054,11 @@ fn print_disambiguation_help<'tcx>(
fn_has_self_parameter: bool,
) {
let mut applicability = Applicability::MachineApplicable;
let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
let (span, sugg) = if let (
ty::AssocKind::Fn,
Some(MethodCallComponents { receiver, args, .. }),
) = (kind, args)
{
let args = format!(
"({}{})",
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {

/// Try to create an Allocation of `size` bytes, panics if there is not enough memory
/// available to the compiler to do so.
///
/// Example use case: To obtain an Allocation filled with specific data,
/// first call this function and then call write_scalar to fill in the right data.
pub fn uninit(size: Size, align: Align) -> Self {
match Self::uninit_inner(size, align, || {
panic!("Allocation::uninit called with panic_on_fail had allocation failure");
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,8 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
| EfiApi
| AvrInterrupt
| AvrNonBlockingInterrupt
| RiscvInterruptM
| RiscvInterruptS
| CCmseNonSecureCall
| Wasm
| PlatformIntrinsic
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ fn abi_can_unwind(abi: Abi) -> bool {
| EfiApi
| AvrInterrupt
| AvrNonBlockingInterrupt
| RiscvInterruptM
| RiscvInterruptS
| CCmseNonSecureCall
| Wasm
| RustIntrinsic
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ impl<'tcx> Tables<'tcx> {
stable_mir::ty::TraitDef(self.create_def_id(did))
}

pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
stable_mir::ty::ConstDef(self.create_def_id(did))
}

fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
// FIXME: this becomes inefficient when we have too many ids
for (i, &d) in self.def_ids.iter().enumerate() {
Expand Down
Loading

0 comments on commit 832db2f

Please sign in to comment.