Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit adc719d

Browse files
committedJun 5, 2023
Auto merge of #112324 - matthiaskrgr:rollup-qscmi3c, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #112081 (Avoid ICE on `#![doc(test(...)]` with literal parameter) - #112196 (Resolve vars in result from `scrape_region_constraints`) - #112303 (Normalize in infcx instead of globally for `Option::as_deref` suggestion) - #112316 (Ensure space is inserted after keyword in `unused_delims`) - #112318 (Merge method, type and const object safety checks) - #112322 (Don't mention `IMPLIED_BOUNDS_ENTAILMENT` if signatures reference error) Failed merges: - #112251 (rustdoc: convert `if let Some()` that always matches to variable) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e6d4725 + dcdd867 commit adc719d

27 files changed

+364
-136
lines changed
 

‎compiler/rustc_hir_analysis/src/astconv/mod.rs‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1601,7 +1601,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16011601
tcx.associated_items(pred.def_id())
16021602
.in_definition_order()
16031603
.filter(|item| item.kind == ty::AssocKind::Type)
1604-
.filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
1604+
.filter(|item| item.opt_rpitit_info.is_none())
16051605
.map(|item| item.def_id),
16061606
);
16071607
}
@@ -1643,6 +1643,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16431643
}
16441644
}
16451645

1646+
// `dyn Trait<Assoc = Foo>` desugars to (not Rust syntax) `dyn Trait where <Self as Trait>::Assoc = Foo`.
1647+
// So every `Projection` clause is an `Assoc = Foo` bound. `associated_types` contains all associated
1648+
// types's `DefId`, so the following loop removes all the `DefIds` of the associated types that have a
1649+
// corresponding `Projection` clause
16461650
for (projection_bound, _) in &projection_bounds {
16471651
for def_ids in associated_types.values_mut() {
16481652
def_ids.remove(&projection_bound.projection_def_id());

‎compiler/rustc_hir_analysis/src/check/compare_impl_item.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ fn compare_method_predicate_entailment<'tcx>(
302302
return Err(emitted);
303303
}
304304

305-
if check_implied_wf == CheckImpliedWfMode::Check {
305+
if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
306306
// We need to check that the impl's args are well-formed given
307307
// the hybrid param-env (impl + trait method where-clauses).
308308
ocx.register_obligation(traits::Obligation::new(
@@ -1216,7 +1216,7 @@ fn compare_number_of_generics<'tcx>(
12161216
// has mismatched type or const generic arguments, then the method that it's
12171217
// inheriting the generics from will also have mismatched arguments, and
12181218
// we'll report an error for that instead. Delay a bug for safety, though.
1219-
if tcx.opt_rpitit_info(trait_.def_id).is_some() {
1219+
if trait_.opt_rpitit_info.is_some() {
12201220
return Err(tcx.sess.delay_span_bug(
12211221
rustc_span::DUMMY_SP,
12221222
"errors comparing numbers of generics of trait/impl functions were not emitted",
@@ -2006,7 +2006,7 @@ pub(super) fn check_type_bounds<'tcx>(
20062006
// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
20072007
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized
20082008
// associated type.
2009-
let impl_ty_span = if tcx.opt_rpitit_info(impl_ty.def_id).is_some() {
2009+
let impl_ty_span = if impl_ty.opt_rpitit_info.is_some() {
20102010
tcx.def_span(impl_ty_def_id)
20112011
} else {
20122012
match tcx.hir().get_by_def_id(impl_ty_def_id) {

‎compiler/rustc_hir_analysis/src/check/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ fn missing_items_err(
188188
full_impl_span: Span,
189189
) {
190190
let missing_items =
191-
missing_items.iter().filter(|trait_item| tcx.opt_rpitit_info(trait_item.def_id).is_none());
191+
missing_items.iter().filter(|trait_item| trait_item.opt_rpitit_info.is_none());
192192

193193
let missing_items_msg = missing_items
194194
.clone()

‎compiler/rustc_lint/src/unused.rs‎

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ trait UnusedDelimLint {
556556
followed_by_block: bool,
557557
left_pos: Option<BytePos>,
558558
right_pos: Option<BytePos>,
559+
is_kw: bool,
559560
);
560561

561562
fn is_expr_delims_necessary(
@@ -624,6 +625,7 @@ trait UnusedDelimLint {
624625
ctx: UnusedDelimsCtx,
625626
left_pos: Option<BytePos>,
626627
right_pos: Option<BytePos>,
628+
is_kw: bool,
627629
) {
628630
// If `value` has `ExprKind::Err`, unused delim lint can be broken.
629631
// For example, the following code caused ICE.
@@ -667,7 +669,7 @@ trait UnusedDelimLint {
667669
left_pos.is_some_and(|s| s >= value.span.lo()),
668670
right_pos.is_some_and(|s| s <= value.span.hi()),
669671
);
670-
self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space);
672+
self.emit_unused_delims(cx, value.span, spans, ctx.into(), keep_space, is_kw);
671673
}
672674

673675
fn emit_unused_delims(
@@ -677,6 +679,7 @@ trait UnusedDelimLint {
677679
spans: Option<(Span, Span)>,
678680
msg: &str,
679681
keep_space: (bool, bool),
682+
is_kw: bool,
680683
) {
681684
let primary_span = if let Some((lo, hi)) = spans {
682685
if hi.is_empty() {
@@ -690,7 +693,7 @@ trait UnusedDelimLint {
690693
let suggestion = spans.map(|(lo, hi)| {
691694
let sm = cx.sess().source_map();
692695
let lo_replace =
693-
if keep_space.0 &&
696+
if (keep_space.0 || is_kw) &&
694697
let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') {
695698
" "
696699
} else {
@@ -720,15 +723,15 @@ trait UnusedDelimLint {
720723

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

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

744747
ForLoop(_, ref cond, ref block, ..) => {
745-
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()))
748+
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()), true)
746749
}
747750

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

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

758-
Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None),
761+
Index(_, ref value) => (value, UnusedDelimsCtx::IndexExpr, false, None, None, false),
759762

760763
Assign(_, ref value, _) | AssignOp(.., ref value) => {
761-
(value, UnusedDelimsCtx::AssignedValue, false, None, None)
764+
(value, UnusedDelimsCtx::AssignedValue, false, None, None, false)
762765
}
763766
// either function/method call, or something this lint doesn't care about
764767
ref call_or_other => {
@@ -778,12 +781,20 @@ trait UnusedDelimLint {
778781
return;
779782
}
780783
for arg in args_to_check {
781-
self.check_unused_delims_expr(cx, arg, ctx, false, None, None);
784+
self.check_unused_delims_expr(cx, arg, ctx, false, None, None, false);
782785
}
783786
return;
784787
}
785788
};
786-
self.check_unused_delims_expr(cx, &value, ctx, followed_by_block, left_pos, right_pos);
789+
self.check_unused_delims_expr(
790+
cx,
791+
&value,
792+
ctx,
793+
followed_by_block,
794+
left_pos,
795+
right_pos,
796+
is_kw,
797+
);
787798
}
788799

789800
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
@@ -794,7 +805,7 @@ trait UnusedDelimLint {
794805
None => UnusedDelimsCtx::AssignedValue,
795806
Some(_) => UnusedDelimsCtx::AssignedValueLetElse,
796807
};
797-
self.check_unused_delims_expr(cx, init, ctx, false, None, None);
808+
self.check_unused_delims_expr(cx, init, ctx, false, None, None, false);
798809
}
799810
}
800811
StmtKind::Expr(ref expr) => {
@@ -805,6 +816,7 @@ trait UnusedDelimLint {
805816
false,
806817
None,
807818
None,
819+
false,
808820
);
809821
}
810822
_ => {}
@@ -824,6 +836,7 @@ trait UnusedDelimLint {
824836
false,
825837
None,
826838
None,
839+
false,
827840
);
828841
}
829842
}
@@ -879,6 +892,7 @@ impl UnusedDelimLint for UnusedParens {
879892
followed_by_block: bool,
880893
left_pos: Option<BytePos>,
881894
right_pos: Option<BytePos>,
895+
is_kw: bool,
882896
) {
883897
match value.kind {
884898
ast::ExprKind::Paren(ref inner) => {
@@ -893,7 +907,7 @@ impl UnusedDelimLint for UnusedParens {
893907
_,
894908
) if node.lazy()))
895909
{
896-
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos)
910+
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
897911
}
898912
}
899913
ast::ExprKind::Let(_, ref expr, _) => {
@@ -904,6 +918,7 @@ impl UnusedDelimLint for UnusedParens {
904918
followed_by_block,
905919
None,
906920
None,
921+
false,
907922
);
908923
}
909924
_ => {}
@@ -942,7 +957,7 @@ impl UnusedParens {
942957
.span
943958
.find_ancestor_inside(value.span)
944959
.map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi())));
945-
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space);
960+
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space, false);
946961
}
947962
}
948963
}
@@ -967,6 +982,7 @@ impl EarlyLintPass for UnusedParens {
967982
true,
968983
None,
969984
None,
985+
true,
970986
);
971987
for stmt in &block.stmts {
972988
<Self as UnusedDelimLint>::check_stmt(self, cx, stmt);
@@ -985,6 +1001,7 @@ impl EarlyLintPass for UnusedParens {
9851001
false,
9861002
None,
9871003
None,
1004+
true,
9881005
);
9891006
}
9901007
}
@@ -1043,6 +1060,7 @@ impl EarlyLintPass for UnusedParens {
10431060
false,
10441061
None,
10451062
None,
1063+
false,
10461064
);
10471065
}
10481066
ast::TyKind::Paren(r) => {
@@ -1057,7 +1075,7 @@ impl EarlyLintPass for UnusedParens {
10571075
.find_ancestor_inside(ty.span)
10581076
.map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())));
10591077

1060-
self.emit_unused_delims(cx, ty.span, spans, "type", (false, false));
1078+
self.emit_unused_delims(cx, ty.span, spans, "type", (false, false), false);
10611079
}
10621080
}
10631081
self.with_self_ty_parens = false;
@@ -1130,6 +1148,7 @@ impl UnusedDelimLint for UnusedBraces {
11301148
followed_by_block: bool,
11311149
left_pos: Option<BytePos>,
11321150
right_pos: Option<BytePos>,
1151+
is_kw: bool,
11331152
) {
11341153
match value.kind {
11351154
ast::ExprKind::Block(ref inner, None)
@@ -1170,7 +1189,7 @@ impl UnusedDelimLint for UnusedBraces {
11701189
&& !value.span.from_expansion()
11711190
&& !inner.span.from_expansion()
11721191
{
1173-
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos)
1192+
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
11741193
}
11751194
}
11761195
}
@@ -1183,6 +1202,7 @@ impl UnusedDelimLint for UnusedBraces {
11831202
followed_by_block,
11841203
None,
11851204
None,
1205+
false,
11861206
);
11871207
}
11881208
_ => {}
@@ -1207,6 +1227,7 @@ impl EarlyLintPass for UnusedBraces {
12071227
false,
12081228
None,
12091229
None,
1230+
false,
12101231
);
12111232
}
12121233
}
@@ -1220,6 +1241,7 @@ impl EarlyLintPass for UnusedBraces {
12201241
false,
12211242
None,
12221243
None,
1244+
false,
12231245
);
12241246
}
12251247
}
@@ -1233,6 +1255,7 @@ impl EarlyLintPass for UnusedBraces {
12331255
false,
12341256
None,
12351257
None,
1258+
false,
12361259
);
12371260
}
12381261
}
@@ -1247,6 +1270,7 @@ impl EarlyLintPass for UnusedBraces {
12471270
false,
12481271
None,
12491272
None,
1273+
false,
12501274
);
12511275
}
12521276

@@ -1258,6 +1282,7 @@ impl EarlyLintPass for UnusedBraces {
12581282
false,
12591283
None,
12601284
None,
1285+
false,
12611286
);
12621287
}
12631288

‎compiler/rustc_passes/messages.ftl‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ passes_doc_keyword_not_mod =
211211
passes_doc_keyword_only_impl =
212212
`#[doc(keyword = "...")]` should be used on impl blocks
213213
214+
passes_doc_test_literal = `#![doc(test(...)]` does not take a literal
215+
214216
passes_doc_test_takes_list =
215217
`#[doc(test(...)]` takes a list of attributes
216218

‎compiler/rustc_passes/src/check_attr.rs‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -944,21 +944,28 @@ impl CheckAttrVisitor<'_> {
944944
let mut is_valid = true;
945945
if let Some(metas) = meta.meta_item_list() {
946946
for i_meta in metas {
947-
match i_meta.name_or_empty() {
948-
sym::attr | sym::no_crate_inject => {}
949-
_ => {
947+
match (i_meta.name_or_empty(), i_meta.meta_item()) {
948+
(sym::attr | sym::no_crate_inject, _) => {}
949+
(_, Some(m)) => {
950950
self.tcx.emit_spanned_lint(
951951
INVALID_DOC_ATTRIBUTES,
952952
hir_id,
953953
i_meta.span(),
954954
errors::DocTestUnknown {
955-
path: rustc_ast_pretty::pprust::path_to_string(
956-
&i_meta.meta_item().unwrap().path,
957-
),
955+
path: rustc_ast_pretty::pprust::path_to_string(&m.path),
958956
},
959957
);
960958
is_valid = false;
961959
}
960+
(_, None) => {
961+
self.tcx.emit_spanned_lint(
962+
INVALID_DOC_ATTRIBUTES,
963+
hir_id,
964+
i_meta.span(),
965+
errors::DocTestLiteral,
966+
);
967+
is_valid = false;
968+
}
962969
}
963970
}
964971
} else {

‎compiler/rustc_passes/src/errors.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ pub struct DocTestUnknown {
281281
pub path: String,
282282
}
283283

284+
#[derive(LintDiagnostic)]
285+
#[diag(passes_doc_test_literal)]
286+
pub struct DocTestLiteral;
287+
284288
#[derive(LintDiagnostic)]
285289
#[diag(passes_doc_test_takes_list)]
286290
pub struct DocTestTakesList;

‎compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3592,8 +3592,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
35923592
// Extract `<U as Deref>::Target` assoc type and check that it is `T`
35933593
&& let Some(deref_target_did) = tcx.lang_items().deref_target()
35943594
&& let projection = tcx.mk_projection(deref_target_did, tcx.mk_substs(&[ty::GenericArg::from(found_ty)]))
3595-
&& let Ok(deref_target) = tcx.try_normalize_erasing_regions(param_env, projection)
3596-
&& deref_target == target_ty
3595+
&& let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(projection)
3596+
&& obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation))
3597+
&& infcx.can_eq(param_env, deref_target, target_ty)
35973598
{
35983599
let help = if let hir::Mutability::Mut = needs_mut
35993600
&& let Some(deref_mut_did) = tcx.lang_items().deref_mut_trait()

‎compiler/rustc_trait_selection/src/traits/object_safety.rs‎

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,11 @@ fn object_safety_violations_for_trait(
115115
tcx: TyCtxt<'_>,
116116
trait_def_id: DefId,
117117
) -> Vec<ObjectSafetyViolation> {
118-
// Check methods for violations.
118+
// Check assoc items for violations.
119119
let mut violations: Vec<_> = tcx
120120
.associated_items(trait_def_id)
121121
.in_definition_order()
122-
.filter(|item| item.kind == ty::AssocKind::Fn)
123-
.filter_map(|&item| {
124-
object_safety_violation_for_method(tcx, trait_def_id, item)
125-
.map(|(code, span)| ObjectSafetyViolation::Method(item.name, code, span))
126-
})
122+
.filter_map(|&item| object_safety_violation_for_assoc_item(tcx, trait_def_id, item))
127123
.collect();
128124

129125
// Check the trait itself.
@@ -145,30 +141,6 @@ fn object_safety_violations_for_trait(
145141
violations.push(ObjectSafetyViolation::SupertraitNonLifetimeBinder(spans));
146142
}
147143

148-
violations.extend(
149-
tcx.associated_items(trait_def_id)
150-
.in_definition_order()
151-
.filter(|item| item.kind == ty::AssocKind::Const)
152-
.map(|item| {
153-
let ident = item.ident(tcx);
154-
ObjectSafetyViolation::AssocConst(ident.name, ident.span)
155-
}),
156-
);
157-
158-
if !tcx.features().generic_associated_types_extended {
159-
violations.extend(
160-
tcx.associated_items(trait_def_id)
161-
.in_definition_order()
162-
.filter(|item| item.kind == ty::AssocKind::Type)
163-
.filter(|item| !tcx.generics_of(item.def_id).params.is_empty())
164-
.filter(|item| tcx.opt_rpitit_info(item.def_id).is_none())
165-
.map(|item| {
166-
let ident = item.ident(tcx);
167-
ObjectSafetyViolation::GAT(ident.name, ident.span)
168-
}),
169-
);
170-
}
171-
172144
debug!(
173145
"object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
174146
trait_def_id, violations
@@ -401,34 +373,54 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
401373
})
402374
}
403375

404-
/// Returns `Some(_)` if this method makes the containing trait not object safe.
405-
fn object_safety_violation_for_method(
376+
/// Returns `Some(_)` if this item makes the containing trait not object safe.
377+
#[instrument(level = "debug", skip(tcx), ret)]
378+
fn object_safety_violation_for_assoc_item(
406379
tcx: TyCtxt<'_>,
407380
trait_def_id: DefId,
408-
method: ty::AssocItem,
409-
) -> Option<(MethodViolationCode, Span)> {
410-
debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
411-
// Any method that has a `Self : Sized` requisite is otherwise
381+
item: ty::AssocItem,
382+
) -> Option<ObjectSafetyViolation> {
383+
// Any item that has a `Self : Sized` requisite is otherwise
412384
// exempt from the regulations.
413-
if generics_require_sized_self(tcx, method.def_id) {
385+
if generics_require_sized_self(tcx, item.def_id) {
414386
return None;
415387
}
416388

417-
let violation = virtual_call_violation_for_method(tcx, trait_def_id, method);
418-
// Get an accurate span depending on the violation.
419-
violation.map(|v| {
420-
let node = tcx.hir().get_if_local(method.def_id);
421-
let span = match (&v, node) {
422-
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
423-
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
424-
(MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
425-
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
426-
node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span())
389+
match item.kind {
390+
// Associated consts are never object safe, as they can't have `where` bounds yet at all,
391+
// and associated const bounds in trait objects aren't a thing yet either.
392+
ty::AssocKind::Const => {
393+
Some(ObjectSafetyViolation::AssocConst(item.name, item.ident(tcx).span))
394+
}
395+
ty::AssocKind::Fn => virtual_call_violation_for_method(tcx, trait_def_id, item).map(|v| {
396+
let node = tcx.hir().get_if_local(item.def_id);
397+
// Get an accurate span depending on the violation.
398+
let span = match (&v, node) {
399+
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
400+
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
401+
(MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
402+
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
403+
node.fn_decl().map_or(item.ident(tcx).span, |decl| decl.output.span())
404+
}
405+
_ => item.ident(tcx).span,
406+
};
407+
408+
ObjectSafetyViolation::Method(item.name, v, span)
409+
}),
410+
// Associated types can only be object safe if they have `Self: Sized` bounds.
411+
ty::AssocKind::Type => {
412+
if !tcx.features().generic_associated_types_extended
413+
&& !tcx.generics_of(item.def_id).params.is_empty()
414+
&& item.opt_rpitit_info.is_none()
415+
{
416+
Some(ObjectSafetyViolation::GAT(item.name, item.ident(tcx).span))
417+
} else {
418+
// We will permit associated types if they are explicitly mentioned in the trait object.
419+
// We can't check this here, as here we only check if it is guaranteed to not be possible.
420+
None
427421
}
428-
_ => method.ident(tcx).span,
429-
};
430-
(v, span)
431-
})
422+
}
423+
}
432424
}
433425

434426
/// Returns `Some(_)` if this method cannot be called on a trait

‎compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::traits::ObligationCtxt;
55
use rustc_errors::ErrorGuaranteed;
66
use rustc_infer::infer::region_constraints::RegionConstraintData;
77
use rustc_middle::traits::query::NoSolution;
8+
use rustc_middle::ty::{TyCtxt, TypeFoldable};
89
use rustc_span::source_map::DUMMY_SP;
910
use rustc_span::Span;
1011

@@ -24,9 +25,10 @@ impl<F> CustomTypeOp<F> {
2425
}
2526
}
2627

27-
impl<'tcx, F, R: fmt::Debug> super::TypeOp<'tcx> for CustomTypeOp<F>
28+
impl<'tcx, F, R> super::TypeOp<'tcx> for CustomTypeOp<F>
2829
where
2930
F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
31+
R: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
3032
{
3133
type Output = R;
3234
/// We can't do any custom error reporting for `CustomTypeOp`, so
@@ -57,12 +59,16 @@ impl<F> fmt::Debug for CustomTypeOp<F> {
5759

5860
/// Executes `op` and then scrapes out all the "old style" region
5961
/// constraints that result, creating query-region-constraints.
60-
pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
62+
pub fn scrape_region_constraints<'tcx, Op, R>(
6163
infcx: &InferCtxt<'tcx>,
6264
op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
6365
name: &'static str,
6466
span: Span,
65-
) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> {
67+
) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed>
68+
where
69+
R: TypeFoldable<TyCtxt<'tcx>>,
70+
Op: super::TypeOp<'tcx, Output = R>,
71+
{
6672
// During NLL, we expect that nobody will register region
6773
// obligations **except** as part of a custom type op (and, at the
6874
// end of each custom type op, we scrape out the region
@@ -91,6 +97,9 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
9197
}
9298
})?;
9399

100+
// Next trait solver performs operations locally, and normalize goals should resolve vars.
101+
let value = infcx.resolve_vars_if_possible(value);
102+
94103
let region_obligations = infcx.take_registered_region_obligations();
95104
let region_constraint_data = infcx.take_and_reset_region_constraints();
96105
let region_constraints = query_response::make_query_region_constraints(
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![deny(warnings)]
2+
3+
#![doc(test(""))]
4+
//~^ ERROR `#![doc(test(...)]` does not take a literal
5+
//~^^ WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6+
7+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: `#![doc(test(...)]` does not take a literal
2+
--> $DIR/doc-test-literal.rs:3:13
3+
|
4+
LL | #![doc(test(""))]
5+
| ^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
9+
note: the lint level is defined here
10+
--> $DIR/doc-test-literal.rs:1:9
11+
|
12+
LL | #![deny(warnings)]
13+
| ^^^^^^^^
14+
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
15+
16+
error: aborting due to previous error
17+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
trait Identity {
2+
type Identity;
3+
}
4+
impl<T> Identity for T {
5+
type Identity = T;
6+
}
7+
8+
trait Trait {
9+
type Assoc: Identity;
10+
fn tokenize(&self) -> <Self::Assoc as Identity>::Identity;
11+
}
12+
13+
impl Trait for () {
14+
type Assoc = DoesNotExist;
15+
//~^ ERROR cannot find type `DoesNotExist` in this scope
16+
17+
fn tokenize(&self) -> <Self::Assoc as Identity>::Identity {
18+
unimplemented!()
19+
}
20+
}
21+
22+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0412]: cannot find type `DoesNotExist` in this scope
2+
--> $DIR/references-err.rs:14:18
3+
|
4+
LL | type Assoc = DoesNotExist;
5+
| ^^^^^^^^^^^^ not found in this scope
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0412`.

‎tests/ui/issues/issue-13167.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// check-pass
22
// pretty-expanded FIXME #23616
3+
// revisions: current next
4+
//[next] compile-flags: -Ztrait-solver=next
35

46
use std::slice;
57

‎tests/ui/issues/issue-15734.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// run-pass
2-
// If `Index` used an associated type for its output, this test would
3-
// work more smoothly.
2+
// revisions: current next
3+
//[next] compile-flags: -Ztrait-solver=next
44

55
use std::ops::Index;
66

‎tests/ui/lint/lint-unnecessary-parens.fixed‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ pub fn passes_unused_parens_lint() -> &'static (dyn Trait) {
3535
panic!()
3636
}
3737

38+
pub fn parens_with_keyword(e: &[()]) -> i32 {
39+
if true {} //~ ERROR unnecessary parentheses around `if`
40+
while true {} //~ ERROR unnecessary parentheses around `while`
41+
for _ in e {} //~ ERROR unnecessary parentheses around `for`
42+
match 1 { _ => ()} //~ ERROR unnecessary parentheses around `match`
43+
return 1; //~ ERROR unnecessary parentheses around `return` value
44+
}
45+
3846
macro_rules! baz {
3947
($($foo:expr),+) => {
4048
($($foo),*)

‎tests/ui/lint/lint-unnecessary-parens.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ pub fn passes_unused_parens_lint() -> &'static (dyn Trait) {
3535
panic!()
3636
}
3737

38+
pub fn parens_with_keyword(e: &[()]) -> i32 {
39+
if(true) {} //~ ERROR unnecessary parentheses around `if`
40+
while(true) {} //~ ERROR unnecessary parentheses around `while`
41+
for _ in(e) {} //~ ERROR unnecessary parentheses around `for`
42+
match(1) { _ => ()} //~ ERROR unnecessary parentheses around `match`
43+
return(1); //~ ERROR unnecessary parentheses around `return` value
44+
}
45+
3846
macro_rules! baz {
3947
($($foo:expr),+) => {
4048
($($foo),*)

‎tests/ui/lint/lint-unnecessary-parens.stderr‎

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,68 @@ LL - (5)
6363
LL + 5
6464
|
6565

66+
error: unnecessary parentheses around `if` condition
67+
--> $DIR/lint-unnecessary-parens.rs:39:7
68+
|
69+
LL | if(true) {}
70+
| ^ ^
71+
|
72+
help: remove these parentheses
73+
|
74+
LL - if(true) {}
75+
LL + if true {}
76+
|
77+
78+
error: unnecessary parentheses around `while` condition
79+
--> $DIR/lint-unnecessary-parens.rs:40:10
80+
|
81+
LL | while(true) {}
82+
| ^ ^
83+
|
84+
help: remove these parentheses
85+
|
86+
LL - while(true) {}
87+
LL + while true {}
88+
|
89+
90+
error: unnecessary parentheses around `for` iterator expression
91+
--> $DIR/lint-unnecessary-parens.rs:41:13
92+
|
93+
LL | for _ in(e) {}
94+
| ^ ^
95+
|
96+
help: remove these parentheses
97+
|
98+
LL - for _ in(e) {}
99+
LL + for _ in e {}
100+
|
101+
102+
error: unnecessary parentheses around `match` scrutinee expression
103+
--> $DIR/lint-unnecessary-parens.rs:42:10
104+
|
105+
LL | match(1) { _ => ()}
106+
| ^ ^
107+
|
108+
help: remove these parentheses
109+
|
110+
LL - match(1) { _ => ()}
111+
LL + match 1 { _ => ()}
112+
|
113+
114+
error: unnecessary parentheses around `return` value
115+
--> $DIR/lint-unnecessary-parens.rs:43:11
116+
|
117+
LL | return(1);
118+
| ^ ^
119+
|
120+
help: remove these parentheses
121+
|
122+
LL - return(1);
123+
LL + return 1;
124+
|
125+
66126
error: unnecessary parentheses around assigned value
67-
--> $DIR/lint-unnecessary-parens.rs:44:31
127+
--> $DIR/lint-unnecessary-parens.rs:52:31
68128
|
69129
LL | pub const CONST_ITEM: usize = (10);
70130
| ^ ^
@@ -76,7 +136,7 @@ LL + pub const CONST_ITEM: usize = 10;
76136
|
77137

78138
error: unnecessary parentheses around assigned value
79-
--> $DIR/lint-unnecessary-parens.rs:45:33
139+
--> $DIR/lint-unnecessary-parens.rs:53:33
80140
|
81141
LL | pub static STATIC_ITEM: usize = (10);
82142
| ^ ^
@@ -88,7 +148,7 @@ LL + pub static STATIC_ITEM: usize = 10;
88148
|
89149

90150
error: unnecessary parentheses around function argument
91-
--> $DIR/lint-unnecessary-parens.rs:49:9
151+
--> $DIR/lint-unnecessary-parens.rs:57:9
92152
|
93153
LL | bar((true));
94154
| ^ ^
@@ -100,7 +160,7 @@ LL + bar(true);
100160
|
101161

102162
error: unnecessary parentheses around `if` condition
103-
--> $DIR/lint-unnecessary-parens.rs:51:8
163+
--> $DIR/lint-unnecessary-parens.rs:59:8
104164
|
105165
LL | if (true) {}
106166
| ^ ^
@@ -112,7 +172,7 @@ LL + if true {}
112172
|
113173

114174
error: unnecessary parentheses around `while` condition
115-
--> $DIR/lint-unnecessary-parens.rs:52:11
175+
--> $DIR/lint-unnecessary-parens.rs:60:11
116176
|
117177
LL | while (true) {}
118178
| ^ ^
@@ -124,7 +184,7 @@ LL + while true {}
124184
|
125185

126186
error: unnecessary parentheses around `match` scrutinee expression
127-
--> $DIR/lint-unnecessary-parens.rs:53:11
187+
--> $DIR/lint-unnecessary-parens.rs:61:11
128188
|
129189
LL | match (true) {
130190
| ^ ^
@@ -136,7 +196,7 @@ LL + match true {
136196
|
137197

138198
error: unnecessary parentheses around `let` scrutinee expression
139-
--> $DIR/lint-unnecessary-parens.rs:56:16
199+
--> $DIR/lint-unnecessary-parens.rs:64:16
140200
|
141201
LL | if let 1 = (1) {}
142202
| ^ ^
@@ -148,7 +208,7 @@ LL + if let 1 = 1 {}
148208
|
149209

150210
error: unnecessary parentheses around `let` scrutinee expression
151-
--> $DIR/lint-unnecessary-parens.rs:57:19
211+
--> $DIR/lint-unnecessary-parens.rs:65:19
152212
|
153213
LL | while let 1 = (2) {}
154214
| ^ ^
@@ -160,7 +220,7 @@ LL + while let 1 = 2 {}
160220
|
161221

162222
error: unnecessary parentheses around method argument
163-
--> $DIR/lint-unnecessary-parens.rs:73:24
223+
--> $DIR/lint-unnecessary-parens.rs:81:24
164224
|
165225
LL | X { y: false }.foo((true));
166226
| ^ ^
@@ -172,7 +232,7 @@ LL + X { y: false }.foo(true);
172232
|
173233

174234
error: unnecessary parentheses around assigned value
175-
--> $DIR/lint-unnecessary-parens.rs:75:18
235+
--> $DIR/lint-unnecessary-parens.rs:83:18
176236
|
177237
LL | let mut _a = (0);
178238
| ^ ^
@@ -184,7 +244,7 @@ LL + let mut _a = 0;
184244
|
185245

186246
error: unnecessary parentheses around assigned value
187-
--> $DIR/lint-unnecessary-parens.rs:76:10
247+
--> $DIR/lint-unnecessary-parens.rs:84:10
188248
|
189249
LL | _a = (0);
190250
| ^ ^
@@ -196,7 +256,7 @@ LL + _a = 0;
196256
|
197257

198258
error: unnecessary parentheses around assigned value
199-
--> $DIR/lint-unnecessary-parens.rs:77:11
259+
--> $DIR/lint-unnecessary-parens.rs:85:11
200260
|
201261
LL | _a += (1);
202262
| ^ ^
@@ -207,5 +267,5 @@ LL - _a += (1);
207267
LL + _a += 1;
208268
|
209269

210-
error: aborting due to 17 previous errors
270+
error: aborting due to 22 previous errors
211271

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn deref_int(a: &i32) -> i32 {
2+
*a
3+
}
4+
5+
fn main() {
6+
// https://github.com/rust-lang/rust/issues/112293
7+
let _has_inference_vars: Option<i32> = Some(0).map(deref_int);
8+
//~^ ERROR type mismatch in function arguments
9+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0631]: type mismatch in function arguments
2+
--> $DIR/suggest-option-asderef-inference-var.rs:7:56
3+
|
4+
LL | fn deref_int(a: &i32) -> i32 {
5+
| ---------------------------- found signature defined here
6+
...
7+
LL | let _has_inference_vars: Option<i32> = Some(0).map(deref_int);
8+
| --- ^^^^^^^^^ expected due to this
9+
| |
10+
| required by a bound introduced by this call
11+
|
12+
= note: expected function signature `fn({integer}) -> _`
13+
found function signature `for<'a> fn(&'a i32) -> _`
14+
note: required by a bound in `Option::<T>::map`
15+
--> $SRC_DIR/core/src/option.rs:LL:COL
16+
help: do not borrow the argument
17+
|
18+
LL - fn deref_int(a: &i32) -> i32 {
19+
LL + fn deref_int(a: i32) -> i32 {
20+
|
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0631`.

‎tests/ui/mismatched_types/suggest-option-asderef-unfixable.rs‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ fn no_args() -> Option<()> {
1010
Some(())
1111
}
1212

13-
fn generic_ref<T>(_: &T) -> Option<()> {
14-
Some(())
15-
}
16-
1713
extern "C" fn takes_str_but_wrong_abi(_: &str) -> Option<()> {
1814
Some(())
1915
}
@@ -33,8 +29,6 @@ fn main() {
3329
//~^ ERROR expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
3430
let _ = produces_string().and_then(no_args);
3531
//~^ ERROR function is expected to take 1 argument, but it takes 0 arguments
36-
let _ = produces_string().and_then(generic_ref);
37-
//~^ ERROR type mismatch in function arguments
3832
let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
3933
//~^ ERROR type mismatch in function arguments
4034
}

‎tests/ui/mismatched_types/suggest-option-asderef-unfixable.stderr‎

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0631]: type mismatch in function arguments
2-
--> $DIR/suggest-option-asderef-unfixable.rs:28:40
2+
--> $DIR/suggest-option-asderef-unfixable.rs:24:40
33
|
44
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
55
| ------------------------------------------------------ found signature defined here
@@ -15,7 +15,7 @@ note: required by a bound in `Option::<T>::and_then`
1515
--> $SRC_DIR/core/src/option.rs:LL:COL
1616

1717
error[E0277]: expected a `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
18-
--> $DIR/suggest-option-asderef-unfixable.rs:30:40
18+
--> $DIR/suggest-option-asderef-unfixable.rs:26:40
1919
|
2020
LL | let _ = produces_string().and_then(takes_str_but_wrong_abi);
2121
| -------- ^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
@@ -27,7 +27,7 @@ note: required by a bound in `Option::<T>::and_then`
2727
--> $SRC_DIR/core/src/option.rs:LL:COL
2828

2929
error[E0277]: expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
30-
--> $DIR/suggest-option-asderef-unfixable.rs:32:40
30+
--> $DIR/suggest-option-asderef-unfixable.rs:28:40
3131
|
3232
LL | let _ = produces_string().and_then(takes_str_but_unsafe);
3333
| -------- ^^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@@ -40,7 +40,7 @@ note: required by a bound in `Option::<T>::and_then`
4040
--> $SRC_DIR/core/src/option.rs:LL:COL
4141

4242
error[E0593]: function is expected to take 1 argument, but it takes 0 arguments
43-
--> $DIR/suggest-option-asderef-unfixable.rs:34:40
43+
--> $DIR/suggest-option-asderef-unfixable.rs:30:40
4444
|
4545
LL | fn no_args() -> Option<()> {
4646
| -------------------------- takes 0 arguments
@@ -54,28 +54,7 @@ note: required by a bound in `Option::<T>::and_then`
5454
--> $SRC_DIR/core/src/option.rs:LL:COL
5555

5656
error[E0631]: type mismatch in function arguments
57-
--> $DIR/suggest-option-asderef-unfixable.rs:36:40
58-
|
59-
LL | fn generic_ref<T>(_: &T) -> Option<()> {
60-
| -------------------------------------- found signature defined here
61-
...
62-
LL | let _ = produces_string().and_then(generic_ref);
63-
| -------- ^^^^^^^^^^^ expected due to this
64-
| |
65-
| required by a bound introduced by this call
66-
|
67-
= note: expected function signature `fn(String) -> _`
68-
found function signature `for<'a> fn(&'a _) -> _`
69-
note: required by a bound in `Option::<T>::and_then`
70-
--> $SRC_DIR/core/src/option.rs:LL:COL
71-
help: do not borrow the argument
72-
|
73-
LL - fn generic_ref<T>(_: &T) -> Option<()> {
74-
LL + fn generic_ref<T>(_: T) -> Option<()> {
75-
|
76-
77-
error[E0631]: type mismatch in function arguments
78-
--> $DIR/suggest-option-asderef-unfixable.rs:38:45
57+
--> $DIR/suggest-option-asderef-unfixable.rs:32:45
7958
|
8059
LL | fn takes_str_but_too_many_refs(_: &&str) -> Option<()> {
8160
| ------------------------------------------------------ found signature defined here
@@ -90,7 +69,7 @@ LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
9069
note: required by a bound in `Option::<T>::and_then`
9170
--> $SRC_DIR/core/src/option.rs:LL:COL
9271

93-
error: aborting due to 6 previous errors
72+
error: aborting due to 5 previous errors
9473

9574
Some errors have detailed explanations: E0277, E0593, E0631.
9675
For more information about an error, try `rustc --explain E0277`.

‎tests/ui/mismatched_types/suggest-option-asderef.fixed‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ fn generic<T>(_: T) -> Option<()> {
1616
Some(())
1717
}
1818

19+
fn generic_ref<T>(_: T) -> Option<()> {
20+
//~^ HELP do not borrow the argument
21+
Some(())
22+
}
23+
1924
fn main() {
2025
let _: Option<()> = produces_string().as_deref().and_then(takes_str);
2126
//~^ ERROR type mismatch in function arguments
@@ -27,4 +32,8 @@ fn main() {
2732
//~^ ERROR type mismatch in function arguments
2833
//~| HELP call `Option::as_deref_mut()` first
2934
let _ = produces_string().and_then(generic);
35+
36+
let _ = produces_string().as_deref().and_then(generic_ref);
37+
//~^ ERROR type mismatch in function arguments
38+
//~| HELP call `Option::as_deref()` first
3039
}

‎tests/ui/mismatched_types/suggest-option-asderef.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ fn generic<T>(_: T) -> Option<()> {
1616
Some(())
1717
}
1818

19+
fn generic_ref<T>(_: &T) -> Option<()> {
20+
//~^ HELP do not borrow the argument
21+
Some(())
22+
}
23+
1924
fn main() {
2025
let _: Option<()> = produces_string().and_then(takes_str);
2126
//~^ ERROR type mismatch in function arguments
@@ -27,4 +32,8 @@ fn main() {
2732
//~^ ERROR type mismatch in function arguments
2833
//~| HELP call `Option::as_deref_mut()` first
2934
let _ = produces_string().and_then(generic);
35+
36+
let _ = produces_string().and_then(generic_ref);
37+
//~^ ERROR type mismatch in function arguments
38+
//~| HELP call `Option::as_deref()` first
3039
}

‎tests/ui/mismatched_types/suggest-option-asderef.stderr‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0631]: type mismatch in function arguments
2-
--> $DIR/suggest-option-asderef.rs:20:52
2+
--> $DIR/suggest-option-asderef.rs:25:52
33
|
44
LL | fn takes_str(_: &str) -> Option<()> {
55
| ----------------------------------- found signature defined here
@@ -19,7 +19,7 @@ LL | let _: Option<()> = produces_string().as_deref().and_then(takes_str);
1919
| +++++++++++
2020

2121
error[E0631]: type mismatch in function arguments
22-
--> $DIR/suggest-option-asderef.rs:23:55
22+
--> $DIR/suggest-option-asderef.rs:28:55
2323
|
2424
LL | fn takes_str(_: &str) -> Option<()> {
2525
| ----------------------------------- found signature defined here
@@ -39,7 +39,7 @@ LL | let _: Option<Option<()>> = produces_string().as_deref().map(takes_str)
3939
| +++++++++++
4040

4141
error[E0631]: type mismatch in function arguments
42-
--> $DIR/suggest-option-asderef.rs:26:55
42+
--> $DIR/suggest-option-asderef.rs:31:55
4343
|
4444
LL | fn takes_str_mut(_: &mut str) -> Option<()> {
4545
| ------------------------------------------- found signature defined here
@@ -58,6 +58,31 @@ help: call `Option::as_deref_mut()` first
5858
LL | let _: Option<Option<()>> = produces_string().as_deref_mut().map(takes_str_mut);
5959
| +++++++++++++++
6060

61-
error: aborting due to 3 previous errors
61+
error[E0631]: type mismatch in function arguments
62+
--> $DIR/suggest-option-asderef.rs:36:40
63+
|
64+
LL | fn generic_ref<T>(_: &T) -> Option<()> {
65+
| -------------------------------------- found signature defined here
66+
...
67+
LL | let _ = produces_string().and_then(generic_ref);
68+
| -------- ^^^^^^^^^^^ expected due to this
69+
| |
70+
| required by a bound introduced by this call
71+
|
72+
= note: expected function signature `fn(String) -> _`
73+
found function signature `for<'a> fn(&'a _) -> _`
74+
note: required by a bound in `Option::<T>::and_then`
75+
--> $SRC_DIR/core/src/option.rs:LL:COL
76+
help: do not borrow the argument
77+
|
78+
LL - fn generic_ref<T>(_: &T) -> Option<()> {
79+
LL + fn generic_ref<T>(_: T) -> Option<()> {
80+
|
81+
help: call `Option::as_deref()` first
82+
|
83+
LL | let _ = produces_string().as_deref().and_then(generic_ref);
84+
| +++++++++++
85+
86+
error: aborting due to 4 previous errors
6287

6388
For more information about this error, try `rustc --explain E0631`.

‎tests/ui/nll/issue-53119.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// check-pass
2+
// revisions: current next
3+
//[next] compile-flags: -Ztrait-solver=next
24

35
use std::ops::Deref;
46

0 commit comments

Comments
 (0)
Please sign in to comment.