diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/at.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 81 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/astconv/mod.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect/type_of.rs | 64 |
8 files changed, 92 insertions, 110 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a0ed72c9e9e..68fdbaa6aa0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2165,6 +2165,12 @@ impl TypeBinding<'_> { _ => panic!("expected equality type binding for parenthesized generic args"), } } + pub fn opt_const(&self) -> Option<&'_ AnonConst> { + match self.kind { + TypeBindingKind::Equality { term: Term::Const(ref c) } => Some(c), + _ => None, + } + } } #[derive(Debug)] diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index aa74a92ad1f..147061dafeb 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -288,13 +288,21 @@ impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> { impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> { fn to_trace( - _: TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, cause: &ObligationCause<'tcx>, a_is_expected: bool, a: Self, b: Self, ) -> TypeTrace<'tcx> { - TypeTrace { cause: cause.clone(), values: Terms(ExpectedFound::new(a_is_expected, a, b)) } + match (a, b) { + (ty::Term::Ty(a), ty::Term::Ty(b)) => { + ToTrace::to_trace(tcx, cause, a_is_expected, a, b) + } + (ty::Term::Const(a), ty::Term::Const(b)) => { + ToTrace::to_trace(tcx, cause, a_is_expected, a, b) + } + (_, _) => todo!(), + } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 24a5f55d53c..1eb8190bd7d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2127,7 +2127,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::Types(exp_found) => self.expected_found_str_ty(exp_found), infer::Regions(exp_found) => self.expected_found_str(exp_found), infer::Consts(exp_found) => self.expected_found_str(exp_found), - infer::Terms(exp_found) => self.expected_found_str(exp_found), infer::TraitRefs(exp_found) => { let pretty_exp_found = ty::error::ExpectedFound { expected: exp_found.expected.print_only_trait_path(), diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 330c99f6073..266eec08ceb 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -371,7 +371,6 @@ pub enum ValuePairs<'tcx> { Types(ExpectedFound<Ty<'tcx>>), Regions(ExpectedFound<ty::Region<'tcx>>), Consts(ExpectedFound<&'tcx ty::Const<'tcx>>), - Terms(ExpectedFound<ty::Term<'tcx>>), TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>), PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>), } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f16601dd08e..d06e8496f59 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1356,11 +1356,26 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { normalized_ty, data.term, ) { - values = Some(infer::ValuePairs::Terms(ExpectedFound::new( - is_normalized_ty_expected, - normalized_ty, - data.term, - ))); + values = Some(match (normalized_ty, data.term) { + (ty::Term::Ty(normalized_ty), ty::Term::Ty(ty)) => { + infer::ValuePairs::Types(ExpectedFound::new( + is_normalized_ty_expected, + normalized_ty, + ty, + )) + } + (ty::Term::Const(normalized_ct), ty::Term::Const(ct)) => { + infer::ValuePairs::Consts(ExpectedFound::new( + is_normalized_ty_expected, + normalized_ct, + ct, + )) + } + (_, _) => span_bug!( + obligation.cause.span, + "found const or type where other expected" + ), + }); err_buf = error; err = &err_buf; } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 11cde60f075..bad4ee30424 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -199,61 +199,30 @@ fn project_and_unify_type<'cx, 'tcx>( let mut obligations = vec![]; let infcx = selcx.infcx(); - match obligation.predicate.term { - ty::Term::Ty(obligation_pred_ty) => { - let normalized_ty = match opt_normalize_projection_type( - selcx, - obligation.param_env, - obligation.predicate.projection_ty, - obligation.cause.clone(), - obligation.recursion_depth, - &mut obligations, - ) { - Ok(Some(n)) => n.ty().unwrap(), - Ok(None) => return Ok(Ok(None)), - Err(InProgress) => return Ok(Err(InProgress)), - }; - debug!(?normalized_ty, ?obligations, "project_and_unify_type result"); - match infcx - .at(&obligation.cause, obligation.param_env) - .eq(normalized_ty, obligation_pred_ty) - { - Ok(InferOk { obligations: inferred_obligations, value: () }) => { - obligations.extend(inferred_obligations); - Ok(Ok(Some(obligations))) - } - Err(err) => { - debug!("project_and_unify_type: equating types encountered error {:?}", err); - Err(MismatchedProjectionTypes { err }) - } - } + let normalized = match opt_normalize_projection_type( + selcx, + obligation.param_env, + obligation.predicate.projection_ty, + obligation.cause.clone(), + obligation.recursion_depth, + &mut obligations, + ) { + Ok(Some(n)) => n, + Ok(None) => return Ok(Ok(None)), + Err(InProgress) => return Ok(Err(InProgress)), + }; + debug!(?normalized, ?obligations, "project_and_unify_type result"); + match infcx + .at(&obligation.cause, obligation.param_env) + .eq(normalized, obligation.predicate.term) + { + Ok(InferOk { obligations: inferred_obligations, value: () }) => { + obligations.extend(inferred_obligations); + Ok(Ok(Some(obligations))) } - ty::Term::Const(obligation_pred_const) => { - let normalized_const = match opt_normalize_projection_type( - selcx, - obligation.param_env, - obligation.predicate.projection_ty, - obligation.cause.clone(), - obligation.recursion_depth, - &mut obligations, - ) { - Ok(Some(n)) => n.ct().unwrap(), - Ok(None) => return Ok(Ok(None)), - Err(InProgress) => return Ok(Err(InProgress)), - }; - match infcx - .at(&obligation.cause, obligation.param_env) - .eq(normalized_const, obligation_pred_const) - { - Ok(InferOk { obligations: inferred_obligations, value: () }) => { - obligations.extend(inferred_obligations); - Ok(Ok(Some(obligations))) - } - Err(err) => { - debug!("project_and_unify_type: equating consts encountered error {:?}", err); - Err(MismatchedProjectionTypes { err }) - } - } + Err(err) => { + debug!("project_and_unify_type: equating types encountered error {:?}", err); + Err(MismatchedProjectionTypes { err }) } } } @@ -934,6 +903,8 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( // created (and hence the new ones will quickly be // discarded as duplicated). But when doing trait // evaluation this is not the case, and dropping the trait + // evaluations can causes ICEs (e.g., #43132). + debug!(?ty, "found normalized ty"); obligations.extend(ty.obligations); return Ok(Some(ty.value)); } @@ -1127,6 +1098,8 @@ fn project<'cx, 'tcx>( Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate))) } ProjectionCandidateSet::None => Ok(Projected::NoProgress( + // FIXME(associated_const_generics): this may need to change in the future? + // need to investigate whether or not this is fine. selcx .tcx() .mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 06d472214e4..5eb9664e1d7 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1244,17 +1244,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // the "projection predicate" for: // // `<T as Iterator>::Item = u32` - let def_kind = tcx.def_kind(projection_ty.skip_binder().item_def_id); + let assoc_item_def_id = projection_ty.skip_binder().item_def_id; + let def_kind = tcx.def_kind(assoc_item_def_id); match (def_kind, term) { (hir::def::DefKind::AssocTy, ty::Term::Ty(_)) | (hir::def::DefKind::AssocConst, ty::Term::Const(_)) => (), (_, _) => { + let got = if let ty::Term::Ty(_) = term { "type" } else { "const" }; + let expected = def_kind.descr(assoc_item_def_id); tcx.sess .struct_span_err( binding.span, - "type/const mismatch in equality bind of associated field", + &format!("mismatch in bind of {expected}, got {got}"), + ) + .span_note( + tcx.def_span(assoc_item_def_id), + &format!("{expected} defined here does not match {got}"), ) - .span_label(binding.span, "type/const Mismatch") .emit(); } } diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 63a8cab3def..7990c14f773 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -161,40 +161,26 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // We've encountered an `AnonConst` in some path, so we need to // figure out which generic parameter it corresponds to and return // the relevant type. - let filtered = path - .segments - .iter() - .filter_map(|seg| seg.args.map(|args| (args.args, seg))) - .find_map(|(args, seg)| { - args.iter() - .filter(|arg| arg.is_ty_or_const()) - .position(|arg| arg.id() == hir_id) - .map(|index| (index, seg)) - }); - // FIXME(associated_const_equality): recursively search through the bindings instead - // of just top level. + let filtered = path.segments.iter().find_map(|seg| { + seg.args? + .args + .iter() + .filter(|arg| arg.is_ty_or_const()) + .position(|arg| arg.id() == hir_id) + .map(|index| (index, seg)) + }); + // FIXME(associated_const_generics): can we blend this with iteration above? let (arg_index, segment) = match filtered { None => { - let binding_filtered = path - .segments - .iter() - .filter_map(|seg| seg.args.map(|args| (args.bindings, seg))) - .find_map(|(bindings, seg)| { - bindings - .iter() - .filter_map(|binding| { - if let hir::TypeBindingKind::Equality { term: Term::Const(c) } = - binding.kind - { - Some(c) - } else { - None - } - }) - .position(|ct| ct.hir_id == hir_id) - .map(|idx| (idx, seg)) - }); + let binding_filtered = path.segments.iter().find_map(|seg| { + seg.args? + .bindings + .iter() + .filter_map(TypeBinding::opt_const) + .position(|ct| ct.hir_id == hir_id) + .map(|idx| (idx, seg)) + }); match binding_filtered { Some(inner) => inner, None => { @@ -518,20 +504,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { path .segments .iter() - .filter_map(|seg| seg.args.map(|args| (args.bindings, seg))) - .find_map(|(bindings, seg)| { - bindings + .find_map(|seg| { + seg.args?.bindings .iter() - .filter_map(|binding| { - if let hir::TypeBindingKind::Equality { term: Term::Const(c) } = - binding.kind - { - Some((binding, c)) - } else { - None - } - }) - .find_map(|(binding, ct)| if ct.hir_id == hir_id { + .find_map(|binding| if binding.opt_const()?.hir_id == hir_id { Some((binding, seg)) } else { None |
