Skip to content

Commit 5ca6f7d

Browse files
committed
Auto merge of #106801 - JohnTitor:rollup-xqkraw0, r=JohnTitor
Rollup of 6 pull requests Successful merges: - #106608 (Render missing generics suggestion verbosely) - #106716 ([RFC 2397] Deny incorrect locations) - #106754 (Rename `Ty::is_ty_infer` -> `Ty::is_ty_or_numeric_infer`) - #106782 (Ignore tests move in git blame) - #106785 (Make blame spans better for impl wfcheck) - #106791 (Fix ICE formatting) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4a04f25 + c06d57e commit 5ca6f7d

File tree

52 files changed

+338
-153
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+338
-153
lines changed

.git-blame-ignore-revs

+2
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ a06baa56b95674fc626b3c3fd680d6a65357fe60
88
283abbf0e7d20176f76006825b5c52e9a4234e4c
99
# format libstd/sys
1010
c34fbfaad38cf5829ef5cfe780dc9d58480adeaa
11+
# move tests
12+
cf2dff2b1e3fa55fa5415d524200070d0d7aacfe

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ impl<'tcx> RegionErrors<'tcx> {
7979
#[track_caller]
8080
pub fn push(&mut self, val: impl Into<RegionErrorKind<'tcx>>) {
8181
let val = val.into();
82-
self.1.sess.delay_span_bug(DUMMY_SP, "{val:?}");
82+
self.1.sess.delay_span_bug(DUMMY_SP, format!("{val:?}"));
8383
self.0.push(val);
8484
}
8585
pub fn is_empty(&self) -> bool {

compiler/rustc_error_messages/locales/en-US/passes.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
-passes_see_issue =
55
see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
66
7+
passes_incorrect_do_not_recommend_location =
8+
`#[do_not_recommend]` can only be placed on trait implementations
9+
710
passes_outer_crate_level_attr =
811
crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
912

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,11 @@ fn check_impl<'tcx>(
12541254
// therefore don't need to be WF (the trait's `Self: Trait` predicate
12551255
// won't hold).
12561256
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap();
1257-
let trait_ref = wfcx.normalize(ast_trait_ref.path.span, None, trait_ref);
1257+
let trait_ref = wfcx.normalize(
1258+
ast_trait_ref.path.span,
1259+
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
1260+
trait_ref,
1261+
);
12581262
let trait_pred = ty::TraitPredicate {
12591263
trait_ref,
12601264
constness: match constness {
@@ -1263,14 +1267,21 @@ fn check_impl<'tcx>(
12631267
},
12641268
polarity: ty::ImplPolarity::Positive,
12651269
};
1266-
let obligations = traits::wf::trait_obligations(
1270+
let mut obligations = traits::wf::trait_obligations(
12671271
wfcx.infcx,
12681272
wfcx.param_env,
12691273
wfcx.body_id,
12701274
&trait_pred,
12711275
ast_trait_ref.path.span,
12721276
item,
12731277
);
1278+
for obligation in &mut obligations {
1279+
if let Some(pred) = obligation.predicate.to_opt_poly_trait_pred()
1280+
&& pred.self_ty().skip_binder() == trait_ref.self_ty()
1281+
{
1282+
obligation.cause.span = ast_self_ty.span;
1283+
}
1284+
}
12741285
debug!(?obligations);
12751286
wfcx.register_obligations(obligations);
12761287
}

compiler/rustc_hir_analysis/src/hir_wf_check.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -114,51 +114,63 @@ fn diagnostic_hir_wf_check<'tcx>(
114114
// Get the starting `hir::Ty` using our `WellFormedLoc`.
115115
// We will walk 'into' this type to try to find
116116
// a more precise span for our predicate.
117-
let ty = match loc {
117+
let tys = match loc {
118118
WellFormedLoc::Ty(_) => match hir.get(hir_id) {
119119
hir::Node::ImplItem(item) => match item.kind {
120-
hir::ImplItemKind::Type(ty) => Some(ty),
121-
hir::ImplItemKind::Const(ty, _) => Some(ty),
120+
hir::ImplItemKind::Type(ty) => vec![ty],
121+
hir::ImplItemKind::Const(ty, _) => vec![ty],
122122
ref item => bug!("Unexpected ImplItem {:?}", item),
123123
},
124124
hir::Node::TraitItem(item) => match item.kind {
125-
hir::TraitItemKind::Type(_, ty) => ty,
126-
hir::TraitItemKind::Const(ty, _) => Some(ty),
125+
hir::TraitItemKind::Type(_, ty) => ty.into_iter().collect(),
126+
hir::TraitItemKind::Const(ty, _) => vec![ty],
127127
ref item => bug!("Unexpected TraitItem {:?}", item),
128128
},
129129
hir::Node::Item(item) => match item.kind {
130-
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
131-
hir::ItemKind::Impl(ref impl_) => {
132-
assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
133-
Some(impl_.self_ty)
134-
}
130+
hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => vec![ty],
131+
hir::ItemKind::Impl(ref impl_) => match &impl_.of_trait {
132+
Some(t) => t
133+
.path
134+
.segments
135+
.last()
136+
.iter()
137+
.flat_map(|seg| seg.args().args)
138+
.filter_map(|arg| {
139+
if let hir::GenericArg::Type(ty) = arg { Some(*ty) } else { None }
140+
})
141+
.chain([impl_.self_ty])
142+
.collect(),
143+
None => {
144+
vec![impl_.self_ty]
145+
}
146+
},
135147
ref item => bug!("Unexpected item {:?}", item),
136148
},
137-
hir::Node::Field(field) => Some(field.ty),
149+
hir::Node::Field(field) => vec![field.ty],
138150
hir::Node::ForeignItem(ForeignItem {
139151
kind: ForeignItemKind::Static(ty, _), ..
140-
}) => Some(*ty),
152+
}) => vec![*ty],
141153
hir::Node::GenericParam(hir::GenericParam {
142154
kind: hir::GenericParamKind::Type { default: Some(ty), .. },
143155
..
144-
}) => Some(*ty),
156+
}) => vec![*ty],
145157
ref node => bug!("Unexpected node {:?}", node),
146158
},
147159
WellFormedLoc::Param { function: _, param_idx } => {
148160
let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
149161
// Get return type
150162
if param_idx as usize == fn_decl.inputs.len() {
151163
match fn_decl.output {
152-
hir::FnRetTy::Return(ty) => Some(ty),
164+
hir::FnRetTy::Return(ty) => vec![ty],
153165
// The unit type `()` is always well-formed
154-
hir::FnRetTy::DefaultReturn(_span) => None,
166+
hir::FnRetTy::DefaultReturn(_span) => vec![],
155167
}
156168
} else {
157-
Some(&fn_decl.inputs[param_idx as usize])
169+
vec![&fn_decl.inputs[param_idx as usize]]
158170
}
159171
}
160172
};
161-
if let Some(ty) = ty {
173+
for ty in tys {
162174
visitor.visit_ty(ty);
163175
}
164176
visitor.cause

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1782,9 +1782,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
17821782
// like when you have two references but one is `usize` and the other
17831783
// is `f32`. In those cases we still want to show the `note`. If the
17841784
// value from `ef` is `Infer(_)`, then we ignore it.
1785-
if !ef.expected.is_ty_infer() {
1785+
if !ef.expected.is_ty_or_numeric_infer() {
17861786
ef.expected != values.expected
1787-
} else if !ef.found.is_ty_infer() {
1787+
} else if !ef.found.is_ty_or_numeric_infer() {
17881788
ef.found != values.found
17891789
} else {
17901790
false

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl InferenceDiagnosticsData {
7878
}
7979

8080
fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str {
81-
if in_type.is_ty_infer() {
81+
if in_type.is_ty_or_numeric_infer() {
8282
""
8383
} else if self.name == "_" {
8484
// FIXME: Consider specializing this message if there is a single `_`
@@ -195,12 +195,12 @@ fn ty_to_string<'tcx>(
195195
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
196196
(ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
197197
(_, Some(def_id))
198-
if ty.is_ty_infer()
198+
if ty.is_ty_or_numeric_infer()
199199
&& infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
200200
{
201201
"Vec<_>".to_string()
202202
}
203-
_ if ty.is_ty_infer() => "/* Type */".to_string(),
203+
_ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
204204
// FIXME: The same thing for closures, but this only works when the closure
205205
// does not capture anything.
206206
//
@@ -680,7 +680,7 @@ impl<'tcx> InferSourceKind<'tcx> {
680680
| InferSourceKind::ClosureReturn { ty, .. } => {
681681
if ty.is_closure() {
682682
("closure", closure_as_fn_str(infcx, ty))
683-
} else if !ty.is_ty_infer() {
683+
} else if !ty.is_ty_or_numeric_infer() {
684684
("normal", ty_to_string(infcx, ty, None))
685685
} else {
686686
("other", String::new())
@@ -813,7 +813,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
813813
self.attempt += 1;
814814
if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source
815815
&& let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind
816-
&& ty.is_ty_infer()
816+
&& ty.is_ty_or_numeric_infer()
817817
{
818818
// Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
819819
// `let x: _ = iter.collect();`, as this is a very common case.

compiler/rustc_middle/src/ty/sty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,7 @@ impl<'tcx> Ty<'tcx> {
16861686
}
16871687

16881688
#[inline]
1689-
pub fn is_ty_infer(self) -> bool {
1689+
pub fn is_ty_or_numeric_infer(self) -> bool {
16901690
matches!(self.kind(), Infer(_))
16911691
}
16921692

compiler/rustc_middle/src/ty/subst.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl<'tcx> GenericArg<'tcx> {
202202
pub fn is_non_region_infer(self) -> bool {
203203
match self.unpack() {
204204
GenericArgKind::Lifetime(_) => false,
205-
GenericArgKind::Type(ty) => ty.is_ty_infer(),
205+
GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(),
206206
GenericArgKind::Const(ct) => ct.is_ct_infer(),
207207
}
208208
}

compiler/rustc_passes/src/check_attr.rs

+11
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ impl CheckAttrVisitor<'_> {
8282
let attrs = self.tcx.hir().attrs(hir_id);
8383
for attr in attrs {
8484
let attr_is_valid = match attr.name_or_empty() {
85+
sym::do_not_recommend => self.check_do_not_recommend(attr.span, target),
8586
sym::inline => self.check_inline(hir_id, attr, span, target),
8687
sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target),
8788
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
@@ -241,6 +242,16 @@ impl CheckAttrVisitor<'_> {
241242
);
242243
}
243244

245+
/// Checks if `#[do_not_recommend]` is applied on a trait impl.
246+
fn check_do_not_recommend(&self, attr_span: Span, target: Target) -> bool {
247+
if let Target::Impl = target {
248+
true
249+
} else {
250+
self.tcx.sess.emit_err(errors::IncorrectDoNotRecommendLocation { span: attr_span });
251+
false
252+
}
253+
}
254+
244255
/// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid.
245256
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
246257
match target {

compiler/rustc_passes/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ use rustc_span::{Span, Symbol, DUMMY_SP};
1414

1515
use crate::lang_items::Duplicate;
1616

17+
#[derive(Diagnostic)]
18+
#[diag(passes_incorrect_do_not_recommend_location)]
19+
pub struct IncorrectDoNotRecommendLocation {
20+
#[primary_span]
21+
pub span: Span,
22+
}
23+
1724
#[derive(LintDiagnostic)]
1825
#[diag(passes_outer_crate_level_attr)]
1926
pub struct OuterCrateLevelAttr;

compiler/rustc_resolve/src/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl<'a> Resolver<'a> {
167167
);
168168
err.emit();
169169
} else if let Some((span, msg, sugg, appl)) = suggestion {
170-
err.span_suggestion(span, msg, sugg, appl);
170+
err.span_suggestion_verbose(span, msg, sugg, appl);
171171
err.emit();
172172
} else if let [segment] = path.as_slice() && is_call {
173173
err.stash(segment.ident.span, rustc_errors::StashKey::CallIntoMethod);

compiler/rustc_resolve/src/late/diagnostics.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2065,7 +2065,11 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
20652065
path: &[Segment],
20662066
) -> Option<(Span, &'static str, String, Applicability)> {
20672067
let (ident, span) = match path {
2068-
[segment] if !segment.has_generic_args && segment.ident.name != kw::SelfUpper => {
2068+
[segment]
2069+
if !segment.has_generic_args
2070+
&& segment.ident.name != kw::SelfUpper
2071+
&& segment.ident.name != kw::Dyn =>
2072+
{
20692073
(segment.ident.to_string(), segment.ident.span)
20702074
}
20712075
_ => return None,

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -2252,8 +2252,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
22522252
Ok(None) => {
22532253
let ambiguities =
22542254
ambiguity::recompute_applicable_impls(self.infcx, &obligation);
2255-
let has_non_region_infer =
2256-
trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_infer());
2255+
let has_non_region_infer = trait_ref
2256+
.skip_binder()
2257+
.substs
2258+
.types()
2259+
.any(|t| !t.is_ty_or_numeric_infer());
22572260
// It doesn't make sense to talk about applicable impls if there are more
22582261
// than a handful of them.
22592262
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {

src/tools/clippy/tests/ui/crashes/ice-6252.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ error[E0412]: cannot find type `VAL` in this scope
1717
--> $DIR/ice-6252.rs:10:63
1818
|
1919
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
20-
| - ^^^ not found in this scope
21-
| |
22-
| help: you might be missing a type parameter: `, VAL`
20+
| ^^^ not found in this scope
21+
|
22+
help: you might be missing a type parameter
23+
|
24+
LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
25+
| +++++
2326

2427
error[E0046]: not all trait items implemented, missing: `VAL`
2528
--> $DIR/ice-6252.rs:10:1

tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `T` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-double-superkind.rs:6:24
2+
--> $DIR/builtin-superkinds-double-superkind.rs:6:32
33
|
44
LL | impl <T: Sync+'static> Foo for (T,) { }
5-
| ^^^ `T` cannot be sent between threads safely
5+
| ^^^^ `T` cannot be sent between threads safely
66
|
77
= note: required because it appears within the type `(T,)`
88
note: required by a bound in `Foo`
@@ -16,10 +16,10 @@ LL | impl <T: Sync+'static + std::marker::Send> Foo for (T,) { }
1616
| +++++++++++++++++++
1717

1818
error[E0277]: `T` cannot be shared between threads safely
19-
--> $DIR/builtin-superkinds-double-superkind.rs:9:16
19+
--> $DIR/builtin-superkinds-double-superkind.rs:9:24
2020
|
2121
LL | impl <T: Send> Foo for (T,T) { }
22-
| ^^^ `T` cannot be shared between threads safely
22+
| ^^^^^ `T` cannot be shared between threads safely
2323
|
2424
= note: required because it appears within the type `(T, T)`
2525
note: required by a bound in `Foo`

tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `T` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-in-metadata.rs:13:23
2+
--> $DIR/builtin-superkinds-in-metadata.rs:13:56
33
|
44
LL | impl <T:Sync+'static> RequiresRequiresShareAndSend for X<T> { }
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
5+
| ^^^^ `T` cannot be sent between threads safely
66
|
77
note: required because it appears within the type `X<T>`
88
--> $DIR/builtin-superkinds-in-metadata.rs:9:8

tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `Rc<i8>` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-simple.rs:6:6
2+
--> $DIR/builtin-superkinds-simple.rs:6:14
33
|
44
LL | impl Foo for std::rc::Rc<i8> { }
5-
| ^^^ `Rc<i8>` cannot be sent between threads safely
5+
| ^^^^^^^^^^^^^^^ `Rc<i8>` cannot be sent between threads safely
66
|
77
= help: the trait `Send` is not implemented for `Rc<i8>`
88
note: required by a bound in `Foo`

tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `T` cannot be sent between threads safely
2-
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:24
2+
--> $DIR/builtin-superkinds-typaram-not-send.rs:5:32
33
|
44
LL | impl <T: Sync+'static> Foo for T { }
5-
| ^^^ `T` cannot be sent between threads safely
5+
| ^ `T` cannot be sent between threads safely
66
|
77
note: required by a bound in `Foo`
88
--> $DIR/builtin-superkinds-typaram-not-send.rs:3:13

tests/ui/chalkify/impl_wf.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `str` cannot be known at compilation time
2-
--> $DIR/impl_wf.rs:11:6
2+
--> $DIR/impl_wf.rs:11:14
33
|
44
LL | impl Foo for str { }
5-
| ^^^ doesn't have a size known at compile-time
5+
| ^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `str`
88
note: required by a bound in `Foo`
@@ -12,10 +12,10 @@ LL | trait Foo: Sized { }
1212
| ^^^^^ required by this bound in `Foo`
1313

1414
error[E0277]: the trait bound `f32: Foo` is not satisfied
15-
--> $DIR/impl_wf.rs:22:6
15+
--> $DIR/impl_wf.rs:22:19
1616
|
1717
LL | impl Baz<f32> for f32 { }
18-
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
18+
| ^^^ the trait `Foo` is not implemented for `f32`
1919
|
2020
= help: the trait `Foo` is implemented for `i32`
2121
note: required by a bound in `Baz`

tests/ui/coherence/coherence-overlap-trait-alias.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0283]: type annotations needed: cannot satisfy `u32: C`
2-
--> $DIR/coherence-overlap-trait-alias.rs:15:6
2+
--> $DIR/coherence-overlap-trait-alias.rs:15:12
33
|
44
LL | impl C for u32 {}
5-
| ^
5+
| ^^^
66
|
77
note: multiple `impl`s satisfying `u32: C` found
88
--> $DIR/coherence-overlap-trait-alias.rs:14:1

0 commit comments

Comments
 (0)