Skip to content

Commit 5ed746b

Browse files
authored
Rollup merge of #64746 - estebank:elide-impl-trait-obligations-on-err, r=cramertj
Remove blanket silencing of "type annotation needed" errors Remove blanket check for existence of other errors before emitting "type annotation needed" errors, and add some eager checks to avoid adding obligations when they refer to types that reference `[type error]` in order to reduce unneeded errors. Fix #64084.
2 parents 66ca0eb + b7ca1c5 commit 5ed746b

Some content is hidden

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

50 files changed

+297
-193
lines changed

src/librustc/hir/lowering.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2184,9 +2184,7 @@ impl<'a> LoweringContext<'a> {
21842184
match decl.output {
21852185
FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
21862186
Some((def_id, _)) if impl_trait_return_allow => {
2187-
hir::Return(self.lower_ty(ty,
2188-
ImplTraitContext::OpaqueTy(Some(def_id))
2189-
))
2187+
hir::Return(self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(def_id))))
21902188
}
21912189
_ => {
21922190
hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))

src/librustc/infer/opaque_types/mod.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
988988
value.fold_with(&mut BottomUpFolder {
989989
tcx,
990990
ty_op: |ty| {
991-
if let ty::Opaque(def_id, substs) = ty.sty {
991+
if ty.references_error() {
992+
return tcx.types.err;
993+
} else if let ty::Opaque(def_id, substs) = ty.sty {
992994
// Check that this is `impl Trait` type is
993995
// declared by `parent_def_id` -- i.e., one whose
994996
// value we are inferring. At present, this is
@@ -1155,6 +1157,15 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
11551157
);
11561158
debug!("instantiate_opaque_types: ty_var={:?}", ty_var);
11571159

1160+
for predicate in &bounds.predicates {
1161+
if let ty::Predicate::Projection(projection) = &predicate {
1162+
if projection.skip_binder().ty.references_error() {
1163+
// No point on adding these obligations since there's a type error involved.
1164+
return ty_var;
1165+
}
1166+
}
1167+
}
1168+
11581169
self.obligations.reserve(bounds.predicates.len());
11591170
for predicate in bounds.predicates {
11601171
// Change the predicate to refer to the type variable,

src/librustc/traits/error_reporting.rs

+42-29
Original file line numberDiff line numberDiff line change
@@ -1432,8 +1432,11 @@ impl<'tcx> TyCtxt<'tcx> {
14321432
}
14331433

14341434
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1435-
fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
1436-
body_id: Option<hir::BodyId>) {
1435+
fn maybe_report_ambiguity(
1436+
&self,
1437+
obligation: &PredicateObligation<'tcx>,
1438+
body_id: Option<hir::BodyId>,
1439+
) {
14371440
// Unable to successfully determine, probably means
14381441
// insufficient type information, but could mean
14391442
// ambiguous impls. The latter *ought* to be a
@@ -1442,9 +1445,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14421445
let predicate = self.resolve_vars_if_possible(&obligation.predicate);
14431446
let span = obligation.cause.span;
14441447

1445-
debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
1446-
predicate,
1447-
obligation);
1448+
debug!(
1449+
"maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})",
1450+
predicate,
1451+
obligation,
1452+
body_id,
1453+
obligation.cause.code,
1454+
);
14481455

14491456
// Ambiguity errors are often caused as fallout from earlier
14501457
// errors. So just ignore them if this infcx is tainted.
@@ -1456,6 +1463,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14561463
ty::Predicate::Trait(ref data) => {
14571464
let trait_ref = data.to_poly_trait_ref();
14581465
let self_ty = trait_ref.self_ty();
1466+
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.sty, trait_ref);
1467+
14591468
if predicate.references_error() {
14601469
return;
14611470
}
@@ -1480,24 +1489,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14801489
// be ignoring the fact that we don't KNOW the type works
14811490
// out. Though even that would probably be harmless, given that
14821491
// we're only talking about builtin traits, which are known to be
1483-
// inhabited. But in any case I just threw in this check for
1484-
// has_errors() to be sure that compilation isn't happening
1485-
// anyway. In that case, why inundate the user.
1486-
if !self.tcx.sess.has_errors() {
1487-
if
1488-
self.tcx.lang_items().sized_trait()
1489-
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
1490-
{
1491-
self.need_type_info_err(body_id, span, self_ty).emit();
1492-
} else {
1493-
let mut err = struct_span_err!(self.tcx.sess,
1494-
span, E0283,
1495-
"type annotations required: \
1496-
cannot resolve `{}`",
1497-
predicate);
1498-
self.note_obligation_cause(&mut err, obligation);
1499-
err.emit();
1500-
}
1492+
// inhabited. We used to check for `self.tcx.sess.has_errors()` to
1493+
// avoid inundating the user with unnecessary errors, but we now
1494+
// check upstream for type errors and dont add the obligations to
1495+
// begin with in those cases.
1496+
if
1497+
self.tcx.lang_items().sized_trait()
1498+
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
1499+
{
1500+
self.need_type_info_err(body_id, span, self_ty).emit();
1501+
} else {
1502+
let mut err = struct_span_err!(
1503+
self.tcx.sess,
1504+
span,
1505+
E0283,
1506+
"type annotations needed: cannot resolve `{}`",
1507+
predicate,
1508+
);
1509+
self.note_obligation_cause(&mut err, obligation);
1510+
err.emit();
15011511
}
15021512
}
15031513

@@ -1524,11 +1534,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15241534

15251535
_ => {
15261536
if !self.tcx.sess.has_errors() {
1527-
let mut err = struct_span_err!(self.tcx.sess,
1528-
obligation.cause.span, E0284,
1529-
"type annotations required: \
1530-
cannot resolve `{}`",
1531-
predicate);
1537+
let mut err = struct_span_err!(
1538+
self.tcx.sess,
1539+
obligation.cause.span,
1540+
E0284,
1541+
"type annotations needed: cannot resolve `{}`",
1542+
predicate,
1543+
);
15321544
self.note_obligation_cause(&mut err, obligation);
15331545
err.emit();
15341546
}
@@ -1766,7 +1778,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
17661778
but not on the corresponding trait method",
17671779
predicate));
17681780
}
1769-
ObligationCauseCode::ReturnType(_) |
1781+
ObligationCauseCode::ReturnType |
1782+
ObligationCauseCode::ReturnValue(_) |
17701783
ObligationCauseCode::BlockTailExpression(_) => (),
17711784
ObligationCauseCode::TrivialBound => {
17721785
err.help("see issue #48214");

src/librustc/traits/mod.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,14 @@ pub enum ObligationCauseCode<'tcx> {
212212
/// Constant expressions must be sized.
213213
ConstSized,
214214

215-
/// static items must have `Sync` type
215+
/// Static items must have `Sync` type
216216
SharedStatic,
217217

218218
BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
219219

220220
ImplDerivedObligation(DerivedObligationCause<'tcx>),
221221

222-
/// error derived when matching traits/impls; see ObligationCause for more details
222+
/// Error derived when matching traits/impls; see ObligationCause for more details
223223
CompareImplMethodObligation {
224224
item_name: ast::Name,
225225
impl_item_def_id: DefId,
@@ -248,17 +248,20 @@ pub enum ObligationCauseCode<'tcx> {
248248
/// `start` has wrong type
249249
StartFunctionType,
250250

251-
/// intrinsic has wrong type
251+
/// Intrinsic has wrong type
252252
IntrinsicType,
253253

254-
/// method receiver
254+
/// Method receiver
255255
MethodReceiver,
256256

257257
/// `return` with no expression
258258
ReturnNoExpression,
259259

260260
/// `return` with an expression
261-
ReturnType(hir::HirId),
261+
ReturnValue(hir::HirId),
262+
263+
/// Return type of this function
264+
ReturnType,
262265

263266
/// Block implicit return
264267
BlockTailExpression(hir::HirId),

src/librustc/traits/select.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ pub struct SelectionCache<'tcx> {
214214
/// of type variables - it just means the obligation isn't sufficiently
215215
/// elaborated. In that case we report an ambiguity, and the caller can
216216
/// try again after more type information has been gathered or report a
217-
/// "type annotations required" error.
217+
/// "type annotations needed" error.
218218
///
219219
/// However, with type parameters, this can be a real problem - type
220220
/// parameters don't unify with regular types, but they *can* unify

src/librustc/traits/structural_impls.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,8 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
485485
super::TupleInitializerSized => Some(super::TupleInitializerSized),
486486
super::StructInitializerSized => Some(super::StructInitializerSized),
487487
super::VariableType(id) => Some(super::VariableType(id)),
488-
super::ReturnType(id) => Some(super::ReturnType(id)),
488+
super::ReturnValue(id) => Some(super::ReturnValue(id)),
489+
super::ReturnType => Some(super::ReturnType),
489490
super::SizedArgumentType => Some(super::SizedArgumentType),
490491
super::SizedReturnType => Some(super::SizedReturnType),
491492
super::SizedYieldType => Some(super::SizedYieldType),

src/librustc/ty/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -438,19 +438,19 @@ bitflags! {
438438

439439
/// `true` if there are "names" of types and regions and so forth
440440
/// that are local to a particular fn
441-
const HAS_FREE_LOCAL_NAMES = 1 << 9;
441+
const HAS_FREE_LOCAL_NAMES = 1 << 9;
442442

443443
/// Present if the type belongs in a local type context.
444444
/// Only set for Infer other than Fresh.
445445
const KEEP_IN_LOCAL_TCX = 1 << 10;
446446

447447
/// Does this have any `ReLateBound` regions? Used to check
448448
/// if a global bound is safe to evaluate.
449-
const HAS_RE_LATE_BOUND = 1 << 11;
449+
const HAS_RE_LATE_BOUND = 1 << 11;
450450

451451
const HAS_TY_PLACEHOLDER = 1 << 12;
452452

453-
const HAS_CT_INFER = 1 << 13;
453+
const HAS_CT_INFER = 1 << 13;
454454
const HAS_CT_PLACEHOLDER = 1 << 14;
455455

456456
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |

src/librustc_typeck/check/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
12531253
expression.map(|expr| (expr, blk_id)),
12541254
);
12551255
}
1256-
ObligationCauseCode::ReturnType(id) => {
1256+
ObligationCauseCode::ReturnValue(id) => {
12571257
db = self.report_return_mismatched_types(
12581258
cause, expected, found, err, fcx, id, None);
12591259
}

src/librustc_typeck/check/expr.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -664,12 +664,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
664664

665665
let ret_ty = ret_coercion.borrow().expected_ty();
666666
let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
667-
ret_coercion.borrow_mut()
668-
.coerce(self,
669-
&self.cause(return_expr.span,
670-
ObligationCauseCode::ReturnType(return_expr.hir_id)),
671-
return_expr,
672-
return_expr_ty);
667+
ret_coercion.borrow_mut().coerce(
668+
self,
669+
&self.cause(return_expr.span, ObligationCauseCode::ReturnValue(return_expr.hir_id)),
670+
return_expr,
671+
return_expr_ty,
672+
);
673673
}
674674

675675
/// Type check assignment expression `expr` of form `lhs = rhs`.

src/librustc_typeck/check/mod.rs

+47-35
Original file line numberDiff line numberDiff line change
@@ -2698,30 +2698,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26982698
traits::ObligationCause::new(span, self.body_id, code));
26992699
}
27002700

2701-
pub fn require_type_is_sized(&self,
2702-
ty: Ty<'tcx>,
2703-
span: Span,
2704-
code: traits::ObligationCauseCode<'tcx>)
2705-
{
2706-
let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2707-
self.require_type_meets(ty, span, code, lang_item);
2701+
pub fn require_type_is_sized(
2702+
&self,
2703+
ty: Ty<'tcx>,
2704+
span: Span,
2705+
code: traits::ObligationCauseCode<'tcx>,
2706+
) {
2707+
if !ty.references_error() {
2708+
let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
2709+
self.require_type_meets(ty, span, code, lang_item);
2710+
}
27082711
}
27092712

2710-
pub fn require_type_is_sized_deferred(&self,
2711-
ty: Ty<'tcx>,
2712-
span: Span,
2713-
code: traits::ObligationCauseCode<'tcx>)
2714-
{
2715-
self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2713+
pub fn require_type_is_sized_deferred(
2714+
&self,
2715+
ty: Ty<'tcx>,
2716+
span: Span,
2717+
code: traits::ObligationCauseCode<'tcx>,
2718+
) {
2719+
if !ty.references_error() {
2720+
self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
2721+
}
27162722
}
27172723

2718-
pub fn register_bound(&self,
2719-
ty: Ty<'tcx>,
2720-
def_id: DefId,
2721-
cause: traits::ObligationCause<'tcx>)
2722-
{
2723-
self.fulfillment_cx.borrow_mut()
2724-
.register_bound(self, self.param_env, ty, def_id, cause);
2724+
pub fn register_bound(
2725+
&self,
2726+
ty: Ty<'tcx>,
2727+
def_id: DefId,
2728+
cause: traits::ObligationCause<'tcx>,
2729+
) {
2730+
if !ty.references_error() {
2731+
self.fulfillment_cx.borrow_mut()
2732+
.register_bound(self, self.param_env, ty, def_id, cause);
2733+
}
27252734
}
27262735

27272736
pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
@@ -2780,22 +2789,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27802789

27812790
/// Registers an obligation for checking later, during regionck, that the type `ty` must
27822791
/// outlive the region `r`.
2783-
pub fn register_wf_obligation(&self,
2784-
ty: Ty<'tcx>,
2785-
span: Span,
2786-
code: traits::ObligationCauseCode<'tcx>)
2787-
{
2792+
pub fn register_wf_obligation(
2793+
&self,
2794+
ty: Ty<'tcx>,
2795+
span: Span,
2796+
code: traits::ObligationCauseCode<'tcx>,
2797+
) {
27882798
// WF obligations never themselves fail, so no real need to give a detailed cause:
27892799
let cause = traits::ObligationCause::new(span, self.body_id, code);
2790-
self.register_predicate(traits::Obligation::new(cause,
2791-
self.param_env,
2792-
ty::Predicate::WellFormed(ty)));
2800+
self.register_predicate(
2801+
traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)),
2802+
);
27932803
}
27942804

27952805
/// Registers obligations that all types appearing in `substs` are well-formed.
27962806
pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
27972807
for ty in substs.types() {
2798-
self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2808+
if !ty.references_error() {
2809+
self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
2810+
}
27992811
}
28002812
}
28012813

@@ -2834,12 +2846,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28342846
// FIXME(arielb1): use this instead of field.ty everywhere
28352847
// Only for fields! Returns <none> for methods>
28362848
// Indifferent to privacy flags
2837-
pub fn field_ty(&self,
2838-
span: Span,
2839-
field: &'tcx ty::FieldDef,
2840-
substs: SubstsRef<'tcx>)
2841-
-> Ty<'tcx>
2842-
{
2849+
pub fn field_ty(
2850+
&self,
2851+
span: Span,
2852+
field: &'tcx ty::FieldDef,
2853+
substs: SubstsRef<'tcx>,
2854+
) -> Ty<'tcx> {
28432855
self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
28442856
}
28452857

src/librustc_typeck/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ fn check_fn_or_method<'fcx, 'tcx>(
596596
}
597597
implied_bounds.extend(sig.inputs());
598598

599-
fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation);
599+
fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::ReturnType);
600600

601601
// FIXME(#25759) return types should not be implied bounds
602602
implied_bounds.push(sig.output());

src/test/ui/associated-types/associated-types-overridden-binding.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#![feature(trait_alias)]
22

33
trait Foo: Iterator<Item = i32> {}
4-
trait Bar: Foo<Item = u32> {} //~ ERROR type annotations required
4+
trait Bar: Foo<Item = u32> {} //~ ERROR type annotations needed
55

66
trait I32Iterator = Iterator<Item = i32>;
7-
trait U32Iterator = I32Iterator<Item = u32>;
7+
trait U32Iterator = I32Iterator<Item = u32>; //~ ERROR type annotations needed
88

99
fn main() {
1010
let _: &dyn I32Iterator<Item = u32>;

0 commit comments

Comments
 (0)