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 8 pull requests #106031

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
bd12d15
add function to tell if the current ambiguity error matches a previou…
Dec 16, 2022
738b0c0
Re-enable fn trait call notation error
compiler-errors Dec 20, 2022
04926e0
Switch `#[track_caller]` back to a no-op unless feature gate is enabled
bryangarza Nov 22, 2022
dc2c4ce
Update code based on PR comments
bryangarza Nov 24, 2022
e28a07a
update wording of lint
bryangarza Nov 24, 2022
2d06003
Update track_caller logic/lint after rebase
bryangarza Dec 7, 2022
f702e89
Add lint doc comment
bryangarza Dec 7, 2022
9650a41
Improve code based on feedback.
bryangarza Dec 21, 2022
2f5334d
forgot a return in drop tracking handle_uninhabited_return
compiler-errors Dec 21, 2022
9c9fa56
codegen tests: adapt patterns to also work with v0 symbol mangling
krasimirgg Dec 21, 2022
a9af75c
Give opaque types a better coherence error
oli-obk Dec 21, 2022
ccbba0a
Update track_caller tests; run fmt
bryangarza Dec 21, 2022
8a4cbf4
Fix ICE
JulianKnodt Dec 21, 2022
f20f86e
Change comment to doc comment
eholk Dec 22, 2022
20052c8
Suggest associated const on capitalization error
compiler-errors Dec 17, 2022
b5faa5b
Rollup merge of #104741 - bryangarza:bug-104588-async-track-caller, r…
matthiaskrgr Dec 22, 2022
50c473b
Rollup merge of #105769 - lyming2007:issue-105177-fix, r=eholk
matthiaskrgr Dec 22, 2022
616f1dd
Rollup merge of #105843 - compiler-errors:sugg-const, r=lcnr
matthiaskrgr Dec 22, 2022
ee15eb7
Rollup merge of #105966 - compiler-errors:issue-105936, r=eholk
matthiaskrgr Dec 22, 2022
87100e3
Rollup merge of #105983 - compiler-errors:issue-105981, r=tmiasko
matthiaskrgr Dec 22, 2022
68cc597
Rollup merge of #106002 - krasimirgg:v0sym, r=tmiasko
matthiaskrgr Dec 22, 2022
d5983c5
Rollup merge of #106010 - oli-obk:tait_coherence_diagnostic, r=compil…
matthiaskrgr Dec 22, 2022
c27553f
Rollup merge of #106024 - JulianKnodt:add_term_html_docs, r=notriddle
matthiaskrgr Dec 22, 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
18 changes: 7 additions & 11 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,18 +656,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ExprKind::Closure(c)
};

let track_caller = self
.attrs
.get(&outer_hir_id.local_id)
.map_or(false, |attrs| attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)));

let hir_id = self.lower_node_id(closure_node_id);
if track_caller {
let unstable_span = self.mark_span_with_reason(
DesugaringKind::Async,
span,
self.allow_gen_future.clone(),
);
let unstable_span =
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());

if self.tcx.features().closure_track_caller
&& let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)
&& attrs.into_iter().any(|attr| attr.has_name(sym::track_caller))
{
self.lower_attrs(
hir_id,
&[Attribute {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/lint.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ lint_builtin_mutable_transmutes =

lint_builtin_unstable_features = unstable feature

lint_ungated_async_fn_track_caller = `#[track_caller]` on async functions is a no-op
.label = this function will not propagate the caller location

lint_builtin_unreachable_pub = unreachable `pub` {$what}
.suggestion = consider restricting its visibility
.help = or consider exporting it for use by other crates
Expand Down
23 changes: 15 additions & 8 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,19 @@ fn emit_orphan_check_error<'tcx>(
ty::Adt(def, _) => tcx.mk_adt(*def, ty::List::empty()),
_ => ty,
};
let this = "this".to_string();
let (ty, postfix) = match &ty.kind() {
ty::Slice(_) => (this, " because slices are always foreign"),
ty::Array(..) => (this, " because arrays are always foreign"),
ty::Tuple(..) => (this, " because tuples are always foreign"),
let msg = |ty: &str, postfix: &str| {
format!("{ty} is not defined in the current crate{postfix}")
};
let this = |name: &str| msg("this", &format!(" because {name} are always foreign"));
let msg = match &ty.kind() {
ty::Slice(_) => this("slices"),
ty::Array(..) => this("arrays"),
ty::Tuple(..) => this("tuples"),
ty::Alias(ty::Opaque, ..) => {
"type alias impl trait is treated as if it were foreign, \
because its hidden type could be from a foreign crate"
.to_string()
}
ty::RawPtr(ptr_ty) => {
emit_newtype_suggestion_for_raw_ptr(
full_impl_span,
Expand All @@ -198,12 +206,11 @@ fn emit_orphan_check_error<'tcx>(
&mut err,
);

(format!("`{}`", ty), " because raw pointers are always foreign")
msg(&format!("`{ty}`"), " because raw pointers are always foreign")
}
_ => (format!("`{}`", ty), ""),
_ => msg(&format!("`{ty}`"), ""),
};

let msg = format!("{} is not defined in the current crate{}", ty, postfix);
if is_target_ty {
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
err.span_label(self_ty_span, &msg);
Expand Down
25 changes: 20 additions & 5 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,24 @@ use std::cmp::min;
use std::iter;

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn emit_coerce_suggestions(
pub fn emit_type_mismatch_suggestions(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
expr_ty: Ty<'tcx>,
expected: Ty<'tcx>,
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
error: Option<TypeError<'tcx>>,
_error: Option<TypeError<'tcx>>,
) {
if expr_ty == expected {
return;
}

self.annotate_expected_due_to_let_ty(err, expr, error);

// Use `||` to give these suggestions a precedence
let _ = self.suggest_missing_parentheses(err, expr)
|| self.suggest_associated_const(err, expr, expected)
|| self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr)
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
|| self.suggest_compatible_variants(err, expr, expected, expr_ty)
|| self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty)
|| self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty)
Expand All @@ -49,9 +49,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|| self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected)
|| self.suggest_copied_or_cloned(err, expr, expr_ty, expected)
|| self.suggest_into(err, expr, expr_ty, expected)
|| self.suggest_option_to_bool(err, expr, expr_ty, expected)
|| self.suggest_floating_point_literal(err, expr, expected);
}

pub fn emit_coerce_suggestions(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'tcx>,
expr_ty: Ty<'tcx>,
expected: Ty<'tcx>,
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
error: Option<TypeError<'tcx>>,
) {
if expr_ty == expected {
return;
}

self.annotate_expected_due_to_let_ty(err, expr, error);
self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error);
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
// FIXME(compiler-errors): We probably should fold some of the
// `suggest_` functions from `emit_coerce_suggestions` into here,
// since some of those aren't necessarily just coerce suggestions.
let _ = self.suggest_deref_ref_or_into(
let _ = self.emit_type_mismatch_suggestions(
&mut err,
expr.peel_drop_temps(),
expected_ty,
ty,
expected_ty,
None,
) || self.suggest_option_to_bool(&mut err, expr, ty, expected_ty);
None,
);
extend_err(&mut err);
err.emit();
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"cannot use call notation; the first type parameter \
for the function trait is neither a tuple nor unit"
)
.delay_as_bug();
.emit();
(self.err_args(provided_args.len()), None)
}
}
Expand Down
84 changes: 82 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::FnCtxt;

use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
use rustc_hir as hir;
Expand All @@ -15,10 +16,11 @@ use rustc_infer::traits::{self, StatementAsExpression};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{
self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty,
TypeVisitable,
};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::DefIdOrName;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
Expand Down Expand Up @@ -1236,6 +1238,84 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

pub(crate) fn suggest_associated_const(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected_ty: Ty<'tcx>,
) -> bool {
let Some((DefKind::AssocFn, old_def_id)) = self.typeck_results.borrow().type_dependent_def(expr.hir_id) else {
return false;
};
let old_item_name = self.tcx.item_name(old_def_id);
let capitalized_name = Symbol::intern(&old_item_name.as_str().to_uppercase());
if old_item_name == capitalized_name {
return false;
}
let (item, segment) = match expr.kind {
hir::ExprKind::Path(QPath::Resolved(
Some(ty),
hir::Path { segments: [segment], .. },
))
| hir::ExprKind::Path(QPath::TypeRelative(ty, segment)) => {
let self_ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
if let Ok(pick) = self.probe_for_name(
Mode::Path,
Ident::new(capitalized_name, segment.ident.span),
IsSuggestion(true),
self_ty,
expr.hir_id,
ProbeScope::TraitsInScope,
) {
(pick.item, segment)
} else {
return false;
}
}
hir::ExprKind::Path(QPath::Resolved(
None,
hir::Path { segments: [.., segment], .. },
)) => {
// we resolved through some path that doesn't end in the item name,
// better not do a bad suggestion by accident.
if old_item_name != segment.ident.name {
return false;
}
if let Some(item) = self
.tcx
.associated_items(self.tcx.parent(old_def_id))
.filter_by_name_unhygienic(capitalized_name)
.next()
{
(*item, segment)
} else {
return false;
}
}
_ => return false,
};
if item.def_id == old_def_id || self.tcx.def_kind(item.def_id) != DefKind::AssocConst {
// Same item
return false;
}
let item_ty = self.tcx.type_of(item.def_id);
// FIXME(compiler-errors): This check is *so* rudimentary
if item_ty.needs_subst() {
return false;
}
if self.can_coerce(item_ty, expected_ty) {
err.span_suggestion_verbose(
segment.ident.span,
format!("try referring to the associated const `{capitalized_name}` instead",),
capitalized_name,
Applicability::MachineApplicable,
);
true
} else {
false
}
}

fn is_loop(&self, id: hir::HirId) -> bool {
let node = self.tcx.hir().get(id);
matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
self.tcx()
.sess
.delay_span_bug(expr.span, format!("could not resolve infer vars in `{ty}`"));
return;
}
let ty = self.tcx().erase_regions(ty);
let m = self.tcx().parent_module(expr.hir_id).to_def_id();
Expand Down
72 changes: 71 additions & 1 deletion compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::{
types::{transparent_newtype_field, CItemKind},
EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext,
};
use hir::IsAsync;
use rustc_ast::attr;
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::visit::{FnCtxt, FnKind};
Expand All @@ -40,7 +41,10 @@ use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, Gate
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
use rustc_hir::{ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin};
use rustc_hir::intravisit::FnKind as HirFnKind;
use rustc_hir::{
Body, FnDecl, ForeignItemKind, GenericParamKind, HirId, Node, PatKind, PredicateOrigin,
};
use rustc_index::vec::Idx;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::{LayoutError, LayoutOf};
Expand Down Expand Up @@ -1370,6 +1374,72 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures {
}
}

declare_lint! {
/// The `ungated_async_fn_track_caller` lint warns when the
/// `#[track_caller]` attribute is used on an async function, method, or
/// closure, without enabling the corresponding unstable feature flag.
///
/// ### Example
///
/// ```rust
/// #[track_caller]
/// async fn foo() {}
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The attribute must be used in conjunction with the
/// [`closure_track_caller` feature flag]. Otherwise, the `#[track_caller]`
/// annotation will function as as no-op.
///
/// [`closure_track_caller` feature flag]: https://doc.rust-lang.org/beta/unstable-book/language-features/closure-track-caller.html
UNGATED_ASYNC_FN_TRACK_CALLER,
Warn,
"enabling track_caller on an async fn is a no-op unless the closure_track_caller feature is enabled"
}

declare_lint_pass!(
/// Explains corresponding feature flag must be enabled for the `#[track_caller] attribute to
/// do anything
UngatedAsyncFnTrackCaller => [UNGATED_ASYNC_FN_TRACK_CALLER]
);

impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
fn check_fn(
&mut self,
cx: &LateContext<'_>,
fn_kind: HirFnKind<'_>,
_: &'tcx FnDecl<'_>,
_: &'tcx Body<'_>,
span: Span,
hir_id: HirId,
) {
if fn_kind.asyncness() == IsAsync::Async
&& !cx.tcx.features().closure_track_caller
&& let attrs = cx.tcx.hir().attrs(hir_id)
// Now, check if the function has the `#[track_caller]` attribute
&& let Some(attr) = attrs.iter().find(|attr| attr.has_name(sym::track_caller))
{
cx.struct_span_lint(
UNGATED_ASYNC_FN_TRACK_CALLER,
attr.span,
fluent::lint_ungated_async_fn_track_caller,
|lint| {
lint.span_label(span, fluent::label);
rustc_session::parse::add_feature_diagnostics(
lint,
&cx.tcx.sess.parse_sess,
sym::closure_track_caller,
);
lint
},
);
}
}
}

declare_lint! {
/// The `unreachable_pub` lint triggers for `pub` items not reachable from
/// the crate root.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ late_lint_methods!(
// May Depend on constants elsewhere
UnusedBrokenConst: UnusedBrokenConst,
UnstableFeatures: UnstableFeatures,
UngatedAsyncFnTrackCaller: UngatedAsyncFnTrackCaller,
ArrayIntoIter: ArrayIntoIter::default(),
DropTraitConstraints: DropTraitConstraints,
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
Expand Down
Loading