Skip to content

Commit 9c2797d

Browse files
committed
Auto merge of #103151 - matthiaskrgr:rollup-t3mmnsg, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #102454 (Suggest parentheses for possible range method calling) - #102466 (only allow `ConstEquate` with `feature(gce)`) - #102945 (Do not register placeholder `RegionOutlives` obligations when `considering_regions` is false) - #103091 (rustdoc: remove unused HTML class `sidebar-title`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents a9d1caf + e1d72a4 commit 9c2797d

File tree

20 files changed

+496
-66
lines changed

20 files changed

+496
-66
lines changed

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

+4
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,7 @@ hir_analysis_extern_crate_not_idiomatic =
133133
.suggestion = convert it to a `{$msg_code}`
134134
135135
hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
136+
137+
hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
138+
139+
hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function

compiler/rustc_hir_analysis/src/check/method/suggest.rs

+87-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//! found or is otherwise invalid.
33
44
use crate::check::FnCtxt;
5+
use crate::errors;
56
use rustc_ast::ast::Mutability;
67
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
78
use rustc_errors::{
@@ -271,7 +272,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
271272
}
272273
};
273274

274-
if self.suggest_constraining_numerical_ty(
275+
if self.suggest_wrapping_range_with_parens(
276+
tcx, actual, source, span, item_name, &ty_str,
277+
) || self.suggest_constraining_numerical_ty(
275278
tcx, actual, source, span, item_kind, item_name, &ty_str,
276279
) {
277280
return None;
@@ -1202,6 +1205,89 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12021205
false
12031206
}
12041207

1208+
/// Suggest possible range with adding parentheses, for example:
1209+
/// when encountering `0..1.map(|i| i + 1)` suggest `(0..1).map(|i| i + 1)`.
1210+
fn suggest_wrapping_range_with_parens(
1211+
&self,
1212+
tcx: TyCtxt<'tcx>,
1213+
actual: Ty<'tcx>,
1214+
source: SelfSource<'tcx>,
1215+
span: Span,
1216+
item_name: Ident,
1217+
ty_str: &str,
1218+
) -> bool {
1219+
if let SelfSource::MethodCall(expr) = source {
1220+
for (_, parent) in tcx.hir().parent_iter(expr.hir_id).take(5) {
1221+
if let Node::Expr(parent_expr) = parent {
1222+
let lang_item = match parent_expr.kind {
1223+
ExprKind::Struct(ref qpath, _, _) => match **qpath {
1224+
QPath::LangItem(LangItem::Range, ..) => Some(LangItem::Range),
1225+
QPath::LangItem(LangItem::RangeTo, ..) => Some(LangItem::RangeTo),
1226+
QPath::LangItem(LangItem::RangeToInclusive, ..) => {
1227+
Some(LangItem::RangeToInclusive)
1228+
}
1229+
_ => None,
1230+
},
1231+
ExprKind::Call(ref func, _) => match func.kind {
1232+
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1233+
ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)) => {
1234+
Some(LangItem::RangeInclusiveStruct)
1235+
}
1236+
_ => None,
1237+
},
1238+
_ => None,
1239+
};
1240+
1241+
if lang_item.is_none() {
1242+
continue;
1243+
}
1244+
1245+
let span_included = match parent_expr.kind {
1246+
hir::ExprKind::Struct(_, eps, _) => {
1247+
eps.len() > 0 && eps.last().map_or(false, |ep| ep.span.contains(span))
1248+
}
1249+
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
1250+
hir::ExprKind::Call(ref func, ..) => func.span.contains(span),
1251+
_ => false,
1252+
};
1253+
1254+
if !span_included {
1255+
continue;
1256+
}
1257+
1258+
let range_def_id = self.tcx.require_lang_item(lang_item.unwrap(), None);
1259+
let range_ty =
1260+
self.tcx.bound_type_of(range_def_id).subst(self.tcx, &[actual.into()]);
1261+
1262+
let pick = self.probe_for_name(
1263+
span,
1264+
Mode::MethodCall,
1265+
item_name,
1266+
IsSuggestion(true),
1267+
range_ty,
1268+
expr.hir_id,
1269+
ProbeScope::AllTraits,
1270+
);
1271+
if pick.is_ok() {
1272+
let range_span = parent_expr.span.with_hi(expr.span.hi());
1273+
tcx.sess.emit_err(errors::MissingParentheseInRange {
1274+
span,
1275+
ty_str: ty_str.to_string(),
1276+
method_name: item_name.as_str().to_string(),
1277+
add_missing_parentheses: Some(errors::AddMissingParenthesesInRange {
1278+
func_name: item_name.name.as_str().to_string(),
1279+
left: range_span.shrink_to_lo(),
1280+
right: range_span.shrink_to_hi(),
1281+
}),
1282+
});
1283+
return true;
1284+
}
1285+
}
1286+
}
1287+
}
1288+
false
1289+
}
1290+
12051291
fn suggest_constraining_numerical_ty(
12061292
&self,
12071293
tcx: TyCtxt<'tcx>,
@@ -1264,7 +1350,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12641350
// If this is a floating point literal that ends with '.',
12651351
// get rid of it to stop this from becoming a member access.
12661352
let snippet = snippet.strip_suffix('.').unwrap_or(&snippet);
1267-
12681353
err.span_suggestion(
12691354
lit.span,
12701355
&format!(

compiler/rustc_hir_analysis/src/errors.rs

+26
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,29 @@ pub struct ExpectedUsedSymbol {
346346
#[primary_span]
347347
pub span: Span,
348348
}
349+
350+
#[derive(Diagnostic)]
351+
#[diag(hir_analysis::missing_parentheses_in_range, code = "E0689")]
352+
pub struct MissingParentheseInRange {
353+
#[primary_span]
354+
#[label(hir_analysis::missing_parentheses_in_range)]
355+
pub span: Span,
356+
pub ty_str: String,
357+
pub method_name: String,
358+
359+
#[subdiagnostic]
360+
pub add_missing_parentheses: Option<AddMissingParenthesesInRange>,
361+
}
362+
363+
#[derive(Subdiagnostic)]
364+
#[multipart_suggestion_verbose(
365+
hir_analysis::add_missing_parentheses_in_range,
366+
applicability = "maybe-incorrect"
367+
)]
368+
pub struct AddMissingParenthesesInRange {
369+
pub func_name: String,
370+
#[suggestion_part(code = "(")]
371+
pub left: Span,
372+
#[suggestion_part(code = ")")]
373+
pub right: Span,
374+
}

compiler/rustc_trait_selection/src/traits/fulfill.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
355355
}
356356

357357
ty::PredicateKind::RegionOutlives(data) => {
358-
if infcx.considering_regions || data.has_placeholders() {
358+
if infcx.considering_regions {
359359
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
360360
}
361361

@@ -492,19 +492,20 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
492492
}
493493

494494
ty::PredicateKind::ConstEquate(c1, c2) => {
495+
assert!(
496+
self.selcx.tcx().features().generic_const_exprs,
497+
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
498+
);
495499
debug!(?c1, ?c2, "equating consts");
496-
let tcx = self.selcx.tcx();
497-
if tcx.features().generic_const_exprs {
498-
// FIXME: we probably should only try to unify abstract constants
499-
// if the constants depend on generic parameters.
500-
//
501-
// Let's just see where this breaks :shrug:
502-
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
503-
(c1.kind(), c2.kind())
504-
{
505-
if infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
506-
return ProcessResult::Changed(vec![]);
507-
}
500+
// FIXME: we probably should only try to unify abstract constants
501+
// if the constants depend on generic parameters.
502+
//
503+
// Let's just see where this breaks :shrug:
504+
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
505+
(c1.kind(), c2.kind())
506+
{
507+
if infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
508+
return ProcessResult::Changed(vec![]);
508509
}
509510
}
510511

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

+13-11
Original file line numberDiff line numberDiff line change
@@ -676,19 +676,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
676676
}
677677

678678
ty::PredicateKind::ConstEquate(c1, c2) => {
679+
assert!(
680+
self.tcx().features().generic_const_exprs,
681+
"`ConstEquate` without a feature gate: {c1:?} {c2:?}",
682+
);
679683
debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts");
680684

681-
if self.tcx().features().generic_const_exprs {
682-
// FIXME: we probably should only try to unify abstract constants
683-
// if the constants depend on generic parameters.
684-
//
685-
// Let's just see where this breaks :shrug:
686-
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
687-
(c1.kind(), c2.kind())
688-
{
689-
if self.infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
690-
return Ok(EvaluatedToOk);
691-
}
685+
// FIXME: we probably should only try to unify abstract constants
686+
// if the constants depend on generic parameters.
687+
//
688+
// Let's just see where this breaks :shrug:
689+
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
690+
(c1.kind(), c2.kind())
691+
{
692+
if self.infcx.try_unify_abstract_consts(a, b, obligation.param_env) {
693+
return Ok(EvaluatedToOk);
692694
}
693695
}
694696

src/librustdoc/html/render/mod.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -2259,13 +2259,7 @@ fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String
22592259
}
22602260

22612261
fn print_sidebar_title(buf: &mut Buffer, id: &str, title: &str) {
2262-
write!(
2263-
buf,
2264-
"<h3 class=\"sidebar-title\">\
2265-
<a href=\"#{}\">{}</a>\
2266-
</h3>",
2267-
id, title
2268-
);
2262+
write!(buf, "<h3><a href=\"#{}\">{}</a></h3>", id, title);
22692263
}
22702264

22712265
fn print_sidebar_block(

src/test/rustdoc-gui/sidebar-mobile.goml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ click: ".sidebar-menu-toggle"
1313
assert-css: (".sidebar", {"display": "block", "left": "-1000px"})
1414
// Force the sidebar open by focusing a link inside it.
1515
// This makes it easier for keyboard users to get to it.
16-
focus: ".sidebar-title a"
16+
focus: ".sidebar-elems h3 a"
1717
assert-css: (".sidebar", {"display": "block", "left": "0px"})
1818
// When we tab out of the sidebar, close it.
1919
focus: ".search-input"

src/test/rustdoc/associated-consts.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub trait Trait {
99
pub struct Bar;
1010

1111
// @has 'foo/struct.Bar.html'
12-
// @!has - '//h3[@class="sidebar-title"]' 'Associated Constants'
12+
// @!has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
1313
// @!has - '//div[@class="sidebar-elems"]//a' 'FOO'
1414
impl Trait for Bar {
1515
const FOO: u32 = 1;
@@ -22,7 +22,7 @@ pub enum Foo {
2222
}
2323

2424
// @has 'foo/enum.Foo.html'
25-
// @!has - '//h3[@class="sidebar-title"]' 'Associated Constants'
25+
// @!has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
2626
// @!has - '//div[@class="sidebar-elems"]//a' 'FOO'
2727
impl Trait for Foo {
2828
const FOO: u32 = 1;
@@ -33,7 +33,7 @@ impl Trait for Foo {
3333
pub struct Baz;
3434

3535
// @has 'foo/struct.Baz.html'
36-
// @has - '//h3[@class="sidebar-title"]' 'Associated Constants'
36+
// @has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
3737
// @has - '//div[@class="sidebar-elems"]//a' 'FOO'
3838
impl Baz {
3939
pub const FOO: u32 = 42;
@@ -44,7 +44,7 @@ pub enum Quux {
4444
}
4545

4646
// @has 'foo/enum.Quux.html'
47-
// @has - '//h3[@class="sidebar-title"]' 'Associated Constants'
47+
// @has - '//div[@class="sidebar-elems"]//h3' 'Associated Constants'
4848
// @has - '//div[@class="sidebar-elems"]//a' 'FOO'
4949
impl Quux {
5050
pub const FOO: u32 = 42;

src/test/rustdoc/deref-recursive-pathbuf.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
// @has '-' '//*[@class="impl-items"]//*[@id="method.as_path"]' 'pub fn as_path(&self)'
88
// @has '-' '//*[@id="deref-methods-Path"]' 'Methods from Deref<Target = Path>'
99
// @has '-' '//*[@class="impl-items"]//*[@id="method.exists"]' 'pub fn exists(&self)'
10-
// @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-PathBuf"]' 'Methods from Deref<Target=PathBuf>'
10+
// @has '-' '//div[@class="sidebar-elems"]//h3/a[@href="#deref-methods-PathBuf"]' 'Methods from Deref<Target=PathBuf>'
1111
// @has '-' '//*[@class="sidebar-elems"]//*[@class="block"]//a[@href="#method.as_path"]' 'as_path'
12-
// @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-Path"]' 'Methods from Deref<Target=Path>'
12+
// @has '-' '//div[@class="sidebar-elems"]//h3/a[@href="#deref-methods-Path"]' 'Methods from Deref<Target=Path>'
1313
// @has '-' '//*[@class="sidebar-elems"]//*[@class="block"]//a[@href="#method.exists"]' 'exists'
1414

1515
#![crate_name = "foo"]

src/test/rustdoc/deref-recursive.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
// @has '-' '//*[@class="impl-items"]//*[@id="method.bar"]' 'pub fn bar(&self)'
88
// @has '-' '//*[@id="deref-methods-Baz"]' 'Methods from Deref<Target = Baz>'
99
// @has '-' '//*[@class="impl-items"]//*[@id="method.baz"]' 'pub fn baz(&self)'
10-
// @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-Bar"]' 'Methods from Deref<Target=Bar>'
10+
// @has '-' '//div[@class="sidebar-elems"]//h3/a[@href="#deref-methods-Bar"]' 'Methods from Deref<Target=Bar>'
1111
// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.bar"]' 'bar'
12-
// @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-Baz"]' 'Methods from Deref<Target=Baz>'
12+
// @has '-' '//div[@class="sidebar-elems"]//h3/a[@href="#deref-methods-Baz"]' 'Methods from Deref<Target=Baz>'
1313
// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.baz"]' 'baz'
1414

1515
#![crate_name = "foo"]

src/test/rustdoc/deref-typedef.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)'
77
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)'
88
// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_j"]' 'pub fn foo_j(&self)'
9-
// @has '-' '//*[@class="sidebar-title"]/a[@href="#deref-methods-FooJ"]' 'Methods from Deref<Target=FooJ>'
9+
// @has '-' '//div[@class="sidebar-elems"]//h3/a[@href="#deref-methods-FooJ"]' 'Methods from Deref<Target=FooJ>'
1010
// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_a"]' 'foo_a'
1111
// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_b"]' 'foo_b'
1212
// @has '-' '//*[@class="sidebar-elems"]//section//a[@href="#method.foo_c"]' 'foo_c'

src/test/rustdoc/escape-deref-methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl Deref for TitleList {
2727
}
2828

2929
// @has foo/struct.TitleList.html
30-
// @has - '//*[@class="sidebar-title"]' 'Methods from Deref<Target=Vec<Title>>'
30+
// @has - '//div[@class="sidebar-elems"]//h3' 'Methods from Deref<Target=Vec<Title>>'
3131
impl DerefMut for TitleList {
3232
fn deref_mut(&mut self) -> &mut Self::Target {
3333
&mut self.members

src/test/rustdoc/negative-impl-sidebar.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
pub struct Foo;
55

66
// @has foo/struct.Foo.html
7-
// @has - '//*[@class="sidebar-title"]/a[@href="#trait-implementations"]' 'Trait Implementations'
7+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#trait-implementations"]' 'Trait Implementations'
88
// @has - '//*[@class="sidebar-elems"]//section//a' '!Sync'
99
impl !Sync for Foo {}

src/test/rustdoc/sidebar-items.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
#![crate_name = "foo"]
33

44
// @has foo/trait.Foo.html
5-
// @has - '//*[@class="sidebar-title"]/a[@href="#required-methods"]' 'Required Methods'
5+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-methods"]' 'Required Methods'
66
// @has - '//*[@class="sidebar-elems"]//section//a' 'bar'
7-
// @has - '//*[@class="sidebar-title"]/a[@href="#provided-methods"]' 'Provided Methods'
7+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-methods"]' 'Provided Methods'
88
// @has - '//*[@class="sidebar-elems"]//section//a' 'foo'
9-
// @has - '//*[@class="sidebar-title"]/a[@href="#required-associated-consts"]' 'Required Associated Constants'
9+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-associated-consts"]' 'Required Associated Constants'
1010
// @has - '//*[@class="sidebar-elems"]//section//a' 'FOO'
11-
// @has - '//*[@class="sidebar-title"]/a[@href="#provided-associated-consts"]' 'Provided Associated Constants'
11+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-consts"]' 'Provided Associated Constants'
1212
// @has - '//*[@class="sidebar-elems"]//section//a' 'BAR'
13-
// @has - '//*[@class="sidebar-title"]/a[@href="#required-associated-types"]' 'Required Associated Types'
13+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#required-associated-types"]' 'Required Associated Types'
1414
// @has - '//*[@class="sidebar-elems"]//section//a' 'Output'
15-
// @has - '//*[@class="sidebar-title"]/a[@href="#provided-associated-types"]' 'Provided Associated Types'
15+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
1616
// @has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
1717
pub trait Foo {
1818
const FOO: usize;
@@ -25,7 +25,7 @@ pub trait Foo {
2525
}
2626

2727
// @has foo/struct.Bar.html
28-
// @has - '//*[@class="sidebar-title"]/a[@href="#fields"]' 'Fields'
28+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
2929
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f"]' 'f'
3030
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.u"]' 'u'
3131
// @!has - '//*[@class="sidebar-elems"]//section//a' 'waza'
@@ -36,7 +36,7 @@ pub struct Bar {
3636
}
3737

3838
// @has foo/enum.En.html
39-
// @has - '//*[@class="sidebar-title"]/a[@href="#variants"]' 'Variants'
39+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#variants"]' 'Variants'
4040
// @has - '//*[@class="sidebar-elems"]//section//a' 'Foo'
4141
// @has - '//*[@class="sidebar-elems"]//section//a' 'Bar'
4242
pub enum En {
@@ -45,7 +45,7 @@ pub enum En {
4545
}
4646

4747
// @has foo/union.MyUnion.html
48-
// @has - '//*[@class="sidebar-title"]/a[@href="#fields"]' 'Fields'
48+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
4949
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f1"]' 'f1'
5050
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f2"]' 'f2'
5151
// @!has - '//*[@class="sidebar-elems"]//section//a' 'waza'

src/test/rustdoc/sidebar-links-to-foreign-impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![crate_name = "foo"]
44

55
// @has foo/trait.Foo.html
6-
// @has - '//*[@class="sidebar-title"]/a[@href="#foreign-impls"]' 'Implementations on Foreign Types'
6+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#foreign-impls"]' 'Implementations on Foreign Types'
77
// @has - '//h2[@id="foreign-impls"]' 'Implementations on Foreign Types'
88
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#impl-Foo-for-u32"]' 'u32'
99
// @has - '//*[@id="impl-Foo-for-u32"]//h3[@class="code-header"]' 'impl Foo for u32'

0 commit comments

Comments
 (0)