Skip to content

Rollup of 6 pull requests #112324

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

Merged
merged 15 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
6 changes: 5 additions & 1 deletion compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.associated_items(pred.def_id())
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
.filter(|item| item.opt_rpitit_info.is_none())
.map(|item| item.def_id),
);
}
Expand Down Expand Up @@ -1643,6 +1643,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}

// `dyn Trait<Assoc = Foo>` desugars to (not Rust syntax) `dyn Trait where <Self as Trait>::Assoc = Foo`.
// So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
// types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
// corresponding `Projection` clause
for (projection_bound, _) in &projection_bounds {
for def_ids in associated_types.values_mut() {
def_ids.remove(&projection_bound.projection_def_id());
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ fn compare_method_predicate_entailment<'tcx>(
return Err(emitted);
}

if check_implied_wf == CheckImpliedWfMode::Check {
if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
// We need to check that the impl's args are well-formed given
// the hybrid param-env (impl + trait method where-clauses).
ocx.register_obligation(traits::Obligation::new(
Expand Down Expand Up @@ -1216,7 +1216,7 @@ fn compare_number_of_generics<'tcx>(
// has mismatched type or const generic arguments, then the method that it's
// inheriting the generics from will also have mismatched arguments, and
// we'll report an error for that instead. Delay a bug for safety, though.
if tcx.opt_rpitit_info(trait_.def_id).is_some() {
if trait_.opt_rpitit_info.is_some() {
return Err(tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"errors comparing numbers of generics of trait/impl functions were not emitted",
Expand Down Expand Up @@ -2006,7 +2006,7 @@ pub(super) fn check_type_bounds<'tcx>(
// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized
// associated type.
let impl_ty_span = if tcx.opt_rpitit_info(impl_ty.def_id).is_some() {
let impl_ty_span = if impl_ty.opt_rpitit_info.is_some() {
tcx.def_span(impl_ty_def_id)
} else {
match tcx.hir().get_by_def_id(impl_ty_def_id) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ fn missing_items_err(
full_impl_span: Span,
) {
let missing_items =
missing_items.iter().filter(|trait_item| tcx.opt_rpitit_info(trait_item.def_id).is_none());
missing_items.iter().filter(|trait_item| trait_item.opt_rpitit_info.is_none());

let missing_items_msg = missing_items
.clone()
Expand Down
59 changes: 42 additions & 17 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ trait UnusedDelimLint {
followed_by_block: bool,
left_pos: Option<BytePos>,
right_pos: Option<BytePos>,
is_kw: bool,
);

fn is_expr_delims_necessary(
Expand Down Expand Up @@ -624,6 +625,7 @@ trait UnusedDelimLint {
ctx: UnusedDelimsCtx,
left_pos: Option<BytePos>,
right_pos: Option<BytePos>,
is_kw: bool,
) {
// If `value` has `ExprKind::Err`, unused delim lint can be broken.
// For example, the following code caused ICE.
Expand Down Expand Up @@ -667,7 +669,7 @@ trait UnusedDelimLint {
left_pos.is_some_and(|s| s >= value.span.lo()),
right_pos.is_some_and(|s| s <= value.span.hi()),
);
self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space);
self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space, is_kw);
}

fn emit_unused_delims(
Expand All @@ -677,6 +679,7 @@ trait UnusedDelimLint {
spans: Option<(Span, Span)>,
msg: &str,
keep_space: (bool, bool),
is_kw: bool,
) {
let primary_span = if let Some((lo, hi)) = spans {
if hi.is_empty() {
Expand All @@ -690,7 +693,7 @@ trait UnusedDelimLint {
let suggestion = spans.map(|(lo, hi)| {
let sm = cx.sess().source_map();
let lo_replace =
if keep_space.0 &&
if (keep_space.0 || is_kw) &&
let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') {
" "
} else {
Expand Down Expand Up @@ -720,15 +723,15 @@ trait UnusedDelimLint {

fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
use rustc_ast::ExprKind::*;
let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind {
let (value, ctx, followed_by_block, left_pos, right_pos, is_kw) = match e.kind {
// Do not lint `unused_braces` in `if let` expressions.
If(ref cond, ref block, _)
if !matches!(cond.kind, Let(_, _, _))
|| Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX =>
{
let left = e.span.lo() + rustc_span::BytePos(2);
let right = block.span.lo();
(cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right))
(cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right), true)
}

// Do not lint `unused_braces` in `while let` expressions.
Expand All @@ -738,27 +741,27 @@ trait UnusedDelimLint {
{
let left = e.span.lo() + rustc_span::BytePos(5);
let right = block.span.lo();
(cond, UnusedDelimsCtx::WhileCond, true, Some(left), Some(right))
(cond, UnusedDelimsCtx::WhileCond, true, Some(left), Some(right), true)
}

ForLoop(_, ref cond, ref block, ..) => {
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()))
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()), true)
}

Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
let left = e.span.lo() + rustc_span::BytePos(5);
(head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None)
(head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None, true)
}

Ret(Some(ref value)) => {
let left = e.span.lo() + rustc_span::BytePos(3);
(value, UnusedDelimsCtx::ReturnValue, false, Some(left), None)
(value, UnusedDelimsCtx::ReturnValue, false, Some(left), None, true)
}

Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None),
Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),

Assign(_, ref value, _) | AssignOp(.., ref value) => {
(value, UnusedDelimsCtx::AssignedValue, false, None, None)
(value, UnusedDelimsCtx::AssignedValue, false, None, None, false)
}
// either function/method call, or something this lint doesn't care about
ref call_or_other => {
Expand All @@ -778,12 +781,20 @@ trait UnusedDelimLint {
return;
}
for arg in args_to_check {
self.check_unused_delims_expr(cx, arg, ctx, false, None, None);
self.check_unused_delims_expr(cx, arg, ctx, false, None, None, false);
}
return;
}
};
self.check_unused_delims_expr(cx, &value, ctx, followed_by_block, left_pos, right_pos);
self.check_unused_delims_expr(
cx,
&value,
ctx,
followed_by_block,
left_pos,
right_pos,
is_kw,
);
}

fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
Expand All @@ -794,7 +805,7 @@ trait UnusedDelimLint {
None => UnusedDelimsCtx::AssignedValue,
Some(_) => UnusedDelimsCtx::AssignedValueLetElse,
};
self.check_unused_delims_expr(cx, init, ctx, false, None, None);
self.check_unused_delims_expr(cx, init, ctx, false, None, None, false);
}
}
StmtKind::Expr(ref expr) => {
Expand All @@ -805,6 +816,7 @@ trait UnusedDelimLint {
false,
None,
None,
false,
);
}
_ => {}
Expand All @@ -824,6 +836,7 @@ trait UnusedDelimLint {
false,
None,
None,
false,
);
}
}
Expand Down Expand Up @@ -879,6 +892,7 @@ impl UnusedDelimLint for UnusedParens {
followed_by_block: bool,
left_pos: Option<BytePos>,
right_pos: Option<BytePos>,
is_kw: bool,
) {
match value.kind {
ast::ExprKind::Paren(ref inner) => {
Expand All @@ -893,7 +907,7 @@ impl UnusedDelimLint for UnusedParens {
_,
) if node.lazy()))
{
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos)
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
}
}
ast::ExprKind::Let(_, ref expr, _) => {
Expand All @@ -904,6 +918,7 @@ impl UnusedDelimLint for UnusedParens {
followed_by_block,
None,
None,
false,
);
}
_ => {}
Expand Down Expand Up @@ -942,7 +957,7 @@ impl UnusedParens {
.span
.find_ancestor_inside(value.span)
.map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())));
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space);
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space, false);
}
}
}
Expand All @@ -967,6 +982,7 @@ impl EarlyLintPass for UnusedParens {
true,
None,
None,
true,
);
for stmt in &block.stmts {
<Self as UnusedDelimLint>::check_stmt(self, cx, stmt);
Expand All @@ -985,6 +1001,7 @@ impl EarlyLintPass for UnusedParens {
false,
None,
None,
true,
);
}
}
Expand Down Expand Up @@ -1043,6 +1060,7 @@ impl EarlyLintPass for UnusedParens {
false,
None,
None,
false,
);
}
ast::TyKind::Paren(r) => {
Expand All @@ -1057,7 +1075,7 @@ impl EarlyLintPass for UnusedParens {
.find_ancestor_inside(ty.span)
.map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())));

self.emit_unused_delims(cx, ty.span, spans, "type", (false, false));
self.emit_unused_delims(cx, ty.span, spans, "type", (false, false), false);
}
}
self.with_self_ty_parens = false;
Expand Down Expand Up @@ -1130,6 +1148,7 @@ impl UnusedDelimLint for UnusedBraces {
followed_by_block: bool,
left_pos: Option<BytePos>,
right_pos: Option<BytePos>,
is_kw: bool,
) {
match value.kind {
ast::ExprKind::Block(ref inner, None)
Expand Down Expand Up @@ -1170,7 +1189,7 @@ impl UnusedDelimLint for UnusedBraces {
&& !value.span.from_expansion()
&& !inner.span.from_expansion()
{
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos)
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
}
}
}
Expand All @@ -1183,6 +1202,7 @@ impl UnusedDelimLint for UnusedBraces {
followed_by_block,
None,
None,
false,
);
}
_ => {}
Expand All @@ -1207,6 +1227,7 @@ impl EarlyLintPass for UnusedBraces {
false,
None,
None,
false,
);
}
}
Expand All @@ -1220,6 +1241,7 @@ impl EarlyLintPass for UnusedBraces {
false,
None,
None,
false,
);
}
}
Expand All @@ -1233,6 +1255,7 @@ impl EarlyLintPass for UnusedBraces {
false,
None,
None,
false,
);
}
}
Expand All @@ -1247,6 +1270,7 @@ impl EarlyLintPass for UnusedBraces {
false,
None,
None,
false,
);
}

Expand All @@ -1258,6 +1282,7 @@ impl EarlyLintPass for UnusedBraces {
false,
None,
None,
false,
);
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ passes_doc_keyword_not_mod =
passes_doc_keyword_only_impl =
`#[doc(keyword = "...")]` should be used on impl blocks

passes_doc_test_literal = `#![doc(test(...)]` does not take a literal

passes_doc_test_takes_list =
`#[doc(test(...)]` takes a list of attributes

Expand Down
19 changes: 13 additions & 6 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,21 +944,28 @@ impl CheckAttrVisitor<'_> {
let mut is_valid = true;
if let Some(metas) = meta.meta_item_list() {
for i_meta in metas {
match i_meta.name_or_empty() {
sym::attr | sym::no_crate_inject => {}
_ => {
match (i_meta.name_or_empty(), i_meta.meta_item()) {
(sym::attr | sym::no_crate_inject, _) => {}
(_, Some(m)) => {
self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span(),
errors::DocTestUnknown {
path: rustc_ast_pretty::pprust::path_to_string(
&i_meta.meta_item().unwrap().path,
),
path: rustc_ast_pretty::pprust::path_to_string(&m.path),
},
);
is_valid = false;
}
(_, None) => {
self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span(),
errors::DocTestLiteral,
);
is_valid = false;
}
}
}
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ pub struct DocTestUnknown {
pub path: String,
}

#[derive(LintDiagnostic)]
#[diag(passes_doc_test_literal)]
pub struct DocTestLiteral;

#[derive(LintDiagnostic)]
#[diag(passes_doc_test_takes_list)]
pub struct DocTestTakesList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3592,8 +3592,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Extract `<U as Deref>::Target` assoc type and check that it is `T`
&& let Some(deref_target_did) = tcx.lang_items().deref_target()
&& let projection = tcx.mk_projection(deref_target_did, tcx.mk_substs(&[ty::GenericArg::from(found_ty)]))
&& let Ok(deref_target) = tcx.try_normalize_erasing_regions(param_env, projection)
&& deref_target == target_ty
&& let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(projection)
&& obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation))
&& infcx.can_eq(param_env, deref_target, target_ty)
{
let help = if let hir::Mutability::Mut = needs_mut
&& let Some(deref_mut_did) = tcx.lang_items().deref_mut_trait()
Expand Down
Loading