Skip to content

Commit c7dbe7a

Browse files
committed
Auto merge of rust-lang#88881 - Manishearth:rollup-alohfwx, r=Manishearth
Rollup of 7 pull requests Successful merges: - rust-lang#88336 ( Detect stricter constraints on gats where clauses in impls vs trait) - rust-lang#88677 (rustc: Remove local variable IDs from `Export`s) - rust-lang#88699 (Remove extra unshallow from cherry-pick checker) - rust-lang#88709 (generic_const_exprs: use thir for abstract consts instead of mir) - rust-lang#88711 (Rework DepthFirstSearch API) - rust-lang#88810 (rustdoc: Cleanup `clean` part 1) - rust-lang#88813 (explicitly link to external `ena` docs) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9ef27bf + 146aee6 commit c7dbe7a

File tree

67 files changed

+688
-576
lines changed

Some content is hidden

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

67 files changed

+688
-576
lines changed

compiler/rustc_data_structures/src/graph/iterate/mod.rs

+52-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,58 @@ impl<G> DepthFirstSearch<'graph, G>
8383
where
8484
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
8585
{
86-
pub fn new(graph: &'graph G, start_node: G::Node) -> Self {
87-
Self { graph, stack: vec![start_node], visited: BitSet::new_empty(graph.num_nodes()) }
86+
pub fn new(graph: &'graph G) -> Self {
87+
Self { graph, stack: vec![], visited: BitSet::new_empty(graph.num_nodes()) }
88+
}
89+
90+
/// Version of `push_start_node` that is convenient for chained
91+
/// use.
92+
pub fn with_start_node(mut self, start_node: G::Node) -> Self {
93+
self.push_start_node(start_node);
94+
self
95+
}
96+
97+
/// Pushes another start node onto the stack. If the node
98+
/// has not already been visited, then you will be able to
99+
/// walk its successors (and so forth) after the current
100+
/// contents of the stack are drained. If multiple start nodes
101+
/// are added into the walk, then their mutual successors
102+
/// will all be walked. You can use this method once the
103+
/// iterator has been completely drained to add additional
104+
/// start nodes.
105+
pub fn push_start_node(&mut self, start_node: G::Node) {
106+
if self.visited.insert(start_node) {
107+
self.stack.push(start_node);
108+
}
109+
}
110+
111+
/// Searches all nodes reachable from the current start nodes.
112+
/// This is equivalent to just invoke `next` repeatedly until
113+
/// you get a `None` result.
114+
pub fn complete_search(&mut self) {
115+
while let Some(_) = self.next() {}
116+
}
117+
118+
/// Returns true if node has been visited thus far.
119+
/// A node is considered "visited" once it is pushed
120+
/// onto the internal stack; it may not yet have been yielded
121+
/// from the iterator. This method is best used after
122+
/// the iterator is completely drained.
123+
pub fn visited(&self, node: G::Node) -> bool {
124+
self.visited.contains(node)
125+
}
126+
}
127+
128+
impl<G> std::fmt::Debug for DepthFirstSearch<'_, G>
129+
where
130+
G: ?Sized + DirectedGraph + WithNumNodes + WithSuccessors,
131+
{
132+
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133+
let mut f = fmt.debug_set();
134+
for n in self.visited.iter() {
135+
f.entry(&n);
136+
}
137+
f.finish()
88138
}
89139
}
90140

compiler/rustc_data_structures/src/graph/iterate/tests.rs

+16
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,19 @@ fn is_cyclic() {
2020
assert!(!is_cyclic(&diamond_acyclic));
2121
assert!(is_cyclic(&diamond_cyclic));
2222
}
23+
24+
#[test]
25+
fn dfs() {
26+
let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]);
27+
28+
let result: Vec<usize> = DepthFirstSearch::new(&graph).with_start_node(0).collect();
29+
assert_eq!(result, vec![0, 2, 3, 1]);
30+
}
31+
32+
#[test]
33+
fn dfs_debug() {
34+
let graph = TestGraph::new(0, &[(0, 1), (0, 2), (1, 3), (2, 3), (3, 0)]);
35+
let mut dfs = DepthFirstSearch::new(&graph).with_start_node(0);
36+
dfs.complete_search();
37+
assert_eq!(format!("{{0, 1, 2, 3}}"), format!("{:?}", dfs));
38+
}

compiler/rustc_data_structures/src/graph/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ where
3232
where
3333
Self: WithNumNodes,
3434
{
35-
iterate::DepthFirstSearch::new(self, from)
35+
iterate::DepthFirstSearch::new(self).with_start_node(from)
3636
}
3737
}
3838

compiler/rustc_data_structures/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#![feature(iter_map_while)]
2222
#![feature(maybe_uninit_uninit_array)]
2323
#![feature(min_specialization)]
24+
#![feature(never_type)]
2425
#![feature(type_alias_impl_trait)]
2526
#![feature(new_uninit)]
2627
#![feature(nll)]

compiler/rustc_data_structures/src/stable_hasher.rs

+6
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ impl_stable_hash_via_hash!(i128);
209209
impl_stable_hash_via_hash!(char);
210210
impl_stable_hash_via_hash!(());
211211

212+
impl<CTX> HashStable<CTX> for ! {
213+
fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
214+
unreachable!()
215+
}
216+
}
217+
212218
impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
213219
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
214220
self.get().hash_stable(ctx, hasher)

compiler/rustc_hir/src/def.rs

+5
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,11 @@ impl<Id> Res<Id> {
598598
}
599599
}
600600

601+
#[track_caller]
602+
pub fn expect_non_local<OtherId>(self) -> Res<OtherId> {
603+
self.map_id(|_| panic!("unexpected `Res::Local`"))
604+
}
605+
601606
pub fn macro_kind(self) -> Option<MacroKind> {
602607
match self {
603608
Res::Def(DefKind::Macro(kind), _) => Some(kind),

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs

+58-30
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
44
use crate::infer::lexical_region_resolve::RegionResolutionError;
5-
use crate::infer::{Subtype, ValuePairs};
5+
use crate::infer::{SubregionOrigin, Subtype, ValuePairs};
66
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
77
use rustc_errors::ErrorReported;
88
use rustc_hir as hir;
@@ -11,44 +11,53 @@ use rustc_hir::def_id::DefId;
1111
use rustc_hir::intravisit::Visitor;
1212
use rustc_middle::ty::error::ExpectedFound;
1313
use rustc_middle::ty::{self, Ty, TyCtxt};
14-
use rustc_span::{MultiSpan, Span};
14+
use rustc_span::{MultiSpan, Span, Symbol};
1515

1616
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1717
/// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
1818
pub(super) fn try_report_impl_not_conforming_to_trait(&self) -> Option<ErrorReported> {
19-
if let Some(ref error) = self.error {
20-
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
21-
if let RegionResolutionError::SubSupConflict(
22-
_,
23-
var_origin,
24-
sub_origin,
25-
_sub,
26-
sup_origin,
27-
_sup,
28-
) = error.clone()
29-
{
30-
if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) =
31-
(&sup_origin, &sub_origin)
19+
let error = self.error.as_ref()?;
20+
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
21+
if let RegionResolutionError::SubSupConflict(
22+
_,
23+
var_origin,
24+
sub_origin,
25+
_sub,
26+
sup_origin,
27+
_sup,
28+
) = error.clone()
29+
{
30+
if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin) {
31+
if let (
32+
ValuePairs::Types(sub_expected_found),
33+
ValuePairs::Types(sup_expected_found),
34+
CompareImplMethodObligation { trait_item_def_id, .. },
35+
) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
3236
{
33-
if let (
34-
ValuePairs::Types(sub_expected_found),
35-
ValuePairs::Types(sup_expected_found),
36-
CompareImplMethodObligation { trait_item_def_id, .. },
37-
) = (&sub_trace.values, &sup_trace.values, &sub_trace.cause.code)
38-
{
39-
if sup_expected_found == sub_expected_found {
40-
self.emit_err(
41-
var_origin.span(),
42-
sub_expected_found.expected,
43-
sub_expected_found.found,
44-
*trait_item_def_id,
45-
);
46-
return Some(ErrorReported);
47-
}
37+
if sup_expected_found == sub_expected_found {
38+
self.emit_err(
39+
var_origin.span(),
40+
sub_expected_found.expected,
41+
sub_expected_found.found,
42+
*trait_item_def_id,
43+
);
44+
return Some(ErrorReported);
4845
}
4946
}
5047
}
5148
}
49+
if let RegionResolutionError::ConcreteFailure(origin, _, _) = error.clone() {
50+
if let SubregionOrigin::CompareImplTypeObligation {
51+
span,
52+
item_name,
53+
impl_item_def_id,
54+
trait_item_def_id,
55+
} = origin
56+
{
57+
self.emit_associated_type_err(span, item_name, impl_item_def_id, trait_item_def_id);
58+
return Some(ErrorReported);
59+
}
60+
}
5261
None
5362
}
5463

@@ -107,6 +116,25 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
107116
}
108117
err.emit();
109118
}
119+
120+
fn emit_associated_type_err(
121+
&self,
122+
span: Span,
123+
item_name: Symbol,
124+
impl_item_def_id: DefId,
125+
trait_item_def_id: DefId,
126+
) {
127+
let impl_sp = self.tcx().def_span(impl_item_def_id);
128+
let trait_sp = self.tcx().def_span(trait_item_def_id);
129+
let mut err = self
130+
.tcx()
131+
.sess
132+
.struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
133+
err.span_label(impl_sp, &format!("found"));
134+
err.span_label(trait_sp, &format!("expected"));
135+
136+
err.emit();
137+
}
110138
}
111139

112140
struct TypeParamSpanVisitor<'tcx> {

compiler/rustc_infer/src/infer/error_reporting/note.rs

+18
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9999
"...so that the definition in impl matches the definition from the trait",
100100
);
101101
}
102+
infer::CompareImplTypeObligation { span, .. } => {
103+
label_or_note(
104+
span,
105+
"...so that the definition in impl matches the definition from the trait",
106+
);
107+
}
102108
}
103109
}
104110

@@ -356,6 +362,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
356362
trait_item_def_id,
357363
&format!("`{}: {}`", sup, sub),
358364
),
365+
infer::CompareImplTypeObligation {
366+
span,
367+
item_name,
368+
impl_item_def_id,
369+
trait_item_def_id,
370+
} => self.report_extra_impl_obligation(
371+
span,
372+
item_name,
373+
impl_item_def_id,
374+
trait_item_def_id,
375+
&format!("`{}: {}`", sup, sub),
376+
),
359377
}
360378
}
361379

compiler/rustc_infer/src/infer/mod.rs

+21
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,15 @@ pub enum SubregionOrigin<'tcx> {
427427
impl_item_def_id: DefId,
428428
trait_item_def_id: DefId,
429429
},
430+
431+
/// Comparing the signature and requirements of an impl associated type
432+
/// against the containing trait
433+
CompareImplTypeObligation {
434+
span: Span,
435+
item_name: Symbol,
436+
impl_item_def_id: DefId,
437+
trait_item_def_id: DefId,
438+
},
430439
}
431440

432441
// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -1810,6 +1819,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
18101819
ReferenceOutlivesReferent(_, a) => a,
18111820
CallReturn(a) => a,
18121821
CompareImplMethodObligation { span, .. } => span,
1822+
CompareImplTypeObligation { span, .. } => span,
18131823
}
18141824
}
18151825

@@ -1833,6 +1843,17 @@ impl<'tcx> SubregionOrigin<'tcx> {
18331843
trait_item_def_id,
18341844
},
18351845

1846+
traits::ObligationCauseCode::CompareImplTypeObligation {
1847+
item_name,
1848+
impl_item_def_id,
1849+
trait_item_def_id,
1850+
} => SubregionOrigin::CompareImplTypeObligation {
1851+
span: cause.span,
1852+
item_name,
1853+
impl_item_def_id,
1854+
trait_item_def_id,
1855+
},
1856+
18361857
_ => default(),
18371858
}
18381859
}

compiler/rustc_metadata/src/rmeta/decoder.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_middle::middle::cstore::{ForeignModule, LinkagePreference, NativeLib};
2626
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
2727
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2828
use rustc_middle::mir::{self, Body, Promoted};
29+
use rustc_middle::thir;
2930
use rustc_middle::ty::codec::TyDecoder;
3031
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
3132
use rustc_serialize::{opaque, Decodable, Decoder};
@@ -541,7 +542,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
541542
}
542543
}
543544

544-
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [mir::abstract_const::Node<'tcx>] {
545+
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
545546
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
546547
ty::codec::RefDecodable::decode(d)
547548
}
@@ -1020,10 +1021,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
10201021
}
10211022

10221023
/// Iterates over each child of the given item.
1023-
fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
1024-
where
1025-
F: FnMut(Export<hir::HirId>),
1026-
{
1024+
fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) {
10271025
if let Some(data) = &self.root.proc_macro_data {
10281026
/* If we are loading as a proc macro, we want to return the view of this crate
10291027
* as a proc macro crate.
@@ -1199,14 +1197,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11991197
.decode((self, tcx))
12001198
}
12011199

1202-
fn get_mir_abstract_const(
1200+
fn get_thir_abstract_const(
12031201
&self,
12041202
tcx: TyCtxt<'tcx>,
12051203
id: DefIndex,
1206-
) -> Result<Option<&'tcx [mir::abstract_const::Node<'tcx>]>, ErrorReported> {
1204+
) -> Result<Option<&'tcx [thir::abstract_const::Node<'tcx>]>, ErrorReported> {
12071205
self.root
12081206
.tables
1209-
.mir_abstract_consts
1207+
.thir_abstract_consts
12101208
.get(self, id)
12111209
.map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx)))))
12121210
}

0 commit comments

Comments
 (0)