|
1 | 1 | use std::assert_matches::assert_matches;
|
2 | 2 |
|
3 |
| -use hir::{HirId, Node}; |
| 3 | +use hir::Node; |
4 | 4 | use rustc_data_structures::fx::FxIndexSet;
|
5 | 5 | use rustc_hir as hir;
|
6 | 6 | use rustc_hir::def::DefKind;
|
7 | 7 | use rustc_hir::def_id::{DefId, LocalDefId};
|
8 |
| -use rustc_hir::intravisit::{self, Visitor}; |
9 |
| -use rustc_middle::ty::{self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, Upcast}; |
| 8 | +use rustc_middle::ty::{ |
| 9 | + self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, |
| 10 | +}; |
10 | 11 | use rustc_middle::{bug, span_bug};
|
11 | 12 | use rustc_span::symbol::Ident;
|
12 | 13 | use rustc_span::{DUMMY_SP, Span};
|
@@ -305,7 +306,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
305 | 306 | }
|
306 | 307 |
|
307 | 308 | if tcx.features().generic_const_exprs() {
|
308 |
| - predicates.extend(const_evaluatable_predicates_of(tcx, def_id)); |
| 309 | + predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates)); |
309 | 310 | }
|
310 | 311 |
|
311 | 312 | let mut predicates: Vec<_> = predicates.into_iter().collect();
|
@@ -369,61 +370,80 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
369 | 370 | }
|
370 | 371 | }
|
371 | 372 |
|
372 |
| -fn const_evaluatable_predicates_of( |
373 |
| - tcx: TyCtxt<'_>, |
| 373 | +#[instrument(level = "debug", skip(tcx, predicates), ret)] |
| 374 | +fn const_evaluatable_predicates_of<'tcx>( |
| 375 | + tcx: TyCtxt<'tcx>, |
374 | 376 | def_id: LocalDefId,
|
375 |
| -) -> FxIndexSet<(ty::Clause<'_>, Span)> { |
| 377 | + predicates: &FxIndexSet<(ty::Clause<'tcx>, Span)>, |
| 378 | +) -> FxIndexSet<(ty::Clause<'tcx>, Span)> { |
376 | 379 | struct ConstCollector<'tcx> {
|
377 | 380 | tcx: TyCtxt<'tcx>,
|
378 | 381 | preds: FxIndexSet<(ty::Clause<'tcx>, Span)>,
|
379 | 382 | }
|
380 | 383 |
|
381 |
| - impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> { |
382 |
| - fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { |
383 |
| - let ct = ty::Const::from_anon_const(self.tcx, c.def_id); |
384 |
| - if let ty::ConstKind::Unevaluated(_) = ct.kind() { |
385 |
| - let span = self.tcx.def_span(c.def_id); |
386 |
| - self.preds.insert((ty::ClauseKind::ConstEvaluatable(ct).upcast(self.tcx), span)); |
387 |
| - } |
388 |
| - } |
| 384 | + fn is_const_param_default(tcx: TyCtxt<'_>, def: LocalDefId) -> bool { |
| 385 | + let hir_id = tcx.local_def_id_to_hir_id(def); |
| 386 | + let (_, parent_node) = tcx |
| 387 | + .hir() |
| 388 | + .parent_iter(hir_id) |
| 389 | + .skip_while(|(_, n)| matches!(n, Node::ConstArg(..))) |
| 390 | + .next() |
| 391 | + .unwrap(); |
| 392 | + matches!( |
| 393 | + parent_node, |
| 394 | + Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { .. }, .. }) |
| 395 | + ) |
| 396 | + } |
389 | 397 |
|
390 |
| - fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::ConstArg<'tcx>) { |
391 |
| - // Do not look into const param defaults, |
392 |
| - // these get checked when they are actually instantiated. |
393 |
| - // |
394 |
| - // We do not want the following to error: |
395 |
| - // |
396 |
| - // struct Foo<const N: usize, const M: usize = { N + 1 }>; |
397 |
| - // struct Bar<const N: usize>(Foo<N, 3>); |
| 398 | + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstCollector<'tcx> { |
| 399 | + fn visit_const(&mut self, c: ty::Const<'tcx>) { |
| 400 | + if let ty::ConstKind::Unevaluated(uv) = c.kind() { |
| 401 | + if is_const_param_default(self.tcx, uv.def.expect_local()) { |
| 402 | + // Do not look into const param defaults, |
| 403 | + // these get checked when they are actually instantiated. |
| 404 | + // |
| 405 | + // We do not want the following to error: |
| 406 | + // |
| 407 | + // struct Foo<const N: usize, const M: usize = { N + 1 }>; |
| 408 | + // struct Bar<const N: usize>(Foo<N, 3>); |
| 409 | + return; |
| 410 | + } |
| 411 | + |
| 412 | + let span = self.tcx.def_span(uv.def); |
| 413 | + self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span)); |
| 414 | + } |
398 | 415 | }
|
399 | 416 | }
|
400 | 417 |
|
401 | 418 | let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
402 | 419 | let node = tcx.hir_node(hir_id);
|
403 | 420 |
|
404 | 421 | let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
|
| 422 | + |
| 423 | + for (clause, _sp) in predicates { |
| 424 | + clause.visit_with(&mut collector); |
| 425 | + } |
| 426 | + |
405 | 427 | if let hir::Node::Item(item) = node
|
406 |
| - && let hir::ItemKind::Impl(impl_) = item.kind |
| 428 | + && let hir::ItemKind::Impl(_) = item.kind |
407 | 429 | {
|
408 |
| - if let Some(of_trait) = &impl_.of_trait { |
409 |
| - debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); |
410 |
| - collector.visit_trait_ref(of_trait); |
| 430 | + if let Some(of_trait) = tcx.impl_trait_ref(def_id) { |
| 431 | + debug!("visit impl trait_ref"); |
| 432 | + of_trait.instantiate_identity().visit_with(&mut collector); |
411 | 433 | }
|
412 | 434 |
|
413 |
| - debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id); |
414 |
| - collector.visit_ty(impl_.self_ty); |
415 |
| - } |
416 |
| - |
417 |
| - if let Some(generics) = node.generics() { |
418 |
| - debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id); |
419 |
| - collector.visit_generics(generics); |
| 435 | + debug!("visit self_ty"); |
| 436 | + let self_ty = tcx.type_of(def_id); |
| 437 | + self_ty.instantiate_identity().visit_with(&mut collector); |
420 | 438 | }
|
421 | 439 |
|
422 |
| - if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) { |
423 |
| - debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id); |
424 |
| - collector.visit_fn_decl(fn_sig.decl); |
| 440 | + if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) { |
| 441 | + debug!("visit fn sig"); |
| 442 | + let fn_sig = tcx.fn_sig(def_id); |
| 443 | + let fn_sig = fn_sig.instantiate_identity(); |
| 444 | + debug!(?fn_sig); |
| 445 | + fn_sig.visit_with(&mut collector); |
425 | 446 | }
|
426 |
| - debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds); |
427 | 447 |
|
428 | 448 | collector.preds
|
429 | 449 | }
|
|
0 commit comments