Skip to content

Commit 7606c13

Browse files
committed
Auto merge of #121964 - matthiaskrgr:rollup-rtcju5m, r=matthiaskrgr
Rollup of 3 pull requests Successful merges: - #121130 (Suggest moving definition if non-found macro_rules! is defined later) - #121912 (Properly deal with GATs when looking for method chains to point at) - #121927 (Add a proper `with_no_queries` to printing) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f7cb53e + de95c39 commit 7606c13

File tree

14 files changed

+180
-37
lines changed

14 files changed

+180
-37
lines changed

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn opaque_type_bounds<'tcx>(
6464
item_ty: Ty<'tcx>,
6565
span: Span,
6666
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
67-
ty::print::with_no_queries!({
67+
ty::print::with_reduced_queries!({
6868
let icx = ItemCtxt::new(tcx, opaque_def_id);
6969
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
7070
// Opaque types are implicitly sized unless a `?Sized` bound is found

compiler/rustc_middle/src/ty/print/pretty.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ thread_local! {
6464
static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = const { Cell::new(false) };
6565
static NO_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
6666
static FORCE_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
67-
static NO_QUERIES: Cell<bool> = const { Cell::new(false) };
67+
static REDUCED_QUERIES: Cell<bool> = const { Cell::new(false) };
6868
static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
6969
}
7070

@@ -102,14 +102,14 @@ macro_rules! define_helper {
102102
}
103103

104104
define_helper!(
105-
/// Avoids running any queries during any prints that occur
105+
/// Avoids running select queries during any prints that occur
106106
/// during the closure. This may alter the appearance of some
107107
/// types (e.g. forcing verbose printing for opaque types).
108108
/// This method is used during some queries (e.g. `explicit_item_bounds`
109109
/// for opaque types), to ensure that any debug printing that
110110
/// occurs during the query computation does not end up recursively
111111
/// calling the same query.
112-
fn with_no_queries(NoQueriesGuard, NO_QUERIES);
112+
fn with_reduced_queries(ReducedQueriesGuard, REDUCED_QUERIES);
113113
/// Force us to name impls with just the filename/line number. We
114114
/// normally try to use types. But at some points, notably while printing
115115
/// cycle errors, this can result in extra or suboptimal error output,
@@ -127,6 +127,15 @@ define_helper!(
127127
fn with_no_visible_paths(NoVisibleGuard, NO_VISIBLE_PATH);
128128
);
129129

130+
/// Avoids running any queries during prints.
131+
pub macro with_no_queries($e:expr) {{
132+
$crate::ty::print::with_reduced_queries!($crate::ty::print::with_forced_impl_filename_line!(
133+
$crate::ty::print::with_no_trimmed_paths!($crate::ty::print::with_no_visible_paths!(
134+
$crate::ty::print::with_forced_impl_filename_line!($e)
135+
))
136+
))
137+
}}
138+
130139
/// The "region highlights" are used to control region printing during
131140
/// specific error messages. When a "region highlight" is enabled, it
132141
/// gives an alternate way to print specific regions. For now, we
@@ -659,7 +668,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
659668
p!(")")
660669
}
661670
ty::FnDef(def_id, args) => {
662-
if with_no_queries() {
671+
if with_reduced_queries() {
663672
p!(print_def_path(def_id, args));
664673
} else {
665674
let sig = self.tcx().fn_sig(def_id).instantiate(self.tcx(), args);
@@ -759,7 +768,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
759768
return Ok(());
760769
}
761770
_ => {
762-
if with_no_queries() {
771+
if with_reduced_queries() {
763772
p!(print_def_path(def_id, &[]));
764773
return Ok(());
765774
} else {
@@ -1876,7 +1885,8 @@ impl DerefMut for FmtPrinter<'_, '_> {
18761885

18771886
impl<'a, 'tcx> FmtPrinter<'a, 'tcx> {
18781887
pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self {
1879-
let limit = if with_no_queries() { Limit::new(1048576) } else { tcx.type_length_limit() };
1888+
let limit =
1889+
if with_reduced_queries() { Limit::new(1048576) } else { tcx.type_length_limit() };
18801890
Self::new_with_limit(tcx, ns, limit)
18811891
}
18821892

@@ -2962,7 +2972,7 @@ define_print_and_forward_display! {
29622972
}
29632973

29642974
TraitRefPrintSugared<'tcx> {
2965-
if !with_no_queries()
2975+
if !with_reduced_queries()
29662976
&& let Some(kind) = cx.tcx().fn_trait_kind_from_def_id(self.0.def_id)
29672977
&& let ty::Tuple(args) = self.0.args.type_at(1).kind()
29682978
{
@@ -3050,7 +3060,7 @@ define_print_and_forward_display! {
30503060
// If we're printing verbosely, or don't want to invoke queries
30513061
// (`is_impl_trait_in_trait`), then fall back to printing the def path.
30523062
// This is likely what you want if you're debugging the compiler anyways.
3053-
if !(cx.should_print_verbose() || with_no_queries())
3063+
if !(cx.should_print_verbose() || with_reduced_queries())
30543064
&& cx.tcx().is_impl_trait_in_trait(self.def_id)
30553065
{
30563066
return cx.pretty_print_opaque_impl_type(self.def_id, self.args);

compiler/rustc_query_impl/src/plumbing.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_middle::query::on_disk_cache::AbsoluteBytePos;
1818
use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex};
1919
use rustc_middle::query::Key;
2020
use rustc_middle::ty::tls::{self, ImplicitCtxt};
21-
use rustc_middle::ty::{self, print::with_no_queries, TyCtxt};
21+
use rustc_middle::ty::{self, TyCtxt};
2222
use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
2323
use rustc_query_system::ich::StableHashingContext;
2424
use rustc_query_system::query::{
@@ -305,28 +305,21 @@ pub(crate) fn create_query_frame<
305305
name: &'static str,
306306
) -> QueryStackFrame {
307307
// Avoid calling queries while formatting the description
308-
let description = ty::print::with_no_queries!(
309-
// Disable visible paths printing for performance reasons.
310-
// Showing visible path instead of any path is not that important in production.
311-
ty::print::with_no_visible_paths!(
312-
// Force filename-line mode to avoid invoking `type_of` query.
313-
ty::print::with_forced_impl_filename_line!(do_describe(tcx, key))
314-
)
315-
);
308+
let description = ty::print::with_no_queries!(do_describe(tcx, key));
316309
let description = if tcx.sess.verbose_internals() {
317310
format!("{description} [{name:?}]")
318311
} else {
319312
description
320313
};
321-
let span = if kind == dep_graph::dep_kinds::def_span || with_no_queries() {
314+
let span = if kind == dep_graph::dep_kinds::def_span {
322315
// The `def_span` query is used to calculate `default_span`,
323316
// so exit to avoid infinite recursion.
324317
None
325318
} else {
326319
Some(key.default_span(tcx))
327320
};
328321
let def_id = key.key_as_def_id();
329-
let def_kind = if kind == dep_graph::dep_kinds::def_kind || with_no_queries() {
322+
let def_kind = if kind == dep_graph::dep_kinds::def_kind {
330323
// Try to avoid infinite recursion.
331324
None
332325
} else {

compiler/rustc_resolve/messages.ftl

+7
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ resolve_consider_declaring_with_pub =
8383
resolve_consider_marking_as_pub =
8484
consider marking `{$ident}` as `pub` in the imported module
8585
86+
resolve_consider_move_macro_position =
87+
consider moving the definition of `{$ident}` before this call
88+
89+
8690
resolve_const_not_member_of_trait =
8791
const `{$const_}` is not a member of trait `{$trait_}`
8892
.label = not a member of trait `{$trait_}`
@@ -176,6 +180,9 @@ resolve_lowercase_self =
176180
attempt to use a non-constant value in a constant
177181
.suggestion = try using `Self`
178182
183+
resolve_macro_defined_later =
184+
a macro with the same name exists, but it appears later at here
185+
179186
resolve_macro_expected_found =
180187
expected {$expected}, found {$found} `{$macro_path}`
181188

compiler/rustc_resolve/src/diagnostics.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ use rustc_span::{BytePos, Span, SyntaxContext};
3030
use thin_vec::{thin_vec, ThinVec};
3131

3232
use crate::errors::{AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion};
33-
use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits, MaybeMissingMacroRulesName};
33+
use crate::errors::{
34+
ConsiderAddingADerive, ExplicitUnsafeTraits, MacroDefinedLater, MacroSuggMovePosition,
35+
MaybeMissingMacroRulesName,
36+
};
3437
use crate::imports::{Import, ImportKind};
3538
use crate::late::{PatternSource, Rib};
3639
use crate::{errors as errs, BindingKey};
@@ -1456,6 +1459,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14561459
return;
14571460
}
14581461

1462+
let unused_macro = self.unused_macros.iter().find_map(|(def_id, (_, unused_ident))| {
1463+
if unused_ident.name == ident.name {
1464+
Some((def_id.clone(), unused_ident.clone()))
1465+
} else {
1466+
None
1467+
}
1468+
});
1469+
1470+
if let Some((def_id, unused_ident)) = unused_macro {
1471+
let scope = self.local_macro_def_scopes[&def_id];
1472+
let parent_nearest = parent_scope.module.nearest_parent_mod();
1473+
if Some(parent_nearest) == scope.opt_def_id() {
1474+
err.subdiagnostic(self.dcx(), MacroDefinedLater { span: unused_ident.span });
1475+
err.subdiagnostic(self.dcx(), MacroSuggMovePosition { span: ident.span, ident });
1476+
return;
1477+
}
1478+
}
1479+
14591480
if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
14601481
err.subdiagnostic(self.dcx(), AddedMacroUse);
14611482
return;

compiler/rustc_resolve/src/errors.rs

+15
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,21 @@ pub(crate) struct ExplicitUnsafeTraits {
646646
pub(crate) ident: Ident,
647647
}
648648

649+
#[derive(Subdiagnostic)]
650+
#[note(resolve_macro_defined_later)]
651+
pub(crate) struct MacroDefinedLater {
652+
#[primary_span]
653+
pub(crate) span: Span,
654+
}
655+
656+
#[derive(Subdiagnostic)]
657+
#[label(resolve_consider_move_macro_position)]
658+
pub(crate) struct MacroSuggMovePosition {
659+
#[primary_span]
660+
pub(crate) span: Span,
661+
pub(crate) ident: Ident,
662+
}
663+
649664
#[derive(Subdiagnostic)]
650665
#[note(resolve_missing_macro_rules_name)]
651666
pub(crate) struct MaybeMissingMacroRulesName {

compiler/rustc_trait_selection/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#![allow(internal_features)]
1717
#![allow(rustc::diagnostic_outside_of_impl)]
1818
#![allow(rustc::untranslatable_diagnostic)]
19+
#![feature(assert_matches)]
1920
#![feature(associated_type_bounds)]
2021
#![feature(box_patterns)]
2122
#![feature(control_flow_enum)]

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

+13-16
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_span::def_id::LocalDefId;
3838
use rustc_span::symbol::{kw, sym, Ident, Symbol};
3939
use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
4040
use rustc_target::spec::abi;
41+
use std::assert_matches::debug_assert_matches;
4142
use std::borrow::Cow;
4243
use std::iter;
4344

@@ -4219,30 +4220,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
42194220
};
42204221

42214222
let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
4222-
let trait_def_id = proj.trait_def_id(self.tcx);
42234223
// Make `Self` be equivalent to the type of the call chain
42244224
// expression we're looking at now, so that we can tell what
42254225
// for example `Iterator::Item` is at this point in the chain.
4226-
let args = GenericArgs::for_item(self.tcx, trait_def_id, |param, _| {
4227-
match param.kind {
4228-
ty::GenericParamDefKind::Type { .. } => {
4229-
if param.index == 0 {
4230-
return prev_ty.into();
4231-
}
4232-
}
4233-
ty::GenericParamDefKind::Lifetime | ty::GenericParamDefKind::Const { .. } => {}
4226+
let args = GenericArgs::for_item(self.tcx, proj.def_id, |param, _| {
4227+
if param.index == 0 {
4228+
debug_assert_matches!(param.kind, ty::GenericParamDefKind::Type { .. });
4229+
return prev_ty.into();
42344230
}
42354231
self.var_for_def(span, param)
42364232
});
42374233
// This will hold the resolved type of the associated type, if the
42384234
// current expression implements the trait that associated type is
42394235
// in. For example, this would be what `Iterator::Item` is here.
4240-
let ty_var = self.infcx.next_ty_var(origin);
4236+
let ty = self.infcx.next_ty_var(origin);
42414237
// This corresponds to `<ExprTy as Iterator>::Item = _`.
42424238
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(
42434239
ty::ClauseKind::Projection(ty::ProjectionPredicate {
42444240
projection_ty: ty::AliasTy::new(self.tcx, proj.def_id, args),
4245-
term: ty_var.into(),
4241+
term: ty.into(),
42464242
}),
42474243
));
42484244
let body_def_id = self.tcx.hir().enclosing_body_owner(body_id);
@@ -4254,14 +4250,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
42544250
param_env,
42554251
projection,
42564252
));
4257-
if ocx.select_where_possible().is_empty() {
4258-
// `ty_var` now holds the type that `Item` is for `ExprTy`.
4259-
let ty_var = self.resolve_vars_if_possible(ty_var);
4260-
assocs_in_this_method.push(Some((span, (proj.def_id, ty_var))));
4253+
if ocx.select_where_possible().is_empty()
4254+
&& let ty = self.resolve_vars_if_possible(ty)
4255+
&& !ty.is_ty_var()
4256+
{
4257+
assocs_in_this_method.push(Some((span, (proj.def_id, ty))));
42614258
} else {
42624259
// `<ExprTy as Iterator>` didn't select, so likely we've
42634260
// reached the end of the iterator chain, like the originating
4264-
// `Vec<_>`.
4261+
// `Vec<_>` or the `ty` couldn't be determined.
42654262
// Keep the space consistent for later zipping.
42664263
assocs_in_this_method.push(None);
42674264
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
mod demo {
2+
fn hello() {
3+
something_later!(); //~ ERROR cannot find macro `something_later` in this scope
4+
}
5+
6+
macro_rules! something_later {
7+
() => {
8+
println!("successfully expanded!");
9+
};
10+
}
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: cannot find macro `something_later` in this scope
2+
--> $DIR/defined-later-issue-121061-2.rs:3:9
3+
|
4+
LL | something_later!();
5+
| ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call
6+
|
7+
note: a macro with the same name exists, but it appears later at here
8+
--> $DIR/defined-later-issue-121061-2.rs:6:18
9+
|
10+
LL | macro_rules! something_later {
11+
| ^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn main() {
2+
something_later!(); //~ ERROR cannot find macro `something_later` in this scope
3+
}
4+
5+
macro_rules! something_later {
6+
() => {
7+
println!("successfully expanded!");
8+
};
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: cannot find macro `something_later` in this scope
2+
--> $DIR/defined-later-issue-121061.rs:2:5
3+
|
4+
LL | something_later!();
5+
| ^^^^^^^^^^^^^^^ consider moving the definition of `something_later` before this call
6+
|
7+
note: a macro with the same name exists, but it appears later at here
8+
--> $DIR/defined-later-issue-121061.rs:5:14
9+
|
10+
LL | macro_rules! something_later {
11+
| ^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

tests/ui/typeck/method-chain-gats.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Regression test for issue #121898.
2+
3+
trait Base {
4+
type Base<B>;
5+
}
6+
7+
trait Functor<A>: Base {
8+
fn fmap<B>(self, f: impl Fn(A) -> B) -> Self::Base<B>
9+
where
10+
Self::Base<B>: Functor<B>;
11+
}
12+
13+
fn fmap2<T, A, B, C>(input: T, f1: impl Fn(A) -> B, f2: impl Fn(B) -> C) -> T::Base<C>
14+
where
15+
T: Functor<A>,
16+
T::Base<B>: Functor<B, Base<C> = T::Base<C>>,
17+
{
18+
input.fmap(f1).fmap(f2)
19+
//~^ ERROR the trait bound `<T as Base>::Base<C>: Functor<C>` is not satisfied
20+
}
21+
22+
fn main() {}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0277]: the trait bound `<T as Base>::Base<C>: Functor<C>` is not satisfied
2+
--> $DIR/method-chain-gats.rs:18:20
3+
|
4+
LL | input.fmap(f1).fmap(f2)
5+
| ^^^^ the trait `Functor<C>` is not implemented for `<T as Base>::Base<C>`
6+
|
7+
note: the method call chain might not have had the expected associated types
8+
--> $DIR/method-chain-gats.rs:13:29
9+
|
10+
LL | fn fmap2<T, A, B, C>(input: T, f1: impl Fn(A) -> B, f2: impl Fn(B) -> C) -> T::Base<C>
11+
| ^ `Base::Base` is `<T as Base>::Base<_>` here
12+
note: required by a bound in `Functor::fmap`
13+
--> $DIR/method-chain-gats.rs:10:24
14+
|
15+
LL | fn fmap<B>(self, f: impl Fn(A) -> B) -> Self::Base<B>
16+
| ---- required by a bound in this associated function
17+
LL | where
18+
LL | Self::Base<B>: Functor<B>;
19+
| ^^^^^^^^^^ required by this bound in `Functor::fmap`
20+
help: consider further restricting the associated type
21+
|
22+
LL | T::Base<B>: Functor<B, Base<C> = T::Base<C>>, <T as Base>::Base<C>: Functor<C>
23+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24+
25+
error: aborting due to 1 previous error
26+
27+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)