Use ty_error_with_guaranteed in many more places
This commit is contained in:
parent
fdbc4329cb
commit
1e7ef03b40
@ -1,5 +1,6 @@
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_data_structures::vec_map::VecMap;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::OpaqueTyOrigin;
|
||||
use rustc_infer::infer::TyCtxtInferExt as _;
|
||||
@ -149,13 +150,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
// once we convert the generic parameters to those of the opaque type.
|
||||
if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
|
||||
if prev.ty != ty {
|
||||
if !ty.references_error() {
|
||||
let guar = ty.error_reported().err().unwrap_or_else(|| {
|
||||
prev.report_mismatch(
|
||||
&OpaqueHiddenType { ty, span: concrete_type.span },
|
||||
infcx.tcx,
|
||||
);
|
||||
}
|
||||
prev.ty = infcx.tcx.ty_error();
|
||||
)
|
||||
});
|
||||
prev.ty = infcx.tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
// Pick a better span if there is one.
|
||||
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
|
||||
@ -254,13 +255,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
|
||||
.ty;
|
||||
|
||||
if !check_opaque_type_parameter_valid(
|
||||
if let Err(guar) = check_opaque_type_parameter_valid(
|
||||
self.tcx,
|
||||
opaque_type_key,
|
||||
origin,
|
||||
instantiated_ty.span,
|
||||
) {
|
||||
return self.tcx.ty_error();
|
||||
return self.tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
|
||||
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
|
||||
@ -335,7 +336,7 @@ fn check_opaque_type_parameter_valid(
|
||||
opaque_type_key: OpaqueTypeKey<'_>,
|
||||
origin: OpaqueTyOrigin,
|
||||
span: Span,
|
||||
) -> bool {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
match origin {
|
||||
// No need to check return position impl trait (RPIT)
|
||||
// because for type and const parameters they are correct
|
||||
@ -358,7 +359,7 @@ fn check_opaque_type_parameter_valid(
|
||||
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
||||
//
|
||||
// which would error here on all of the `'static` args.
|
||||
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
|
||||
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()),
|
||||
// Check these
|
||||
OpaqueTyOrigin::TyAlias => {}
|
||||
}
|
||||
@ -379,13 +380,13 @@ fn check_opaque_type_parameter_valid(
|
||||
// Prevent `fn foo() -> Foo<u32>` from being defining.
|
||||
let opaque_param = opaque_generics.param_at(i, tcx);
|
||||
let kind = opaque_param.kind.descr();
|
||||
tcx.sess.emit_err(NonGenericOpaqueTypeParam {
|
||||
|
||||
return Err(tcx.sess.emit_err(NonGenericOpaqueTypeParam {
|
||||
ty: arg,
|
||||
kind,
|
||||
span,
|
||||
param_span: tcx.def_span(opaque_param.def_id),
|
||||
});
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -396,12 +397,13 @@ fn check_opaque_type_parameter_valid(
|
||||
.into_iter()
|
||||
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
|
||||
.collect();
|
||||
tcx.sess
|
||||
return Err(tcx
|
||||
.sess
|
||||
.struct_span_err(span, "non-defining opaque type use in defining scope")
|
||||
.span_note(spans, &format!("{} used multiple times", descr))
|
||||
.emit();
|
||||
return false;
|
||||
.emit());
|
||||
}
|
||||
}
|
||||
true
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -270,12 +270,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
.and(type_op::normalize::Normalize::new(ty))
|
||||
.fully_perform(self.infcx)
|
||||
.unwrap_or_else(|_| {
|
||||
self.infcx
|
||||
let guar = self
|
||||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
|
||||
TypeOpOutput {
|
||||
output: self.infcx.tcx.ty_error(),
|
||||
output: self.infcx.tcx.ty_error_with_guaranteed(guar),
|
||||
constraints: None,
|
||||
error_info: None,
|
||||
}
|
||||
|
@ -529,9 +529,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
|
||||
for elem in place.projection.iter() {
|
||||
if place_ty.variant_index.is_none() {
|
||||
if place_ty.ty.references_error() {
|
||||
if let Err(guar) = place_ty.ty.error_reported() {
|
||||
assert!(self.errors_reported);
|
||||
return PlaceTy::from_ty(self.tcx().ty_error());
|
||||
return PlaceTy::from_ty(self.tcx().ty_error_with_guaranteed(guar));
|
||||
}
|
||||
}
|
||||
place_ty = self.sanitize_projection(place_ty, elem, place, location, context);
|
||||
|
@ -518,8 +518,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.type_of(param.def_id)
|
||||
.no_bound_vars()
|
||||
.expect("const parameter types cannot be generic");
|
||||
if ty.references_error() {
|
||||
return tcx.const_error(ty).into();
|
||||
if let Err(guar) = ty.error_reported() {
|
||||
return tcx.const_error_with_guaranteed(ty, guar).into();
|
||||
}
|
||||
if !infer_args && has_default {
|
||||
tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
|
||||
@ -1579,7 +1579,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
false
|
||||
});
|
||||
if references_self {
|
||||
tcx.sess
|
||||
let guar = tcx
|
||||
.sess
|
||||
.delay_span_bug(span, "trait object projection bounds reference `Self`");
|
||||
let substs: Vec<_> = b
|
||||
.projection_ty
|
||||
@ -1587,7 +1588,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
if arg.walk().any(|arg| arg == dummy_self.into()) {
|
||||
return tcx.ty_error().into();
|
||||
return tcx.ty_error_with_guaranteed(guar).into();
|
||||
}
|
||||
arg
|
||||
})
|
||||
@ -3064,7 +3065,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let ty = self.ast_ty_to_ty_inner(qself, false, true);
|
||||
self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false)
|
||||
.map(|(ty, _, _)| ty)
|
||||
.unwrap_or_else(|_| tcx.ty_error())
|
||||
.unwrap_or_else(|guar| tcx.ty_error_with_guaranteed(guar))
|
||||
}
|
||||
&hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
|
||||
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
||||
|
@ -319,8 +319,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>>
|
||||
ItemKind::Impl(hir::Impl { self_ty, .. }) => {
|
||||
match self_ty.find_self_aliases() {
|
||||
spans if spans.len() > 0 => {
|
||||
tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), });
|
||||
tcx.ty_error()
|
||||
let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
|
||||
tcx.ty_error_with_guaranteed(guar)
|
||||
},
|
||||
_ => icx.to_ty(*self_ty),
|
||||
}
|
||||
@ -599,8 +599,11 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
|
||||
// // constant does not contain interior mutability.
|
||||
// ```
|
||||
let tables = self.tcx.typeck(item_def_id);
|
||||
if let Some(_) = tables.tainted_by_errors {
|
||||
self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error() });
|
||||
if let Some(guar) = tables.tainted_by_errors {
|
||||
self.found = Some(ty::OpaqueHiddenType {
|
||||
span: DUMMY_SP,
|
||||
ty: self.tcx.ty_error_with_guaranteed(guar),
|
||||
});
|
||||
return;
|
||||
}
|
||||
let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else {
|
||||
@ -618,8 +621,8 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
|
||||
debug!(?concrete_type, "found constraint");
|
||||
if let Some(prev) = &mut self.found {
|
||||
if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() {
|
||||
prev.report_mismatch(&concrete_type, self.tcx);
|
||||
prev.ty = self.tcx.ty_error();
|
||||
let guar = prev.report_mismatch(&concrete_type, self.tcx);
|
||||
prev.ty = self.tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
} else {
|
||||
self.found = Some(concrete_type);
|
||||
@ -814,11 +817,11 @@ fn find_opaque_ty_constraints_for_rpit(
|
||||
|
||||
concrete.map(|concrete| concrete.ty).unwrap_or_else(|| {
|
||||
let table = tcx.typeck(owner_def_id);
|
||||
if let Some(_) = table.tainted_by_errors {
|
||||
if let Some(guar) = table.tainted_by_errors {
|
||||
// Some error in the
|
||||
// owner fn prevented us from populating
|
||||
// the `concrete_opaque_types` table.
|
||||
tcx.ty_error()
|
||||
tcx.ty_error_with_guaranteed(guar)
|
||||
} else {
|
||||
table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| {
|
||||
// We failed to resolve the opaque type or it
|
||||
|
@ -3,6 +3,7 @@
|
||||
use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
|
||||
|
||||
use hir::def::DefKind;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir_analysis::astconv::AstConv;
|
||||
@ -488,17 +489,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
let expected_span =
|
||||
expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id));
|
||||
self.report_arg_count_mismatch(
|
||||
expected_span,
|
||||
closure_span,
|
||||
expected_args,
|
||||
found_args,
|
||||
true,
|
||||
closure_arg_span,
|
||||
)
|
||||
.emit();
|
||||
let guar = self
|
||||
.report_arg_count_mismatch(
|
||||
expected_span,
|
||||
closure_span,
|
||||
expected_args,
|
||||
found_args,
|
||||
true,
|
||||
closure_arg_span,
|
||||
)
|
||||
.emit();
|
||||
|
||||
let error_sig = self.error_sig_of_closure(decl);
|
||||
let error_sig = self.error_sig_of_closure(decl, guar);
|
||||
|
||||
self.closure_sigs(expr_def_id, body, error_sig)
|
||||
}
|
||||
@ -792,13 +794,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// Converts the types that the user supplied, in case that doing
|
||||
/// so should yield an error, but returns back a signature where
|
||||
/// all parameters are of type `TyErr`.
|
||||
fn error_sig_of_closure(&self, decl: &hir::FnDecl<'_>) -> ty::PolyFnSig<'tcx> {
|
||||
fn error_sig_of_closure(
|
||||
&self,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
guar: ErrorGuaranteed,
|
||||
) -> ty::PolyFnSig<'tcx> {
|
||||
let astconv: &dyn AstConv<'_> = self;
|
||||
let err_ty = self.tcx.ty_error_with_guaranteed(guar);
|
||||
|
||||
let supplied_arguments = decl.inputs.iter().map(|a| {
|
||||
// Convert the types that the user supplied (if any), but ignore them.
|
||||
astconv.ast_ty_to_ty(a);
|
||||
self.tcx.ty_error()
|
||||
err_ty
|
||||
});
|
||||
|
||||
if let hir::FnRetTy::Return(ref output) = decl.output {
|
||||
@ -807,7 +814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let result = ty::Binder::dummy(self.tcx.mk_fn_sig(
|
||||
supplied_arguments,
|
||||
self.tcx.ty_error(),
|
||||
err_ty,
|
||||
decl.c_variadic,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::RustCall,
|
||||
|
@ -170,14 +170,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
debug!("Coerce.tys({:?} => {:?})", a, b);
|
||||
|
||||
// Just ignore error types.
|
||||
if a.references_error() || b.references_error() {
|
||||
if let Err(guar) = (a, b).error_reported() {
|
||||
// Best-effort try to unify these types -- we're already on the error path,
|
||||
// so this will have the side-effect of making sure we have no ambiguities
|
||||
// due to `[type error]` and `_` not coercing together.
|
||||
let _ = self.commit_if_ok(|_| {
|
||||
self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b)
|
||||
});
|
||||
return success(vec![], self.fcx.tcx.ty_error(), vec![]);
|
||||
return success(vec![], self.fcx.tcx.ty_error_with_guaranteed(guar), vec![]);
|
||||
}
|
||||
|
||||
// Coercing from `!` to any type is allowed:
|
||||
@ -997,7 +997,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let (adjustments, _) = self.register_infer_ok_obligations(ok);
|
||||
self.apply_adjustments(expr, adjustments);
|
||||
Ok(if expr_ty.references_error() { self.tcx.ty_error() } else { target })
|
||||
Ok(if let Err(guar) = expr_ty.error_reported() {
|
||||
self.tcx.ty_error_with_guaranteed(guar)
|
||||
} else {
|
||||
target
|
||||
})
|
||||
}
|
||||
|
||||
/// Same as `try_coerce()`, but without side-effects.
|
||||
@ -1434,8 +1438,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
|
||||
// If we see any error types, just propagate that error
|
||||
// upwards.
|
||||
if expression_ty.references_error() || self.merged_ty().references_error() {
|
||||
self.final_ty = Some(fcx.tcx.ty_error());
|
||||
if let Err(guar) = (expression_ty, self.merged_ty()).error_reported() {
|
||||
self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(guar));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1033,7 +1033,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let result_ty = coerce.complete(self);
|
||||
if cond_ty.references_error() { self.tcx.ty_error() } else { result_ty }
|
||||
if let Err(guar) = cond_ty.error_reported() {
|
||||
self.tcx.ty_error_with_guaranteed(guar)
|
||||
} else {
|
||||
result_ty
|
||||
}
|
||||
}
|
||||
|
||||
/// Type check assignment expression `expr` of form `lhs = rhs`.
|
||||
@ -1155,8 +1159,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
|
||||
|
||||
if lhs_ty.references_error() || rhs_ty.references_error() {
|
||||
self.tcx.ty_error()
|
||||
if let Err(guar) = (lhs_ty, rhs_ty).error_reported() {
|
||||
self.tcx.ty_error_with_guaranteed(guar)
|
||||
} else {
|
||||
self.tcx.mk_unit()
|
||||
}
|
||||
@ -1274,8 +1278,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let t_expr = self.resolve_vars_if_possible(t_expr);
|
||||
|
||||
// Eagerly check for some obvious errors.
|
||||
if t_expr.references_error() || t_cast.references_error() {
|
||||
self.tcx.ty_error()
|
||||
if let Err(guar) = (t_expr, t_cast).error_reported() {
|
||||
self.tcx.ty_error_with_guaranteed(guar)
|
||||
} else {
|
||||
// Defer other checks until we're done type checking.
|
||||
let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
|
||||
@ -1296,7 +1300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
deferred_cast_checks.push(cast_check);
|
||||
t_cast
|
||||
}
|
||||
Err(_) => self.tcx.ty_error(),
|
||||
Err(guar) => self.tcx.ty_error_with_guaranteed(guar),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1423,8 +1427,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
if element_ty.references_error() {
|
||||
return tcx.ty_error();
|
||||
if let Err(guar) = element_ty.error_reported() {
|
||||
return tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
|
||||
self.check_repeat_element_needs_copy_bound(element, count, element_ty);
|
||||
@ -1493,8 +1497,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
_ => self.check_expr_with_expectation(&e, NoExpectation),
|
||||
});
|
||||
let tuple = self.tcx.mk_tup(elt_ts_iter);
|
||||
if tuple.references_error() {
|
||||
self.tcx.ty_error()
|
||||
if let Err(guar) = tuple.error_reported() {
|
||||
self.tcx.ty_error_with_guaranteed(guar)
|
||||
} else {
|
||||
self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
|
||||
tuple
|
||||
@ -1510,9 +1514,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
|
||||
) -> Ty<'tcx> {
|
||||
// Find the relevant variant
|
||||
let Some((variant, adt_ty)) = self.check_struct_path(qpath, expr.hir_id) else {
|
||||
self.check_struct_fields_on_error(fields, base_expr);
|
||||
return self.tcx.ty_error();
|
||||
let (variant, adt_ty) = match self.check_struct_path(qpath, expr.hir_id) {
|
||||
Ok(data) => data,
|
||||
Err(guar) => {
|
||||
self.check_struct_fields_on_error(fields, base_expr);
|
||||
return self.tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
};
|
||||
|
||||
// Prohibit struct expressions when non-exhaustive flag is set.
|
||||
@ -1594,12 +1601,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.field_ty(field.span, v_field, substs)
|
||||
} else {
|
||||
error_happened = true;
|
||||
if let Some(prev_span) = seen_fields.get(&ident) {
|
||||
let guar = if let Some(prev_span) = seen_fields.get(&ident) {
|
||||
tcx.sess.emit_err(FieldMultiplySpecifiedInInitializer {
|
||||
span: field.ident.span,
|
||||
prev_span: *prev_span,
|
||||
ident,
|
||||
});
|
||||
})
|
||||
} else {
|
||||
self.report_unknown_field(
|
||||
adt_ty,
|
||||
@ -1608,10 +1615,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ast_fields,
|
||||
adt.variant_descr(),
|
||||
expr_span,
|
||||
);
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
tcx.ty_error()
|
||||
tcx.ty_error_with_guaranteed(guar)
|
||||
};
|
||||
|
||||
// Make sure to give a type to the field even if there's
|
||||
@ -1994,14 +2001,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
skip_fields: &[hir::ExprField<'_>],
|
||||
kind_name: &str,
|
||||
expr_span: Span,
|
||||
) {
|
||||
) -> ErrorGuaranteed {
|
||||
if variant.is_recovered() {
|
||||
self.set_tainted_by_errors(
|
||||
self.tcx
|
||||
.sess
|
||||
.delay_span_bug(expr_span, "parser recovered but no error was emitted"),
|
||||
);
|
||||
return;
|
||||
let guar = self
|
||||
.tcx
|
||||
.sess
|
||||
.delay_span_bug(expr_span, "parser recovered but no error was emitted");
|
||||
self.set_tainted_by_errors(guar);
|
||||
return guar;
|
||||
}
|
||||
let mut err = self.err_ctxt().type_error_struct_with_diag(
|
||||
field.ident.span,
|
||||
@ -2115,7 +2122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
// Return a hint about the closest match in field names
|
||||
@ -2256,11 +2263,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// (#90483) apply adjustments to avoid ExprUseVisitor from
|
||||
// creating erroneous projection.
|
||||
self.apply_adjustments(base, adjustments);
|
||||
self.ban_private_field_access(expr, base_ty, field, did, expected.only_has_type(self));
|
||||
return self.tcx().ty_error();
|
||||
let guar = self.ban_private_field_access(
|
||||
expr,
|
||||
base_ty,
|
||||
field,
|
||||
did,
|
||||
expected.only_has_type(self),
|
||||
);
|
||||
return self.tcx().ty_error_with_guaranteed(guar);
|
||||
}
|
||||
|
||||
if field.name == kw::Empty {
|
||||
let guar = if field.name == kw::Empty {
|
||||
self.tcx.sess.delay_span_bug(field.span, "field name with no name")
|
||||
} else if self.method_exists(
|
||||
field,
|
||||
base_ty,
|
||||
@ -2268,9 +2282,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
true,
|
||||
expected.only_has_type(self),
|
||||
) {
|
||||
self.ban_take_value_of_method(expr, base_ty, field);
|
||||
self.ban_take_value_of_method(expr, base_ty, field)
|
||||
} else if !base_ty.is_primitive_ty() {
|
||||
self.ban_nonexisting_field(field, base, expr, base_ty);
|
||||
self.ban_nonexisting_field(field, base, expr, base_ty)
|
||||
} else {
|
||||
let field_name = field.to_string();
|
||||
let mut err = type_error_struct!(
|
||||
@ -2339,10 +2353,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
err.emit()
|
||||
};
|
||||
|
||||
self.tcx().ty_error()
|
||||
self.tcx().ty_error_with_guaranteed(guar)
|
||||
}
|
||||
|
||||
fn suggest_await_on_field_access(
|
||||
@ -2388,7 +2402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
base: &'tcx hir::Expr<'tcx>,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
base_ty: Ty<'tcx>,
|
||||
) {
|
||||
) -> ErrorGuaranteed {
|
||||
debug!(
|
||||
"ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}",
|
||||
ident, base, expr, base_ty
|
||||
@ -2436,7 +2450,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn ban_private_field_access(
|
||||
@ -2446,7 +2460,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
field: Ident,
|
||||
base_did: DefId,
|
||||
return_ty: Option<Ty<'tcx>>,
|
||||
) {
|
||||
) -> ErrorGuaranteed {
|
||||
let struct_path = self.tcx().def_path_str(base_did);
|
||||
let kind_name = self.tcx().def_kind(base_did).descr(base_did);
|
||||
let mut err = struct_span_err!(
|
||||
@ -2469,10 +2483,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
None,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn ban_take_value_of_method(&self, expr: &hir::Expr<'tcx>, expr_t: Ty<'tcx>, field: Ident) {
|
||||
fn ban_take_value_of_method(
|
||||
&self,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
expr_t: Ty<'tcx>,
|
||||
field: Ident,
|
||||
) -> ErrorGuaranteed {
|
||||
let mut err = type_error_struct!(
|
||||
self.tcx().sess,
|
||||
field.span,
|
||||
@ -2544,7 +2563,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.help("methods are immutable and cannot be assigned to");
|
||||
}
|
||||
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) {
|
||||
|
@ -701,7 +701,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
|
||||
vec![self.tcx.ty_error(); len]
|
||||
let ty_error = self.tcx.ty_error();
|
||||
vec![ty_error; len]
|
||||
}
|
||||
|
||||
/// Unifies the output type with the expected type early, for more coercions
|
||||
|
@ -10,7 +10,9 @@ use crate::{
|
||||
};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
|
||||
use rustc_errors::{
|
||||
pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -1294,15 +1296,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
qpath: &QPath<'_>,
|
||||
hir_id: hir::HirId,
|
||||
) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
|
||||
) -> Result<(&'tcx ty::VariantDef, Ty<'tcx>), ErrorGuaranteed> {
|
||||
let path_span = qpath.span();
|
||||
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
|
||||
let variant = match def {
|
||||
Res::Err => {
|
||||
self.set_tainted_by_errors(
|
||||
self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"),
|
||||
);
|
||||
return None;
|
||||
let guar =
|
||||
self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted");
|
||||
self.set_tainted_by_errors(guar);
|
||||
return Err(guar);
|
||||
}
|
||||
Res::Def(DefKind::Variant, _) => match ty.normalized.ty_adt_def() {
|
||||
Some(adt) => {
|
||||
@ -1330,28 +1332,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Check bounds on type arguments used in the path.
|
||||
self.add_required_obligations_for_hir(path_span, did, substs, hir_id);
|
||||
|
||||
Some((variant, ty.normalized))
|
||||
Ok((variant, ty.normalized))
|
||||
} else {
|
||||
match ty.normalized.kind() {
|
||||
ty::Error(_) => {
|
||||
Err(match *ty.normalized.kind() {
|
||||
ty::Error(guar) => {
|
||||
// E0071 might be caused by a spelling error, which will have
|
||||
// already caused an error message and probably a suggestion
|
||||
// elsewhere. Refrain from emitting more unhelpful errors here
|
||||
// (issue #88844).
|
||||
guar
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
path_span,
|
||||
E0071,
|
||||
"expected struct, variant or union type, found {}",
|
||||
ty.normalized.sort_string(self.tcx)
|
||||
)
|
||||
.span_label(path_span, "not a struct")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
None
|
||||
_ => struct_span_err!(
|
||||
self.tcx.sess,
|
||||
path_span,
|
||||
E0071,
|
||||
"expected struct, variant or union type, found {}",
|
||||
ty.normalized.sort_string(self.tcx)
|
||||
)
|
||||
.span_label(path_span, "not a struct")
|
||||
.emit(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1715,9 +1715,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pat: &'tcx hir::Pat<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
if ty.references_error() {
|
||||
if let Err(guar) = ty.error_reported() {
|
||||
// Override the types everywhere with `err()` to avoid knock on errors.
|
||||
let err = self.tcx.ty_error();
|
||||
let err = self.tcx.ty_error_with_guaranteed(guar);
|
||||
self.write_ty(hir_id, err);
|
||||
self.write_ty(pat.hir_id, err);
|
||||
let local_ty = LocalTy { decl_ty: err, revealed_ty: err };
|
||||
@ -1746,7 +1746,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let result = self
|
||||
.astconv()
|
||||
.associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true);
|
||||
let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
|
||||
let ty = result
|
||||
.map(|(ty, _, _)| ty)
|
||||
.unwrap_or_else(|guar| self.tcx().ty_error_with_guaranteed(guar));
|
||||
let ty = self.handle_raw_ty(path_span, ty);
|
||||
let result = result.map(|(_, kind, def_id)| (kind, def_id));
|
||||
|
||||
|
@ -631,7 +631,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
Err(errors) => {
|
||||
let actual = self.resolve_vars_if_possible(operand_ty);
|
||||
if !actual.references_error() {
|
||||
let guar = actual.error_reported().err().unwrap_or_else(|| {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
ex.span,
|
||||
@ -701,9 +701,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
self.tcx.ty_error()
|
||||
err.emit()
|
||||
});
|
||||
self.tcx.ty_error_with_guaranteed(guar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,8 +475,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) {
|
||||
// There exists a side that didn't meet our criteria that the end-point
|
||||
// be of a numeric or char type, as checked in `calc_side` above.
|
||||
self.emit_err_pat_range(span, lhs, rhs);
|
||||
return self.tcx.ty_error();
|
||||
let guar = self.emit_err_pat_range(span, lhs, rhs);
|
||||
return self.tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
|
||||
// Unify each side with `expected`.
|
||||
@ -511,8 +511,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let Some((ref mut fail, _, _)) = rhs {
|
||||
*fail = true;
|
||||
}
|
||||
self.emit_err_pat_range(span, lhs, rhs);
|
||||
return self.tcx.ty_error();
|
||||
let guar = self.emit_err_pat_range(span, lhs, rhs);
|
||||
return self.tcx.ty_error_with_guaranteed(guar);
|
||||
}
|
||||
ty
|
||||
}
|
||||
@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span: Span,
|
||||
lhs: Option<(bool, Ty<'tcx>, Span)>,
|
||||
rhs: Option<(bool, Ty<'tcx>, Span)>,
|
||||
) {
|
||||
) -> ErrorGuaranteed {
|
||||
let span = match (lhs, rhs) {
|
||||
(Some((true, ..)), Some((true, ..))) => span,
|
||||
(Some((true, _, sp)), _) => sp,
|
||||
@ -573,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
type between two end-points, you can use a guard.",
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn check_pat_ident(
|
||||
@ -807,29 +807,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat<'_>) -> bool {
|
||||
pub fn check_dereferenceable(
|
||||
&self,
|
||||
span: Span,
|
||||
expected: Ty<'tcx>,
|
||||
inner: &Pat<'_>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
if let PatKind::Binding(..) = inner.kind
|
||||
&& let Some(mt) = self.shallow_resolve(expected).builtin_deref(true)
|
||||
&& let ty::Dynamic(..) = mt.ty.kind()
|
||||
{
|
||||
// This is "x = SomeTrait" being reduced from
|
||||
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
|
||||
let type_str = self.ty_to_string(expected);
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0033,
|
||||
"type `{}` cannot be dereferenced",
|
||||
type_str
|
||||
);
|
||||
err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
|
||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
|
||||
}
|
||||
err.emit();
|
||||
return false;
|
||||
}
|
||||
true
|
||||
// This is "x = SomeTrait" being reduced from
|
||||
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
|
||||
let type_str = self.ty_to_string(expected);
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0033,
|
||||
"type `{}` cannot be dereferenced",
|
||||
type_str
|
||||
);
|
||||
err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
|
||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
|
||||
}
|
||||
return Err(err.emit());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_pat_struct(
|
||||
@ -843,13 +847,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
// Resolve the path and check the definition for errors.
|
||||
let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else {
|
||||
let err = self.tcx.ty_error();
|
||||
for field in fields {
|
||||
let ti = ti;
|
||||
self.check_pat(field.pat, err, def_bm, ti);
|
||||
let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) {
|
||||
Ok(data) => data,
|
||||
Err(guar) => {
|
||||
let err = self.tcx.ty_error_with_guaranteed(guar);
|
||||
for field in fields {
|
||||
let ti = ti;
|
||||
self.check_pat(field.pat, err, def_bm, ti);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
return err;
|
||||
};
|
||||
|
||||
// Type-check the path.
|
||||
@ -1349,9 +1356,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ident = tcx.adjust_ident(field.ident, variant.def_id);
|
||||
let field_ty = match used_fields.entry(ident) {
|
||||
Occupied(occupied) => {
|
||||
self.error_field_already_bound(span, field.ident, *occupied.get());
|
||||
no_field_errors = false;
|
||||
tcx.ty_error()
|
||||
let guar = self.error_field_already_bound(span, field.ident, *occupied.get());
|
||||
tcx.ty_error_with_guaranteed(guar)
|
||||
}
|
||||
Vacant(vacant) => {
|
||||
vacant.insert(span);
|
||||
@ -1536,7 +1543,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span) {
|
||||
fn error_field_already_bound(
|
||||
&self,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
other_field: Span,
|
||||
) -> ErrorGuaranteed {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
@ -1546,7 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
)
|
||||
.span_label(span, format!("multiple uses of `{ident}` in pattern"))
|
||||
.span_label(other_field, format!("first use of `{ident}`"))
|
||||
.emit();
|
||||
.emit()
|
||||
}
|
||||
|
||||
fn error_inexistent_fields(
|
||||
@ -1919,19 +1931,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, inner) {
|
||||
// Here, `demand::subtype` is good enough, but I don't
|
||||
// think any errors can be introduced by using `demand::eqtype`.
|
||||
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: inner.span,
|
||||
});
|
||||
let box_ty = tcx.mk_box(inner_ty);
|
||||
self.demand_eqtype_pat(span, expected, box_ty, ti);
|
||||
(box_ty, inner_ty)
|
||||
} else {
|
||||
let err = tcx.ty_error();
|
||||
(err, err)
|
||||
let (box_ty, inner_ty) = match self.check_dereferenceable(span, expected, inner) {
|
||||
Ok(()) => {
|
||||
// Here, `demand::subtype` is good enough, but I don't
|
||||
// think any errors can be introduced by using `demand::eqtype`.
|
||||
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: inner.span,
|
||||
});
|
||||
let box_ty = tcx.mk_box(inner_ty);
|
||||
self.demand_eqtype_pat(span, expected, box_ty, ti);
|
||||
(box_ty, inner_ty)
|
||||
}
|
||||
Err(guar) => {
|
||||
let err = tcx.ty_error_with_guaranteed(guar);
|
||||
(err, err)
|
||||
}
|
||||
};
|
||||
self.check_pat(inner, inner_ty, def_bm, ti);
|
||||
box_ty
|
||||
@ -1949,37 +1964,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let expected = self.shallow_resolve(expected);
|
||||
let (ref_ty, inner_ty) = if self.check_dereferenceable(pat.span, expected, inner) {
|
||||
// `demand::subtype` would be good enough, but using `eqtype` turns
|
||||
// out to be equally general. See (note_1) for details.
|
||||
let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) {
|
||||
Ok(()) => {
|
||||
// `demand::subtype` would be good enough, but using `eqtype` turns
|
||||
// out to be equally general. See (note_1) for details.
|
||||
|
||||
// Take region, inner-type from expected type if we can,
|
||||
// to avoid creating needless variables. This also helps with
|
||||
// the bad interactions of the given hack detailed in (note_1).
|
||||
debug!("check_pat_ref: expected={:?}", expected);
|
||||
match *expected.kind() {
|
||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
|
||||
_ => {
|
||||
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: inner.span,
|
||||
});
|
||||
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
|
||||
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
|
||||
let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti);
|
||||
// Take region, inner-type from expected type if we can,
|
||||
// to avoid creating needless variables. This also helps with
|
||||
// the bad interactions of the given hack detailed in (note_1).
|
||||
debug!("check_pat_ref: expected={:?}", expected);
|
||||
match *expected.kind() {
|
||||
ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
|
||||
_ => {
|
||||
let inner_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: inner.span,
|
||||
});
|
||||
let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
|
||||
debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
|
||||
let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti);
|
||||
|
||||
// Look for a case like `fn foo(&foo: u32)` and suggest
|
||||
// `fn foo(foo: &u32)`
|
||||
if let Some(mut err) = err {
|
||||
self.borrow_pat_suggestion(&mut err, pat);
|
||||
err.emit();
|
||||
// Look for a case like `fn foo(&foo: u32)` and suggest
|
||||
// `fn foo(foo: &u32)`
|
||||
if let Some(mut err) = err {
|
||||
self.borrow_pat_suggestion(&mut err, pat);
|
||||
err.emit();
|
||||
}
|
||||
(ref_ty, inner_ty)
|
||||
}
|
||||
(ref_ty, inner_ty)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let err = tcx.ty_error();
|
||||
(err, err)
|
||||
Err(guar) => {
|
||||
let err = tcx.ty_error_with_guaranteed(guar);
|
||||
(err, err)
|
||||
}
|
||||
};
|
||||
self.check_pat(inner, inner_ty, def_bm, ti);
|
||||
ref_ty
|
||||
@ -2027,10 +2045,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::Slice(element_ty) => (element_ty, Some(expected), expected),
|
||||
// The expected type must be an array or slice, but was neither, so error.
|
||||
_ => {
|
||||
if !expected.references_error() {
|
||||
self.error_expected_array_or_slice(span, expected, ti);
|
||||
}
|
||||
let err = self.tcx.ty_error();
|
||||
let guar = expected
|
||||
.error_reported()
|
||||
.err()
|
||||
.unwrap_or_else(|| self.error_expected_array_or_slice(span, expected, ti));
|
||||
let err = self.tcx.ty_error_with_guaranteed(guar);
|
||||
(err, Some(err), err)
|
||||
}
|
||||
};
|
||||
@ -2063,7 +2082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
len: ty::Const<'tcx>,
|
||||
min_len: u64,
|
||||
) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
|
||||
if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) {
|
||||
let guar = if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) {
|
||||
// Now we know the length...
|
||||
if slice.is_none() {
|
||||
// ...and since there is no variable-length pattern,
|
||||
@ -2073,7 +2092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return (None, arr_ty);
|
||||
}
|
||||
|
||||
self.error_scrutinee_inconsistent_length(span, min_len, len);
|
||||
self.error_scrutinee_inconsistent_length(span, min_len, len)
|
||||
} else if let Some(pat_len) = len.checked_sub(min_len) {
|
||||
// The variable-length pattern was there,
|
||||
// so it has an array type with the remaining elements left as its size...
|
||||
@ -2081,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
// ...however, in this case, there were no remaining elements.
|
||||
// That is, the slice pattern requires more than the array type offers.
|
||||
self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len);
|
||||
self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len)
|
||||
}
|
||||
} else if slice.is_none() {
|
||||
// We have a pattern with a fixed length,
|
||||
@ -2093,14 +2112,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// We have a variable-length pattern and don't know the array length.
|
||||
// This happens if we have e.g.,
|
||||
// `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
|
||||
self.error_scrutinee_unfixed_length(span);
|
||||
}
|
||||
self.error_scrutinee_unfixed_length(span)
|
||||
};
|
||||
|
||||
// If we get here, we must have emitted an error.
|
||||
(Some(self.tcx.ty_error()), arr_ty)
|
||||
(Some(self.tcx.ty_error_with_guaranteed(guar)), arr_ty)
|
||||
}
|
||||
|
||||
fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
|
||||
fn error_scrutinee_inconsistent_length(
|
||||
&self,
|
||||
span: Span,
|
||||
min_len: u64,
|
||||
size: u64,
|
||||
) -> ErrorGuaranteed {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
@ -2111,10 +2135,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
size,
|
||||
)
|
||||
.span_label(span, format!("expected {} element{}", size, pluralize!(size)))
|
||||
.emit();
|
||||
.emit()
|
||||
}
|
||||
|
||||
fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
|
||||
fn error_scrutinee_with_rest_inconsistent_length(
|
||||
&self,
|
||||
span: Span,
|
||||
min_len: u64,
|
||||
size: u64,
|
||||
) -> ErrorGuaranteed {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
@ -2128,20 +2157,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span,
|
||||
format!("pattern cannot match array of {} element{}", size, pluralize!(size),),
|
||||
)
|
||||
.emit();
|
||||
.emit()
|
||||
}
|
||||
|
||||
fn error_scrutinee_unfixed_length(&self, span: Span) {
|
||||
fn error_scrutinee_unfixed_length(&self, span: Span) -> ErrorGuaranteed {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0730,
|
||||
"cannot pattern-match on an array without a fixed length",
|
||||
)
|
||||
.emit();
|
||||
.emit()
|
||||
}
|
||||
|
||||
fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
|
||||
fn error_expected_array_or_slice(
|
||||
&self,
|
||||
span: Span,
|
||||
expected_ty: Ty<'tcx>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> ErrorGuaranteed {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
@ -2185,7 +2219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`"));
|
||||
err.emit();
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) {
|
||||
|
@ -35,6 +35,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
|
||||
@ -1358,7 +1359,7 @@ pub struct OpaqueHiddenType<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> OpaqueHiddenType<'tcx> {
|
||||
pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
|
||||
pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) -> ErrorGuaranteed {
|
||||
// Found different concrete types for the opaque type.
|
||||
let sub_diag = if self.span == other.span {
|
||||
TypeMismatchReason::ConflictType { span: self.span }
|
||||
@ -1370,7 +1371,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
|
||||
other_ty: other.ty,
|
||||
other_span: other.span,
|
||||
sub: sub_diag,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
|
@ -639,7 +639,7 @@ fn construct_error(
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||
let generator_kind = tcx.generator_kind(def);
|
||||
|
||||
let ty = tcx.ty_error();
|
||||
let ty = tcx.ty_error_with_guaranteed(err);
|
||||
let num_params = match body_owner_kind {
|
||||
hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(),
|
||||
hir::BodyOwnerKind::Closure => {
|
||||
|
@ -1213,8 +1213,8 @@ struct Progress<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> Progress<'tcx> {
|
||||
fn error(tcx: TyCtxt<'tcx>) -> Self {
|
||||
Progress { term: tcx.ty_error().into(), obligations: vec![] }
|
||||
fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
|
||||
Progress { term: tcx.ty_error_with_guaranteed(guar).into(), obligations: vec![] }
|
||||
}
|
||||
|
||||
fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self {
|
||||
@ -1240,8 +1240,8 @@ fn project<'cx, 'tcx>(
|
||||
)));
|
||||
}
|
||||
|
||||
if obligation.predicate.references_error() {
|
||||
return Ok(Projected::Progress(Progress::error(selcx.tcx())));
|
||||
if let Err(guar) = obligation.predicate.error_reported() {
|
||||
return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar)));
|
||||
}
|
||||
|
||||
let mut candidates = ProjectionCandidateSet::None;
|
||||
@ -2097,8 +2097,9 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
|
||||
|
||||
let param_env = obligation.param_env;
|
||||
let Ok(assoc_ty) = specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) else {
|
||||
return Progress { term: tcx.ty_error().into(), obligations: nested };
|
||||
let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
|
||||
Ok(assoc_ty) => assoc_ty,
|
||||
Err(guar) => return Progress::error(tcx, guar),
|
||||
};
|
||||
|
||||
if !assoc_ty.item.defaultness(tcx).has_value() {
|
||||
@ -2194,8 +2195,9 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
let mut obligations = data.nested;
|
||||
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
|
||||
let Ok(leaf_def) = specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) else {
|
||||
return Progress { term: tcx.ty_error().into(), obligations };
|
||||
let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) {
|
||||
Ok(assoc_ty) => assoc_ty,
|
||||
Err(guar) => return Progress::error(tcx, guar),
|
||||
};
|
||||
if !leaf_def.item.defaultness(tcx).has_value() {
|
||||
return Progress { term: tcx.ty_error().into(), obligations };
|
||||
@ -2269,7 +2271,10 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
obligation.recursion_depth + 1,
|
||||
tcx.bound_return_position_impl_trait_in_trait_tys(impl_fn_def_id)
|
||||
.map_bound(|tys| {
|
||||
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id])
|
||||
tys.map_or_else(
|
||||
|guar| tcx.ty_error_with_guaranteed(guar),
|
||||
|tys| tys[&obligation.predicate.def_id],
|
||||
)
|
||||
})
|
||||
.subst(tcx, impl_fn_substs),
|
||||
&mut obligations,
|
||||
|
@ -2443,7 +2443,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// the placeholder trait ref may fail due the Generalizer relation
|
||||
// raising a CyclicalTy error due to a sub_root_var relation
|
||||
// for a variable being generalized...
|
||||
self.infcx.tcx.sess.delay_span_bug(
|
||||
let guar = self.infcx.tcx.sess.delay_span_bug(
|
||||
obligation.cause.span,
|
||||
&format!(
|
||||
"Impl {:?} was matchable against {:?} but now is not",
|
||||
@ -2451,7 +2451,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
),
|
||||
);
|
||||
let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
|
||||
let err = self.tcx().ty_error();
|
||||
let err = self.tcx().ty_error_with_guaranteed(guar);
|
||||
let value = value.fold_with(&mut BottomUpFolder {
|
||||
tcx: self.tcx(),
|
||||
ty_op: |_| err,
|
||||
|
Loading…
x
Reference in New Issue
Block a user