Skip to content

Commit

Permalink
Rollup merge of rust-lang#119813 - oli-obk:even_more_follow_up_errors…
Browse files Browse the repository at this point in the history
…2, 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.
  • Loading branch information
matthiaskrgr authored Jan 11, 2024
2 parents 762f101 + 55cab53 commit 63b5065
Show file tree
Hide file tree
Showing 35 changed files with 100 additions and 266 deletions.
4 changes: 3 additions & 1 deletion compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,15 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
.expect("missing associated item");

if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
tcx.dcx()
let reported = tcx
.dcx()
.struct_span_err(
binding.span,
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
)
.with_span_label(binding.span, format!("private {}", assoc_item.kind))
.emit();
self.set_tainted_by_errors(reported);
}
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);

Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
);
err.span_label(name.span, format!("multiple `{name}` found"));
self.note_ambiguous_inherent_assoc_type(&mut err, candidates, span);
err.emit()
let reported = err.emit();
self.set_tainted_by_errors(reported);
reported
}

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

err.emit();
self.set_tainted_by_errors(err.emit());
}
}

Expand Down
30 changes: 23 additions & 7 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
infer_args,
);

if let Err(err) = &arg_count.correct
&& let Some(reported) = err.reported
{
self.set_tainted_by_errors(reported);
}

// Skip processing if type has no generic parameters.
// Traits always have `Self` as a generic parameter, which means they will not return early
// here and so associated type bindings will be handled regardless of whether there are any
Expand Down Expand Up @@ -567,6 +573,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span,
modifier: constness.as_str(),
});
self.set_tainted_by_errors(e);
arg_count.correct =
Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] });
}
Expand Down Expand Up @@ -965,7 +972,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
}
err.emit()
let reported = err.emit();
self.set_tainted_by_errors(reported);
reported
}

// Search for a bound on a type parameter which includes the associated item
Expand Down Expand Up @@ -1042,6 +1051,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span,
binding,
);
self.set_tainted_by_errors(reported);
return Err(reported);
};
debug!(?bound);
Expand Down Expand Up @@ -1119,6 +1129,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
));
}
let reported = err.emit();
self.set_tainted_by_errors(reported);
if !where_bounds.is_empty() {
return Err(reported);
}
Expand Down Expand Up @@ -1373,6 +1384,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
assoc_ident.name,
)
};
self.set_tainted_by_errors(reported);
return Err(reported);
}
};
Expand Down Expand Up @@ -1615,12 +1627,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let kind = tcx.def_kind_descr(kind, item);
let msg = format!("{kind} `{name}` is private");
let def_span = tcx.def_span(item);
tcx.dcx()
let reported = tcx
.dcx()
.struct_span_err(span, msg)
.with_code(rustc_errors::error_code!(E0624))
.with_span_label(span, format!("private {kind}"))
.with_span_label(def_span, format!("{kind} defined here"))
.emit();
self.set_tainted_by_errors(reported);
}
tcx.check_stability(item, Some(block), span, None);
}
Expand Down Expand Up @@ -1861,7 +1875,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
err.span_label(span, format!("not allowed on {what}"));
}
extend(&mut err);
err.emit();
self.set_tainted_by_errors(err.emit());
emitted = true;
}

Expand Down Expand Up @@ -2183,7 +2197,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
{
err.span_note(impl_.self_ty.span, "not a concrete type");
}
Ty::new_error(tcx, err.emit())
let reported = err.emit();
self.set_tainted_by_errors(reported);
Ty::new_error(tcx, reported)
} else {
ty
}
Expand Down Expand Up @@ -2702,7 +2718,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
);
}

diag.emit();
self.set_tainted_by_errors(diag.emit());
}

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

err.emit();
self.set_tainted_by_errors(err.emit());
}
}

Expand Down Expand Up @@ -2841,7 +2857,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// error.
let r = derived_region_bounds[0];
if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
tcx.dcx().emit_err(AmbiguousLifetimeBound { span });
self.set_tainted_by_errors(tcx.dcx().emit_err(AmbiguousLifetimeBound { span }));
}
Some(r)
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir_analysis/src/astconv/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
for more information on them, visit \
<https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>",
);
err.emit();
self.set_tainted_by_errors(err.emit());
}

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

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

if references_self {
let def_id = i.bottom().0.def_id();
struct_span_code_err!(
let reported = struct_span_code_err!(
tcx.dcx(),
i.bottom().1,
E0038,
Expand All @@ -303,6 +304,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.error_msg(),
)
.emit();
self.set_tainted_by_errors(reported);
}

ty::ExistentialTraitRef { def_id: trait_ref.def_id, args }
Expand Down Expand Up @@ -389,6 +391,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} else {
err.emit()
};
self.set_tainted_by_errors(e);
ty::Region::new_error(tcx, e)
})
}
Expand Down
15 changes: 12 additions & 3 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use rustc_target::spec::abi;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
use rustc_trait_selection::traits::ObligationCtxt;
use std::cell::Cell;
use std::iter;
use std::ops::Bound;

Expand Down Expand Up @@ -119,6 +120,7 @@ pub fn provide(providers: &mut Providers) {
pub struct ItemCtxt<'tcx> {
tcx: TyCtxt<'tcx>,
item_def_id: LocalDefId,
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -343,7 +345,7 @@ fn bad_placeholder<'tcx>(

impl<'tcx> ItemCtxt<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
ItemCtxt { tcx, item_def_id }
ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
}

pub fn to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
Expand All @@ -357,6 +359,13 @@ impl<'tcx> ItemCtxt<'tcx> {
pub fn node(&self) -> hir::Node<'tcx> {
self.tcx.hir_node(self.hir_id())
}

fn check_tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
match self.tainted_by_errors.get() {
Some(err) => Err(err),
None => Ok(()),
}
}
}

impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
Expand Down Expand Up @@ -492,8 +501,8 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
ty.ty_adt_def()
}

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

fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
bug!("unexpected sort of node in type_of(): {:?}", x);
}
};
ty::EarlyBinder::bind(output)
if let Err(e) = icx.check_tainted_by_errors() {
ty::EarlyBinder::bind(Ty::new_error(tcx, e))
} else {
ty::EarlyBinder::bind(output)
}
}

pub(super) fn type_of_opaque(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, args)
.find_map(|(p, s)| get_future_output(p.as_predicate(), s))?,
ty::Error(_) => return None,
ty::Error(_) => return Some(ret_ty),
_ => span_bug!(
closure_span,
"async fn coroutine return type not an inference variable: {ret_ty}"
Expand Down
1 change: 0 additions & 1 deletion tests/rustdoc-ui/unable-fulfill-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub struct Foo<'a, 'b, T> {
field1: dyn Bar<'a, 'b,>,
//~^ ERROR
//~| ERROR
//~| ERROR
}

pub trait Bar<'x, 's, U>
Expand Down
23 changes: 3 additions & 20 deletions tests/rustdoc-ui/unable-fulfill-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | field1: dyn Bar<'a, 'b,>,
| ^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `U`
--> $DIR/unable-fulfill-trait.rs:10:11
--> $DIR/unable-fulfill-trait.rs:9:11
|
LL | pub trait Bar<'x, 's, U>
| ^^^ -
Expand All @@ -20,24 +20,7 @@ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
LL | field1: dyn Bar<'a, 'b,>,
| ^^^^^^^^^^^^^^^^

error[E0478]: lifetime bound not satisfied
--> $DIR/unable-fulfill-trait.rs:4:13
|
LL | field1: dyn Bar<'a, 'b,>,
| ^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'b` as defined here
--> $DIR/unable-fulfill-trait.rs:3:20
|
LL | pub struct Foo<'a, 'b, T> {
| ^^
note: but lifetime parameter must outlive the lifetime `'a` as defined here
--> $DIR/unable-fulfill-trait.rs:3:16
|
LL | pub struct Foo<'a, 'b, T> {
| ^^

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0107, E0227, E0478.
Some errors have detailed explanations: E0107, E0227.
For more information about an error, try `rustc --explain E0107`.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ LL | type Item = &[T];
= help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable

error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:16:22
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^
Expand Down
4 changes: 1 addition & 3 deletions tests/ui/associated-inherent-types/issue-109071.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ impl<T> Windows { //~ ERROR: missing generics for struct `Windows`
//[no_gate]~^ ERROR: inherent associated types are unstable

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

impl<T> Windows<T> {
fn T() -> Option<Self::Item> {}
//[no_gate]~^ ERROR: ambiguous associated type
//[with_gate]~^^ ERROR type annotations needed
//~^ ERROR: ambiguous associated type
}

fn main() {}
23 changes: 12 additions & 11 deletions tests/ui/associated-inherent-types/issue-109071.with_gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,20 @@ help: add missing generic argument
LL | impl<T> Windows<T> {
| +++

error[E0282]: type annotations needed
--> $DIR/issue-109071.rs:11:18
|
LL | fn next() -> Option<Self::Item> {}
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`

error[E0282]: type annotations needed
--> $DIR/issue-109071.rs:16:15
error[E0223]: ambiguous associated type
--> $DIR/issue-109071.rs:15:22
|
LL | fn T() -> Option<Self::Item> {}
| ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
| ^^^^^^^^^^
|
help: use fully-qualified syntax
|
LL | fn T() -> Option<<Windows<T> as IntoAsyncIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | fn T() -> Option<<Windows<T> as IntoIterator>::Item> {}
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0107, E0282, E0637.
Some errors have detailed explanations: E0107, E0223, E0637.
For more information about an error, try `rustc --explain E0107`.
3 changes: 1 addition & 2 deletions tests/ui/associated-types/issue-23595-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use std::ops::Index;
trait Hierarchy {
type Value;
type ChildKey;
type Children = dyn Index<Self::ChildKey, Output=dyn Hierarchy>;
type Children = dyn Index<Self::ChildKey, Output = dyn Hierarchy>;
//~^ ERROR: the value of the associated types
//~| ERROR: the size for values of type

fn data(&self) -> Option<(Self::Value, Self::Children)>;
}
Expand Down
Loading

0 comments on commit 63b5065

Please sign in to comment.