Skip to content

Commit 63b5065

Browse files
authored
Rollup merge of rust-lang#119813 - oli-obk:even_more_follow_up_errors2, r=estebank
Silence some follow-up errors [2/x] this is one piece of the requested cleanups from rust-lang#117449 the `type_of` query frequently uses astconv to convert a `hir::Ty` to a `ty::Ty`. This process is infallible, but may produce errors as it goes. All the error reporting sites that had access to the `ItemCtxt` are now tainting it, causing `type_of` to return a `ty::Error` instead of anything else.
2 parents 762f101 + 55cab53 commit 63b5065

35 files changed

+100
-266
lines changed

compiler/rustc_hir_analysis/src/astconv/bounds.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
300300
.expect("missing associated item");
301301

302302
if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
303-
tcx.dcx()
303+
let reported = tcx
304+
.dcx()
304305
.struct_span_err(
305306
binding.span,
306307
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
307308
)
308309
.with_span_label(binding.span, format!("private {}", assoc_item.kind))
309310
.emit();
311+
self.set_tainted_by_errors(reported);
310312
}
311313
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
312314

compiler/rustc_hir_analysis/src/astconv/errors.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
354354
);
355355
err.span_label(name.span, format!("multiple `{name}` found"));
356356
self.note_ambiguous_inherent_assoc_type(&mut err, candidates, span);
357-
err.emit()
357+
let reported = err.emit();
358+
self.set_tainted_by_errors(reported);
359+
reported
358360
}
359361

360362
// FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
@@ -843,7 +845,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
843845
}
844846
}
845847

846-
err.emit();
848+
self.set_tainted_by_errors(err.emit());
847849
}
848850
}
849851

compiler/rustc_hir_analysis/src/astconv/mod.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
389389
infer_args,
390390
);
391391

392+
if let Err(err) = &arg_count.correct
393+
&& let Some(reported) = err.reported
394+
{
395+
self.set_tainted_by_errors(reported);
396+
}
397+
392398
// Skip processing if type has no generic parameters.
393399
// Traits always have `Self` as a generic parameter, which means they will not return early
394400
// here and so associated type bindings will be handled regardless of whether there are any
@@ -567,6 +573,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
567573
span,
568574
modifier: constness.as_str(),
569575
});
576+
self.set_tainted_by_errors(e);
570577
arg_count.correct =
571578
Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] });
572579
}
@@ -965,7 +972,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
965972
}
966973
}
967974
}
968-
err.emit()
975+
let reported = err.emit();
976+
self.set_tainted_by_errors(reported);
977+
reported
969978
}
970979

971980
// Search for a bound on a type parameter which includes the associated item
@@ -1042,6 +1051,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10421051
span,
10431052
binding,
10441053
);
1054+
self.set_tainted_by_errors(reported);
10451055
return Err(reported);
10461056
};
10471057
debug!(?bound);
@@ -1119,6 +1129,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11191129
));
11201130
}
11211131
let reported = err.emit();
1132+
self.set_tainted_by_errors(reported);
11221133
if !where_bounds.is_empty() {
11231134
return Err(reported);
11241135
}
@@ -1373,6 +1384,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13731384
assoc_ident.name,
13741385
)
13751386
};
1387+
self.set_tainted_by_errors(reported);
13761388
return Err(reported);
13771389
}
13781390
};
@@ -1615,12 +1627,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16151627
let kind = tcx.def_kind_descr(kind, item);
16161628
let msg = format!("{kind} `{name}` is private");
16171629
let def_span = tcx.def_span(item);
1618-
tcx.dcx()
1630+
let reported = tcx
1631+
.dcx()
16191632
.struct_span_err(span, msg)
16201633
.with_code(rustc_errors::error_code!(E0624))
16211634
.with_span_label(span, format!("private {kind}"))
16221635
.with_span_label(def_span, format!("{kind} defined here"))
16231636
.emit();
1637+
self.set_tainted_by_errors(reported);
16241638
}
16251639
tcx.check_stability(item, Some(block), span, None);
16261640
}
@@ -1861,7 +1875,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18611875
err.span_label(span, format!("not allowed on {what}"));
18621876
}
18631877
extend(&mut err);
1864-
err.emit();
1878+
self.set_tainted_by_errors(err.emit());
18651879
emitted = true;
18661880
}
18671881

@@ -2183,7 +2197,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
21832197
{
21842198
err.span_note(impl_.self_ty.span, "not a concrete type");
21852199
}
2186-
Ty::new_error(tcx, err.emit())
2200+
let reported = err.emit();
2201+
self.set_tainted_by_errors(reported);
2202+
Ty::new_error(tcx, reported)
21872203
} else {
21882204
ty
21892205
}
@@ -2702,7 +2718,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
27022718
);
27032719
}
27042720

2705-
diag.emit();
2721+
self.set_tainted_by_errors(diag.emit());
27062722
}
27072723

27082724
// Find any late-bound regions declared in return type that do
@@ -2802,7 +2818,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28022818
err.note("consider introducing a named lifetime parameter");
28032819
}
28042820

2805-
err.emit();
2821+
self.set_tainted_by_errors(err.emit());
28062822
}
28072823
}
28082824

@@ -2841,7 +2857,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28412857
// error.
28422858
let r = derived_region_bounds[0];
28432859
if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2844-
tcx.dcx().emit_err(AmbiguousLifetimeBound { span });
2860+
self.set_tainted_by_errors(tcx.dcx().emit_err(AmbiguousLifetimeBound { span }));
28452861
}
28462862
Some(r)
28472863
}

compiler/rustc_hir_analysis/src/astconv/object_safety.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
116116
for more information on them, visit \
117117
<https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>",
118118
);
119-
err.emit();
119+
self.set_tainted_by_errors(err.emit());
120120
}
121121

122122
if regular_traits.is_empty() && auto_traits.is_empty() {
@@ -127,6 +127,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
127127
.map(|trait_ref| tcx.def_span(trait_ref));
128128
let reported =
129129
tcx.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span });
130+
self.set_tainted_by_errors(reported);
130131
return Ty::new_error(tcx, reported);
131132
}
132133

@@ -290,7 +291,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
290291

291292
if references_self {
292293
let def_id = i.bottom().0.def_id();
293-
struct_span_code_err!(
294+
let reported = struct_span_code_err!(
294295
tcx.dcx(),
295296
i.bottom().1,
296297
E0038,
@@ -303,6 +304,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
303304
.error_msg(),
304305
)
305306
.emit();
307+
self.set_tainted_by_errors(reported);
306308
}
307309

308310
ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
@@ -389,6 +391,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
389391
} else {
390392
err.emit()
391393
};
394+
self.set_tainted_by_errors(e);
392395
ty::Region::new_error(tcx, e)
393396
})
394397
}

compiler/rustc_hir_analysis/src/collect.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_target::spec::abi;
3535
use rustc_trait_selection::infer::InferCtxtExt;
3636
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
3737
use rustc_trait_selection::traits::ObligationCtxt;
38+
use std::cell::Cell;
3839
use std::iter;
3940
use std::ops::Bound;
4041

@@ -119,6 +120,7 @@ pub fn provide(providers: &mut Providers) {
119120
pub struct ItemCtxt<'tcx> {
120121
tcx: TyCtxt<'tcx>,
121122
item_def_id: LocalDefId,
123+
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
122124
}
123125

124126
///////////////////////////////////////////////////////////////////////////
@@ -343,7 +345,7 @@ fn bad_placeholder<'tcx>(
343345

344346
impl<'tcx> ItemCtxt<'tcx> {
345347
pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
346-
ItemCtxt { tcx, item_def_id }
348+
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
347349
}
348350

349351
pub fn to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
@@ -357,6 +359,13 @@ impl<'tcx> ItemCtxt<'tcx> {
357359
pub fn node(&self) -> hir::Node<'tcx> {
358360
self.tcx.hir_node(self.hir_id())
359361
}
362+
363+
fn check_tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
364+
match self.tainted_by_errors.get() {
365+
Some(err) => Err(err),
366+
None => Ok(()),
367+
}
368+
}
360369
}
361370

362371
impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
@@ -492,8 +501,8 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
492501
ty.ty_adt_def()
493502
}
494503

495-
fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
496-
// There's no obvious place to track this, so just let it go.
504+
fn set_tainted_by_errors(&self, err: ErrorGuaranteed) {
505+
self.tainted_by_errors.set(Some(err));
497506
}
498507

499508
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {

compiler/rustc_hir_analysis/src/collect/type_of.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
513513
bug!("unexpected sort of node in type_of(): {:?}", x);
514514
}
515515
};
516-
ty::EarlyBinder::bind(output)
516+
if let Err(e) = icx.check_tainted_by_errors() {
517+
ty::EarlyBinder::bind(Ty::new_error(tcx, e))
518+
} else {
519+
ty::EarlyBinder::bind(output)
520+
}
517521
}
518522

519523
pub(super) fn type_of_opaque(

compiler/rustc_hir_typeck/src/closure.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
802802
.explicit_item_bounds(def_id)
803803
.iter_instantiated_copied(self.tcx, args)
804804
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
805-
ty::Error(_) => return None,
805+
ty::Error(_) => return Some(ret_ty),
806806
_ => span_bug!(
807807
closure_span,
808808
"async fn coroutine return type not an inference variable: {ret_ty}"

tests/rustdoc-ui/unable-fulfill-trait.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pub struct Foo<'a, 'b, T> {
44
field1: dyn Bar<'a, 'b,>,
55
//~^ ERROR
66
//~| ERROR
7-
//~| ERROR
87
}
98

109
pub trait Bar<'x, 's, U>

tests/rustdoc-ui/unable-fulfill-trait.stderr

+3-20
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | field1: dyn Bar<'a, 'b,>,
55
| ^^^ expected 1 generic argument
66
|
77
note: trait defined here, with 1 generic parameter: `U`
8-
--> $DIR/unable-fulfill-trait.rs:10:11
8+
--> $DIR/unable-fulfill-trait.rs:9:11
99
|
1010
LL | pub trait Bar<'x, 's, U>
1111
| ^^^ -
@@ -20,24 +20,7 @@ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
2020
LL | field1: dyn Bar<'a, 'b,>,
2121
| ^^^^^^^^^^^^^^^^
2222

23-
error[E0478]: lifetime bound not satisfied
24-
--> $DIR/unable-fulfill-trait.rs:4:13
25-
|
26-
LL | field1: dyn Bar<'a, 'b,>,
27-
| ^^^^^^^^^^^^^^^^
28-
|
29-
note: lifetime parameter instantiated with the lifetime `'b` as defined here
30-
--> $DIR/unable-fulfill-trait.rs:3:20
31-
|
32-
LL | pub struct Foo<'a, 'b, T> {
33-
| ^^
34-
note: but lifetime parameter must outlive the lifetime `'a` as defined here
35-
--> $DIR/unable-fulfill-trait.rs:3:16
36-
|
37-
LL | pub struct Foo<'a, 'b, T> {
38-
| ^^
39-
40-
error: aborting due to 3 previous errors
23+
error: aborting due to 2 previous errors
4124

42-
Some errors have detailed explanations: E0107, E0227, E0478.
25+
Some errors have detailed explanations: E0107, E0227.
4326
For more information about an error, try `rustc --explain E0107`.

tests/ui/associated-inherent-types/issue-109071.no_gate.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ LL | type Item = &[T];
3030
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
3131

3232
error[E0223]: ambiguous associated type
33-
--> $DIR/issue-109071.rs:16:22
33+
--> $DIR/issue-109071.rs:15:22
3434
|
3535
LL | fn T() -> Option<Self::Item> {}
3636
| ^^^^^^^^^^

tests/ui/associated-inherent-types/issue-109071.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@ impl<T> Windows { //~ ERROR: missing generics for struct `Windows`
99
//[no_gate]~^ ERROR: inherent associated types are unstable
1010

1111
fn next() -> Option<Self::Item> {}
12-
//[with_gate]~^ ERROR type annotations needed
1312
}
1413

1514
impl<T> Windows<T> {
1615
fn T() -> Option<Self::Item> {}
17-
//[no_gate]~^ ERROR: ambiguous associated type
18-
//[with_gate]~^^ ERROR type annotations needed
16+
//~^ ERROR: ambiguous associated type
1917
}
2018

2119
fn main() {}

tests/ui/associated-inherent-types/issue-109071.with_gate.stderr

+12-11
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,20 @@ help: add missing generic argument
2020
LL | impl<T> Windows<T> {
2121
| +++
2222

23-
error[E0282]: type annotations needed
24-
--> $DIR/issue-109071.rs:11:18
25-
|
26-
LL | fn next() -> Option<Self::Item> {}
27-
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
28-
29-
error[E0282]: type annotations needed
30-
--> $DIR/issue-109071.rs:16:15
23+
error[E0223]: ambiguous associated type
24+
--> $DIR/issue-109071.rs:15:22
3125
|
3226
LL | fn T() -> Option<Self::Item> {}
33-
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
27+
| ^^^^^^^^^^
28+
|
29+
help: use fully-qualified syntax
30+
|
31+
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
32+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33+
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
34+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3435

35-
error: aborting due to 4 previous errors
36+
error: aborting due to 3 previous errors
3637

37-
Some errors have detailed explanations: E0107, E0282, E0637.
38+
Some errors have detailed explanations: E0107, E0223, E0637.
3839
For more information about an error, try `rustc --explain E0107`.

tests/ui/associated-types/issue-23595-1.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ use std::ops::Index;
55
trait Hierarchy {
66
type Value;
77
type ChildKey;
8-
type Children = dyn Index<Self::ChildKey, Output=dyn Hierarchy>;
8+
type Children = dyn Index<Self::ChildKey, Output = dyn Hierarchy>;
99
//~^ ERROR: the value of the associated types
10-
//~| ERROR: the size for values of type
1110

1211
fn data(&self) -> Option<(Self::Value, Self::Children)>;
1312
}

0 commit comments

Comments
 (0)