Skip to content

Commit c6293e3

Browse files
committed
Auto merge of #65038 - Centril:rollup-m83dpfh, r=Centril
Rollup of 7 pull requests Successful merges: - #63678 (Improve HRTB error span when -Zno-leak-check is used) - #64931 (Reword E0392 slightly) - #64959 (syntax: improve parameter without type suggestions) - #64975 (Implement Clone::clone_from for LinkedList) - #64993 (BacktraceStatus: add Eq impl) - #64998 (Filter out RLS output directories on tidy runs) - #65010 (Compare `primary` with maximum of `children`s' line num instead of dropping it) Failed merges: r? @ghost
2 parents 2daa404 + d5a0765 commit c6293e3

Some content is hidden

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

41 files changed

+357
-65
lines changed

src/liballoc/collections/linked_list.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,19 @@ impl<T: Clone> Clone for LinkedList<T> {
11971197
fn clone(&self) -> Self {
11981198
self.iter().cloned().collect()
11991199
}
1200+
1201+
fn clone_from(&mut self, other: &Self) {
1202+
let mut iter_other = other.iter();
1203+
if self.len() > other.len() {
1204+
self.split_off(other.len());
1205+
}
1206+
for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) {
1207+
elem.clone_from(elem_other);
1208+
}
1209+
if !iter_other.is_empty() {
1210+
self.extend(iter_other.cloned());
1211+
}
1212+
}
12001213
}
12011214

12021215
#[stable(feature = "rust1", since = "1.0.0")]

src/liballoc/collections/linked_list/tests.rs

+43
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,49 @@ fn test_append() {
110110
check_links(&n);
111111
}
112112

113+
#[test]
114+
fn test_clone_from() {
115+
// Short cloned from long
116+
{
117+
let v = vec![1, 2, 3, 4, 5];
118+
let u = vec![8, 7, 6, 2, 3, 4, 5];
119+
let mut m = list_from(&v);
120+
let n = list_from(&u);
121+
m.clone_from(&n);
122+
check_links(&m);
123+
assert_eq!(m, n);
124+
for elt in u {
125+
assert_eq!(m.pop_front(), Some(elt))
126+
}
127+
}
128+
// Long cloned from short
129+
{
130+
let v = vec![1, 2, 3, 4, 5];
131+
let u = vec![6, 7, 8];
132+
let mut m = list_from(&v);
133+
let n = list_from(&u);
134+
m.clone_from(&n);
135+
check_links(&m);
136+
assert_eq!(m, n);
137+
for elt in u {
138+
assert_eq!(m.pop_front(), Some(elt))
139+
}
140+
}
141+
// Two equal length lists
142+
{
143+
let v = vec![1, 2, 3, 4, 5];
144+
let u = vec![9, 8, 1, 2, 3];
145+
let mut m = list_from(&v);
146+
let n = list_from(&u);
147+
m.clone_from(&n);
148+
check_links(&m);
149+
assert_eq!(m, n);
150+
for elt in u {
151+
assert_eq!(m.pop_front(), Some(elt))
152+
}
153+
}
154+
}
155+
113156
#[test]
114157
fn test_insert_prev() {
115158
let mut m = list_from(&[0, 2, 4, 6, 8]);

src/librustc/infer/mod.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,27 @@ pub enum NLLRegionVariableOrigin {
418418
/// from a `for<'a> T` binder). Meant to represent "any region".
419419
Placeholder(ty::PlaceholderRegion),
420420

421-
Existential,
421+
Existential {
422+
/// If this is true, then this variable was created to represent a lifetime
423+
/// bound in a `for` binder. For example, it might have been created to
424+
/// represent the lifetime `'a` in a type like `for<'a> fn(&'a u32)`.
425+
/// Such variables are created when we are trying to figure out if there
426+
/// is any valid instantiation of `'a` that could fit into some scenario.
427+
///
428+
/// This is used to inform error reporting: in the case that we are trying to
429+
/// determine whether there is any valid instantiation of a `'a` variable that meets
430+
/// some constraint C, we want to blame the "source" of that `for` type,
431+
/// rather than blaming the source of the constraint C.
432+
from_forall: bool
433+
},
422434
}
423435

424436
impl NLLRegionVariableOrigin {
425437
pub fn is_universal(self) -> bool {
426438
match self {
427439
NLLRegionVariableOrigin::FreeRegion => true,
428440
NLLRegionVariableOrigin::Placeholder(..) => true,
429-
NLLRegionVariableOrigin::Existential => false,
441+
NLLRegionVariableOrigin::Existential{ .. } => false,
430442
}
431443
}
432444

src/librustc/infer/nll_relate/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub trait TypeRelatingDelegate<'tcx> {
9393
/// we will invoke this method to instantiate `'a` with an
9494
/// inference variable (though `'b` would be instantiated first,
9595
/// as a placeholder).
96-
fn next_existential_region_var(&mut self) -> ty::Region<'tcx>;
96+
fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>;
9797

9898
/// Creates a new region variable representing a
9999
/// higher-ranked region that is instantiated universally.
@@ -193,7 +193,7 @@ where
193193
let placeholder = ty::PlaceholderRegion { universe, name: br };
194194
delegate.next_placeholder_region(placeholder)
195195
} else {
196-
delegate.next_existential_region_var()
196+
delegate.next_existential_region_var(true)
197197
}
198198
}
199199
};

src/librustc_errors/emitter.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,8 @@ impl EmitterWriter {
10261026
children.iter()
10271027
.map(|sub| self.get_multispan_max_line_num(&sub.span))
10281028
.max()
1029-
.unwrap_or(primary)
1029+
.unwrap_or(0)
1030+
.max(primary)
10301031
}
10311032

10321033
/// Adds a left margin to every line but the first, given a padding length and the label being

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

+86-12
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
9797
&self,
9898
body: &Body<'tcx>,
9999
from_region: RegionVid,
100+
from_region_origin: NLLRegionVariableOrigin,
100101
target_test: impl Fn(RegionVid) -> bool,
101102
) -> (ConstraintCategory, bool, Span) {
102-
debug!("best_blame_constraint(from_region={:?})", from_region);
103+
debug!("best_blame_constraint(from_region={:?}, from_region_origin={:?})",
104+
from_region, from_region_origin);
103105

104106
// Find all paths
105107
let (path, target_region) =
@@ -152,19 +154,85 @@ impl<'tcx> RegionInferenceContext<'tcx> {
152154
// we still want to screen for an "interesting" point to
153155
// highlight (e.g., a call site or something).
154156
let target_scc = self.constraint_sccs.scc(target_region);
155-
let best_choice = (0..path.len()).rev().find(|&i| {
156-
let constraint = path[i];
157+
let mut range = 0..path.len();
158+
159+
// As noted above, when reporting an error, there is typically a chain of constraints
160+
// leading from some "source" region which must outlive some "target" region.
161+
// In most cases, we prefer to "blame" the constraints closer to the target --
162+
// but there is one exception. When constraints arise from higher-ranked subtyping,
163+
// we generally prefer to blame the source value,
164+
// as the "target" in this case tends to be some type annotation that the user gave.
165+
// Therefore, if we find that the region origin is some instantiation
166+
// of a higher-ranked region, we start our search from the "source" point
167+
// rather than the "target", and we also tweak a few other things.
168+
//
169+
// An example might be this bit of Rust code:
170+
//
171+
// ```rust
172+
// let x: fn(&'static ()) = |_| {};
173+
// let y: for<'a> fn(&'a ()) = x;
174+
// ```
175+
//
176+
// In MIR, this will be converted into a combination of assignments and type ascriptions.
177+
// In particular, the 'static is imposed through a type ascription:
178+
//
179+
// ```rust
180+
// x = ...;
181+
// AscribeUserType(x, fn(&'static ())
182+
// y = x;
183+
// ```
184+
//
185+
// We wind up ultimately with constraints like
186+
//
187+
// ```rust
188+
// !a: 'temp1 // from the `y = x` statement
189+
// 'temp1: 'temp2
190+
// 'temp2: 'static // from the AscribeUserType
191+
// ```
192+
//
193+
// and here we prefer to blame the source (the y = x statement).
194+
let blame_source = match from_region_origin {
195+
NLLRegionVariableOrigin::FreeRegion
196+
| NLLRegionVariableOrigin::Existential { from_forall: false } => {
197+
true
198+
}
199+
NLLRegionVariableOrigin::Placeholder(_)
200+
| NLLRegionVariableOrigin::Existential { from_forall: true } => {
201+
false
202+
}
203+
};
204+
205+
let find_region = |i: &usize| {
206+
let constraint = path[*i];
157207

158208
let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
159209

160-
match categorized_path[i].0 {
161-
ConstraintCategory::OpaqueType | ConstraintCategory::Boring |
162-
ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false,
163-
ConstraintCategory::TypeAnnotation | ConstraintCategory::Return |
164-
ConstraintCategory::Yield => true,
165-
_ => constraint_sup_scc != target_scc,
210+
if blame_source {
211+
match categorized_path[*i].0 {
212+
ConstraintCategory::OpaqueType | ConstraintCategory::Boring |
213+
ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false,
214+
ConstraintCategory::TypeAnnotation | ConstraintCategory::Return |
215+
ConstraintCategory::Yield => true,
216+
_ => constraint_sup_scc != target_scc,
217+
}
218+
} else {
219+
match categorized_path[*i].0 {
220+
ConstraintCategory::OpaqueType | ConstraintCategory::Boring |
221+
ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false,
222+
_ => true
223+
}
166224
}
167-
});
225+
};
226+
227+
let best_choice = if blame_source {
228+
range.rev().find(find_region)
229+
} else {
230+
range.find(find_region)
231+
};
232+
233+
debug!("best_blame_constraint: best_choice={:?} blame_source={}",
234+
best_choice, blame_source);
235+
168236
if let Some(i) = best_choice {
169237
if let Some(next) = categorized_path.get(i + 1) {
170238
if categorized_path[i].0 == ConstraintCategory::Return
@@ -300,12 +368,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
300368
infcx: &'a InferCtxt<'a, 'tcx>,
301369
mir_def_id: DefId,
302370
fr: RegionVid,
371+
fr_origin: NLLRegionVariableOrigin,
303372
outlived_fr: RegionVid,
304373
renctx: &mut RegionErrorNamingCtx,
305374
) -> DiagnosticBuilder<'a> {
306375
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
307376

308-
let (category, _, span) = self.best_blame_constraint(body, fr, |r| {
377+
let (category, _, span) = self.best_blame_constraint(body, fr, fr_origin, |r| {
309378
self.provides_universal_region(r, fr, outlived_fr)
310379
});
311380

@@ -712,6 +781,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
712781
let (category, from_closure, span) = self.best_blame_constraint(
713782
body,
714783
borrow_region,
784+
NLLRegionVariableOrigin::FreeRegion,
715785
|r| self.provides_universal_region(r, borrow_region, outlived_region)
716786
);
717787

@@ -771,11 +841,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
771841
&self,
772842
body: &Body<'tcx>,
773843
fr1: RegionVid,
844+
fr1_origin: NLLRegionVariableOrigin,
774845
fr2: RegionVid,
775846
) -> (ConstraintCategory, Span) {
776847
let (category, _, span) = self.best_blame_constraint(
777848
body,
778849
fr1,
850+
fr1_origin,
779851
|r| self.provides_universal_region(r, fr1, fr2),
780852
);
781853
(category, span)
@@ -828,7 +900,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
828900
universe1.cannot_name(placeholder.universe)
829901
}
830902

831-
NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential => false,
903+
NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => {
904+
false
905+
}
832906
}
833907
}
834908
}

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
406406
}
407407
}
408408

409-
NLLRegionVariableOrigin::Existential => {
409+
NLLRegionVariableOrigin::Existential { .. } => {
410410
// For existential, regions, nothing to do.
411411
}
412412
}
@@ -1348,7 +1348,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
13481348
self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder);
13491349
}
13501350

1351-
NLLRegionVariableOrigin::Existential => {
1351+
NLLRegionVariableOrigin::Existential { .. } => {
13521352
// nothing to check here
13531353
}
13541354
}
@@ -1461,7 +1461,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14611461
debug!("check_universal_region: fr_minus={:?}", fr_minus);
14621462

14631463
let blame_span_category =
1464-
self.find_outlives_blame_span(body, longer_fr, shorter_fr);
1464+
self.find_outlives_blame_span(body, longer_fr,
1465+
NLLRegionVariableOrigin::FreeRegion,shorter_fr);
14651466

14661467
// Grow `shorter_fr` until we find some non-local regions. (We
14671468
// always will.) We'll call them `shorter_fr+` -- they're ever
@@ -1494,6 +1495,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14941495
infcx,
14951496
mir_def_id,
14961497
longer_fr,
1498+
NLLRegionVariableOrigin::FreeRegion,
14971499
shorter_fr,
14981500
region_naming,
14991501
);
@@ -1547,7 +1549,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15471549
};
15481550

15491551
// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
1550-
let (_, span) = self.find_outlives_blame_span(body, longer_fr, error_region);
1552+
let (_, span) = self.find_outlives_blame_span(
1553+
body, longer_fr, NLLRegionVariableOrigin::Placeholder(placeholder), error_region
1554+
);
15511555

15521556
// Obviously, this error message is far from satisfactory.
15531557
// At present, though, it only appears in unit tests --
@@ -1608,7 +1612,7 @@ impl<'tcx> RegionDefinition<'tcx> {
16081612

16091613
let origin = match rv_origin {
16101614
RegionVariableOrigin::NLL(origin) => origin,
1611-
_ => NLLRegionVariableOrigin::Existential,
1615+
_ => NLLRegionVariableOrigin::Existential { from_forall: false },
16121616
};
16131617

16141618
Self { origin, universe, external_name: None }

src/librustc_mir/borrow_check/nll/renumber.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ where
3535
infcx
3636
.tcx
3737
.fold_regions(value, &mut false, |_region, _depth| {
38-
let origin = NLLRegionVariableOrigin::Existential;
38+
let origin = NLLRegionVariableOrigin::Existential { from_forall: false };
3939
infcx.next_nll_region_var(origin)
4040
})
4141
}

src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
6666
self.infcx.create_next_universe()
6767
}
6868

69-
fn next_existential_region_var(&mut self) -> ty::Region<'tcx> {
69+
fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
7070
if let Some(_) = &mut self.borrowck_context {
71-
let origin = NLLRegionVariableOrigin::Existential;
71+
let origin = NLLRegionVariableOrigin::Existential { from_forall };
7272
self.infcx.next_nll_region_var(origin)
7373
} else {
7474
self.infcx.tcx.lifetimes.re_erased
@@ -88,7 +88,9 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
8888

8989
fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
9090
self.infcx
91-
.next_nll_region_var_in_universe(NLLRegionVariableOrigin::Existential, universe)
91+
.next_nll_region_var_in_universe(NLLRegionVariableOrigin::Existential {
92+
from_forall: false
93+
}, universe)
9294
}
9395

9496
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>) {

src/librustc_traits/chalk_context/unify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl TypeRelatingDelegate<'tcx> for &mut ChalkTypeRelatingDelegate<'_, 'tcx> {
6565
self.infcx.create_next_universe()
6666
}
6767

68-
fn next_existential_region_var(&mut self) -> ty::Region<'tcx> {
68+
fn next_existential_region_var(&mut self, _was_placeholder: bool) -> ty::Region<'tcx> {
6969
self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
7070
}
7171

0 commit comments

Comments
 (0)