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

Merged
merged 15 commits into from
Mar 15, 2023
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
5 changes: 3 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ dependencies = [

[[package]]
name = "cargo"
version = "0.70.0"
version = "0.71.0"
dependencies = [
"anyhow",
"base64",
Expand Down Expand Up @@ -1001,7 +1001,7 @@ dependencies = [

[[package]]
name = "crates-io"
version = "0.35.1"
version = "0.36.0"
dependencies = [
"anyhow",
"curl",
Expand Down Expand Up @@ -5139,6 +5139,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"tracing",
]

Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_lint/src/map_unit_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
return;
}
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
let default_span = args[0].span;
if let ty::FnDef(id, _) = arg_ty.kind() {
let fn_ty = cx.tcx.fn_sig(id).skip_binder();
let ret_ty = fn_ty.output().skip_binder();
Expand All @@ -64,7 +65,10 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
MAP_UNIT_FN,
span,
MappingToUnit {
function_label: cx.tcx.span_of_impl(*id).unwrap(),
function_label: cx
.tcx
.span_of_impl(*id)
.unwrap_or(default_span),
argument_label: args[0].span,
map_label: arg_ty.default_span(cx.tcx),
suggestion: path.ident.span,
Expand All @@ -80,7 +84,10 @@ impl<'tcx> LateLintPass<'tcx> for MapUnitFn {
MAP_UNIT_FN,
span,
MappingToUnit {
function_label: cx.tcx.span_of_impl(*id).unwrap(),
function_label: cx
.tcx
.span_of_impl(*id)
.unwrap_or(default_span),
argument_label: args[0].span,
map_label: arg_ty.default_span(cx.tcx),
suggestion: path.ident.span,
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,15 @@ provide! { tcx, def_id, other, cdata,
lookup_default_body_stability => { table }
lookup_deprecation_entry => { table }
params_in_repr => { table }
unused_generic_params => { table }
// FIXME: Could be defaulted, but `LazyValue<UnusedGenericParams>` is not `FixedSizeEncoding`..
unused_generic_params => {
cdata
.root
.tables
.unused_generic_params
.get(cdata, def_id.index)
.map_or_else(|| ty::UnusedGenericParams::new_all_used(), |lazy| lazy.decode((cdata, tcx)))
}
opt_def_kind => { table_direct }
impl_parent => { table }
impl_polarity => { table_direct }
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/query/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> {

#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
self.def_id().is_local()
}

fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
Expand All @@ -76,7 +76,7 @@ impl<'tcx> Key for ty::Instance<'tcx> {

#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
self.def_id().is_local()
}

fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_monomorphize/src/polymorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ fn unused_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
instance: ty::InstanceDef<'tcx>,
) -> UnusedGenericParams {
assert!(instance.def_id().is_local());

if !tcx.sess.opts.unstable_opts.polymorphize {
// If polymorphization disabled, then all parameters are used.
return UnusedGenericParams::new_all_used();
Expand Down Expand Up @@ -100,13 +102,6 @@ fn should_polymorphize<'tcx>(
return false;
}

// Polymorphization results are stored in cross-crate metadata only when there are unused
// parameters, so assume that non-local items must have only used parameters (else this query
// would not be invoked, and the cross-crate metadata used instead).
if !def_id.is_local() {
return false;
}

// Foreign items have no bodies to analyze.
if tcx.is_foreign_item(def_id) {
return false;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ rustc_span = { path = "../rustc_span" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_feature = { path = "../rustc_feature" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
21 changes: 1 addition & 20 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -720,26 +720,7 @@ passes_ignored_derived_impls =
*[other] traits {$trait_list}, but these are
} intentionally ignored during dead code analysis

passes_proc_macro_typeerror = mismatched {$kind} signature
.label = found {$found}, expected type `proc_macro::TokenStream`
.note = {$kind}s must have a signature of `{$expected_signature}`

passes_proc_macro_diff_arg_count = mismatched {$kind} signature
.label = found unexpected {$count ->
[one] argument
*[other] arguments
}
.note = {$kind}s must have a signature of `{$expected_signature}`

passes_proc_macro_missing_args = mismatched {$kind} signature
.label = {$kind} must have {$expected_input_count ->
[one] one argument
*[other] two arguments
} of type `proc_macro::TokenStream`

passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"`

passes_proc_macro_unsafe = proc macro functions may not be `unsafe`
passes_proc_macro_bad_sig = {$kind} has incorrect signature

passes_skipping_const_checks = skipping const checks

Expand Down
173 changes: 88 additions & 85 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ use rustc_hir::{
use rustc_hir::{MethodKind, Target, Unsafety};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{ParamEnv, TyCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
UNUSED_ATTRIBUTES,
Expand All @@ -30,6 +31,9 @@ use rustc_session::parse::feature_err;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::ObligationCtxt;
use std::cell::Cell;
use std::collections::hash_map::Entry;

Expand Down Expand Up @@ -2188,100 +2192,99 @@ impl CheckAttrVisitor<'_> {
///
/// If this best effort goes wrong, it will just emit a worse error later (see #102923)
fn check_proc_macro(&self, hir_id: HirId, target: Target, kind: ProcMacroKind) {
let expected_input_count = match kind {
ProcMacroKind::Attribute => 2,
ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1,
};

let expected_signature = match kind {
ProcMacroKind::Attribute => "fn(TokenStream, TokenStream) -> TokenStream",
ProcMacroKind::Derive | ProcMacroKind::FunctionLike => "fn(TokenStream) -> TokenStream",
};
if target != Target::Fn {
return;
}

let tcx = self.tcx;
if target == Target::Fn {
let Some(tokenstream) = tcx.get_diagnostic_item(sym::TokenStream) else {return};
let tokenstream = tcx.type_of(tokenstream).subst_identity();

let id = hir_id.expect_owner();
let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id).unwrap();

let sig =
tcx.liberate_late_bound_regions(id.to_def_id(), tcx.fn_sig(id).subst_identity());
let sig = tcx.normalize_erasing_regions(ParamEnv::empty(), sig);

// We don't currently require that the function signature is equal to
// `fn(TokenStream) -> TokenStream`, but instead monomorphizes to
// `fn(TokenStream) -> TokenStream` after some substitution of generic arguments.
//
// Properly checking this means pulling in additional `rustc` crates, so we don't.
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::AsCandidateKey };

if sig.abi != Abi::Rust {
tcx.sess.emit_err(errors::ProcMacroInvalidAbi {
span: hir_sig.span,
abi: sig.abi.name(),
});
self.abort.set(true);
}
let Some(token_stream_def_id) = tcx.get_diagnostic_item(sym::TokenStream) else { return; };
let Some(token_stream) = tcx.type_of(token_stream_def_id).no_bound_vars() else { return; };

if sig.unsafety == Unsafety::Unsafe {
tcx.sess.emit_err(errors::ProcMacroUnsafe { span: hir_sig.span });
self.abort.set(true);
}
let def_id = hir_id.expect_owner().def_id;
let param_env = ty::ParamEnv::empty();

let output = sig.output();
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);

// Typecheck the output
if !drcx.types_may_unify(output, tokenstream) {
tcx.sess.emit_err(errors::ProcMacroTypeError {
span: hir_sig.decl.output.span(),
found: output,
kind,
expected_signature,
});
self.abort.set(true);
}
let span = tcx.def_span(def_id);
let fresh_substs = infcx.fresh_substs_for_item(span, def_id.to_def_id());
let sig = tcx.liberate_late_bound_regions(
def_id.to_def_id(),
tcx.fn_sig(def_id).subst(tcx, fresh_substs),
);

if sig.inputs().len() < expected_input_count {
tcx.sess.emit_err(errors::ProcMacroMissingArguments {
expected_input_count,
span: hir_sig.span,
kind,
expected_signature,
});
self.abort.set(true);
}
let mut cause = ObligationCause::misc(span, def_id);
let sig = ocx.normalize(&cause, param_env, sig);

// Check that the inputs are correct, if there are enough.
if sig.inputs().len() >= expected_input_count {
for (arg, input) in
sig.inputs().iter().zip(hir_sig.decl.inputs).take(expected_input_count)
{
if !drcx.types_may_unify(*arg, tokenstream) {
tcx.sess.emit_err(errors::ProcMacroTypeError {
span: input.span,
found: *arg,
kind,
expected_signature,
});
self.abort.set(true);
// proc macro is not WF.
let errors = ocx.select_where_possible();
if !errors.is_empty() {
return;
}

let expected_sig = tcx.mk_fn_sig(
std::iter::repeat(token_stream).take(match kind {
ProcMacroKind::Attribute => 2,
ProcMacroKind::Derive | ProcMacroKind::FunctionLike => 1,
}),
token_stream,
false,
Unsafety::Normal,
Abi::Rust,
);

if let Err(terr) = ocx.eq(&cause, param_env, expected_sig, sig) {
let mut diag = tcx.sess.create_err(errors::ProcMacroBadSig { span, kind });

let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id);
if let Some(hir_sig) = hir_sig {
match terr {
TypeError::ArgumentMutability(idx) | TypeError::ArgumentSorts(_, idx) => {
if let Some(ty) = hir_sig.decl.inputs.get(idx) {
diag.set_span(ty.span);
cause.span = ty.span;
} else if idx == hir_sig.decl.inputs.len() {
let span = hir_sig.decl.output.span();
diag.set_span(span);
cause.span = span;
}
}
TypeError::ArgCount => {
if let Some(ty) = hir_sig.decl.inputs.get(expected_sig.inputs().len()) {
diag.set_span(ty.span);
cause.span = ty.span;
}
}
TypeError::UnsafetyMismatch(_) => {
// FIXME: Would be nice if we had a span here..
}
TypeError::AbiMismatch(_) => {
// FIXME: Would be nice if we had a span here..
}
TypeError::VariadicMismatch(_) => {
// FIXME: Would be nice if we had a span here..
}
_ => {}
}
}

// Check that there are not too many arguments
let body_id = tcx.hir().body_owned_by(id.def_id);
let excess = tcx.hir().body(body_id).params.get(expected_input_count..);
if let Some(excess @ [begin @ end] | excess @ [begin, .., end]) = excess {
tcx.sess.emit_err(errors::ProcMacroDiffArguments {
span: begin.span.to(end.span),
count: excess.len(),
kind,
expected_signature,
});
self.abort.set(true);
}
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
None,
Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })),
terr,
false,
false,
);
diag.emit();
self.abort.set(true);
}

let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.err_ctxt().report_fulfillment_errors(&errors);
self.abort.set(true);
}
}
}
Expand Down
Loading