From 020287516b756936dc774f95f6a8039c7d24d640 Mon Sep 17 00:00:00 2001 From: The8472 Date: Fri, 2 Apr 2021 01:10:26 +0200 Subject: [PATCH 01/70] add TrustedRandomAccess specialization to vec::extend This should do roughly the same as the TrustedLen specialization but result in less IR by using __iterator_get_unchecked instead of iterator.for_each. --- library/alloc/src/vec/spec_extend.rs | 84 +++++++++++++++++++-------- library/core/src/iter/adapters/zip.rs | 4 ++ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index e132befcfa5e2..db19d739ff8df 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -1,5 +1,5 @@ use crate::alloc::Allocator; -use core::iter::TrustedLen; +use core::iter::{TrustedLen, TrustedRandomAccess}; use core::ptr::{self}; use core::slice::{self}; @@ -11,6 +11,49 @@ pub(super) trait SpecExtend { } impl SpecExtend for Vec +where + I: Iterator, +{ + default fn spec_extend(&mut self, iter: I) { + SpecExtendInner::spec_extend(self, iter); + } +} + +impl SpecExtend> for Vec { + fn spec_extend(&mut self, mut iterator: IntoIter) { + unsafe { + self.append_elements(iterator.as_slice() as _); + } + iterator.ptr = iterator.end; + } +} + +impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec +where + I: Iterator, + T: Clone, +{ + default fn spec_extend(&mut self, iterator: I) { + SpecExtend::spec_extend(self, iterator.cloned()) + } +} + +impl<'a, T: 'a, A: Allocator + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec +where + T: Copy, +{ + fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { + let slice = iterator.as_slice(); + unsafe { self.append_elements(slice) }; + } +} + +// Helper trait to disambiguate overlapping specializations +trait SpecExtendInner { + fn spec_extend(&mut self, iter: I); +} + +impl SpecExtendInner for Vec where I: Iterator, { @@ -19,7 +62,7 @@ where } } -impl SpecExtend for Vec +impl SpecExtendInner for Vec where I: TrustedLen, { @@ -57,31 +100,22 @@ where } } -impl SpecExtend> for Vec { - fn spec_extend(&mut self, mut iterator: IntoIter) { - unsafe { - self.append_elements(iterator.as_slice() as _); - } - iterator.ptr = iterator.end; - } -} - -impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec +impl SpecExtendInner for Vec where - I: Iterator, - T: Clone, + I: TrustedLen + TrustedRandomAccess, { - default fn spec_extend(&mut self, iterator: I) { - self.spec_extend(iterator.cloned()) - } -} + default fn spec_extend(&mut self, mut iterator: I) { + let size = iterator.size(); + self.reserve(size); -impl<'a, T: 'a, A: Allocator + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec -where - T: Copy, -{ - fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { - let slice = iterator.as_slice(); - unsafe { self.append_elements(slice) }; + // SAFETY: reserve ensured that there is sufficient capacity for the additional items. + // The loop upholds the TRA requirements by accessing each element only once. + unsafe { + let sink = self.as_mut_ptr().add(self.len()); + for i in 0..size { + ptr::write(sink.add(i), iterator.__iterator_get_unchecked(i)); + self.set_len(self.len() + 1); + } + } } } diff --git a/library/core/src/iter/adapters/zip.rs b/library/core/src/iter/adapters/zip.rs index 2f8f504d8fcaa..4f6ef24be1ba4 100644 --- a/library/core/src/iter/adapters/zip.rs +++ b/library/core/src/iter/adapters/zip.rs @@ -416,6 +416,10 @@ impl ZipFmt Date: Thu, 15 Apr 2021 16:58:17 +0200 Subject: [PATCH 02/70] elision of generic argument in E0599 if the methode has not been found anywhere and sugetion of type with method when found. --- .../rustc_typeck/src/check/method/suggest.rs | 120 +++++++++++++++++- src/test/ui/auto-ref-slice-plus-ref.stderr | 4 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 12 +- .../no-method-suggested-traits.stderr | 24 ++-- src/test/ui/issues/issue-30123.stderr | 2 + src/test/ui/issues/issue-41880.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 90 +++++++++++++ ...ethod-not-found-generic-arg-elision.stderr | 75 +++++++++++ src/test/ui/object-pointer-types.stderr | 2 +- 11 files changed, 310 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/methods/method-not-found-generic-arg-elision.rs create mode 100644 src/test/ui/methods/method-not-found-generic-arg-elision.stderr diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 02fe8312c4c1f..54a1078383fcb 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -13,6 +13,7 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; +use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; @@ -383,6 +384,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } else { span = item_name.span; + + // issue #81576, elision of generic argument when no methode can be found in any implementation + let mut ty_str_reported = ty_str.clone(); + if let ty::Adt(_, ref generics) = actual.kind() { + if generics.len() > 0 { + let candidate_numbers: usize = self + .autoderef(span, actual) + .map(|(ty, _)| { + if let ty::Adt(ref adt_deref, _) = ty.kind() { + self.tcx + .inherent_impls(adt_deref.did) + .iter() + .filter_map(|def_id| { + self.associated_item( + *def_id, + item_name, + Namespace::ValueNS, + ) + }) + .count() + } else { + 0 + } + }) + .sum(); + if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { + if let Some((path_string, _)) = ty_str.split_once('<') { + ty_str_reported = format!("{}<", path_string); + for (index, arg) in generics.iter().enumerate() { + let arg_replace = match arg.unpack() { + GenericArgKind::Lifetime(_) => "'_", + GenericArgKind::Type(_) + | GenericArgKind::Const(_) => "_", + }; + ty_str_reported = + format!("{}{}", ty_str_reported, arg_replace); + if index < generics.len() - 1 { + ty_str_reported = format!("{}, ", ty_str_reported); + } + } + ty_str_reported = format!("{}>", ty_str_reported); + } + } + } + } + let mut err = struct_span_err!( tcx.sess, span, @@ -391,7 +438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_kind, item_name, actual.prefix_string(self.tcx), - ty_str, + ty_str_reported, ); if let Mode::MethodCall = mode { if let SelfSource::MethodCall(call) = source { @@ -449,6 +496,77 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut label_span_not_found = || { if unsatisfied_predicates.is_empty() { err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); + if let ty::Adt(ref adt, _) = rcvr_ty.kind() { + let mut inherent_impls_candidate = self + .tcx + .inherent_impls(adt.did) + .iter() + .copied() + .filter(|def_id| { + if let Some(assoc) = + self.associated_item(*def_id, item_name, Namespace::ValueNS) + { + // Check for both mode is the same so we avoid suggesting + // incorect associated item. + match (mode, assoc.fn_has_self_parameter) { + (Mode::MethodCall, true) => { + if let SelfSource::MethodCall(_) = source { + // We check that the suggest type is actually + // different from the received one + // So we avoid suggestion method with Box + // for instance + self.tcx.at(span).type_of(*def_id) != actual + && self.tcx.at(span).type_of(*def_id) + != rcvr_ty + } else { + false + } + } + (Mode::Path, false) => true, + _ => false, + } + } else { + false + } + }) + .collect::>(); + if inherent_impls_candidate.len() > 0 { + inherent_impls_candidate.sort(); + inherent_impls_candidate.dedup(); + // number of type to shows at most. + const LIMIT: usize = 3; + let mut note = format!("The {item_kind} was found for"); + if inherent_impls_candidate.len() > 1 { + for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2) + { + let impl_ty = self.tcx.at(span).type_of(*impl_item); + note = format!("{} {},", note, impl_ty); + } + let impl_ty = self.tcx.at(span).type_of( + inherent_impls_candidate + [inherent_impls_candidate.len() - 1], + ); + if inherent_impls_candidate.len() > LIMIT { + note = format!("{} {},", note, impl_ty); + } else { + note = format!("{} {} and", note, impl_ty); + } + } + let impl_ty = self + .tcx + .at(span) + .type_of(*inherent_impls_candidate.last().unwrap()); + note = format!("{} {}", note, impl_ty); + if inherent_impls_candidate.len() > LIMIT { + note = format!( + "{} and {} more", + note, + inherent_impls_candidate.len() - LIMIT + ); + } + err.note(&format!("{}.", note)); + } + } } else { err.span_label(span, format!("{item_kind} cannot be called on `{ty_str}` due to unsatisfied trait bounds")); } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index eb8447ff0f3e7..be1b79e936d24 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec<_, _>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it LL | trait MyIter { | ^^^^^^^^^^^^ -error[E0599]: no method named `test` found for struct `Vec<{integer}>` in the current scope +error[E0599]: no method named `test` found for struct `Vec<_, _>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index 56d10d88d8b25..c01af6d7e2561 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for struct `Box` in the current scope +error[E0599]: no method named `eat` found for struct `Box<_, _>` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr index d6b399acb7330..2bf32975a6f45 100644 --- a/src/test/ui/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-18343.rs:6:28: 6:33]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index 051940bbe9660..f17a56eba2f7a 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<[closure@$DIR/issue-2392.rs:35:36: 35:41]>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -65,7 +65,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_closure.boxed_closure)(); | ^ ^ -error[E0599]: no method named `closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj u32 {func}>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj u32 + 'static)>>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 64ddcb81c0a9b..5c0f945140a01 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -98,7 +98,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `Reexported` -error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope +error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -202,7 +202,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -225,7 +225,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index bc6731601f095..27b128372c0fe 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -3,6 +3,8 @@ error[E0599]: no function or associated item named `new_undirected` found for st | LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` + | + = note: The function or associated item was found for issue_30123_aux::Graph. error: aborting due to previous error diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index 09d5594f73f06..f9d11c47687b9 100644 --- a/src/test/ui/issues/issue-41880.stderr +++ b/src/test/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for struct `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate<_, _>` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs new file mode 100644 index 0000000000000..85ccb0bd0de2a --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -0,0 +1,90 @@ +// Test for issue 81576 +// Remove generic arguments if no method is found for all possible generic argument + + +struct Wrapper2<'a, T, const C: usize> { + x: &'a T, +} + +impl<'a, const C: usize> Wrapper2<'a, i8, C> { + fn method(&self) {} +} + +impl<'a, const C: usize> Wrapper2<'a, i16, C> { + fn method(&self) {} +} + +impl<'a, const C: usize> Wrapper2<'a, i32, C> { + fn method(&self) {} +} +struct Wrapper(T); + + + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +impl Wrapper { + fn method(&self) {} +} + +struct Point { + x: T, + y: T, +} + +impl Point { + fn distance(&self) -> f64 { + self.x.hypot(self.y) + } +} + +struct Other; + +impl Other { + fn other(&self) {} +} + +fn main() { + let point_f64 = Point{ x: 1_f64, y: 1_f64}; + let d = point_f64.distance(); + let point_i32 = Point{ x: 1_i32, y: 1_i32}; + let d = point_i32.distance(); + //~^ ERROR no method named `distance` found for struct `Point + let d = point_i32.other(); + //~^ ERROR no method named `other` found for struct `Point<_> + let v = vec![1_i32, 2, 3]; + v.iter().map(|x| x * x).extend(std::iter::once(100)); + //~^ ERROR no method named `extend` found for struct `Map<_, _> + let wrapper = Wrapper(true); + wrapper.method(); + //~^ ERROR no method named `method` found for struct `Wrapper + wrapper.other(); + //~^ ERROR no method named `other` found for struct `Wrapper<_> + let boolean = true; + let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; + wrapper.method(); + //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> + wrapper.other(); + //~^ ERROR no method named `other` found for struct `Wrapper2<'_, _, _> + let a = vec![1, 2, 3]; + a.not_found(); + //~^ ERROR no method named `not_found` found for struct `Vec<_, _> +} diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr new file mode 100644 index 0000000000000..80e111390c6ac --- /dev/null +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -0,0 +1,75 @@ +error[E0599]: no method named `distance` found for struct `Point` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:69:23 + | +LL | struct Point { + | --------------- method `distance` not found for this +... +LL | let d = point_i32.distance(); + | ^^^^^^^^ method not found in `Point` + | + = note: The method was found for Point. + +error[E0599]: no method named `other` found for struct `Point<_>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:71:23 + | +LL | struct Point { + | --------------- method `other` not found for this +... +LL | let d = point_i32.other(); + | ^^^^^ method not found in `Point` + +error[E0599]: no method named `extend` found for struct `Map<_, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:74:29 + | +LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); + | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:74:18: 74:27]>` + +error[E0599]: no method named `method` found for struct `Wrapper` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:77:13 + | +LL | struct Wrapper(T); + | --------------------- method `method` not found for this +... +LL | wrapper.method(); + | ^^^^^^ method not found in `Wrapper` + | + = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. + +error[E0599]: no method named `other` found for struct `Wrapper<_>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:79:13 + | +LL | struct Wrapper(T); + | --------------------- method `other` not found for this +... +LL | wrapper.other(); + | ^^^^^ method not found in `Wrapper` + +error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:83:13 + | +LL | struct Wrapper2<'a, T, const C: usize> { + | -------------------------------------- method `method` not found for this +... +LL | wrapper.method(); + | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | + = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. + +error[E0599]: no method named `other` found for struct `Wrapper2<'_, _, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:85:13 + | +LL | struct Wrapper2<'a, T, const C: usize> { + | -------------------------------------- method `other` not found for this +... +LL | wrapper.other(); + | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + +error[E0599]: no method named `not_found` found for struct `Vec<_, _>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:88:7 + | +LL | a.not_found(); + | ^^^^^^^^^ method not found in `Vec<{integer}>` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index a477425edc81b..fb3462b2cabd4 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box<(dyn Foo + 'static)>` in the current scope +error[E0599]: no method named `managed` found for struct `Box<_, _>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); From 8789ab10f93fb129649e34b5fa5f50ea2e8451c3 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Thu, 13 May 2021 12:40:06 +0200 Subject: [PATCH 03/70] Update Docker to build the deprecated target alongside the new one --- .../docker/host-x86_64/dist-various-2/Dockerfile | 10 ++++++++-- .../dist-various-2/build-solaris-toolchain.sh | 14 ++------------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index de3a99f34fcfa..357ac7a2becb9 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -42,6 +42,9 @@ ENV \ AR_x86_64_pc_solaris=x86_64-pc-solaris2.10-ar \ CC_x86_64_pc_solaris=x86_64-pc-solaris2.10-gcc \ CXX_x86_64_pc_solaris=x86_64-pc-solaris2.10-g++ \ + AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar \ + CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \ + CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ \ CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-8 \ CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-8 \ AR_x86_64_fortanix_unknown_sgx=ar \ @@ -68,8 +71,10 @@ COPY host-x86_64/dist-various-2/shared.sh /tmp/ COPY host-x86_64/dist-various-2/build-fuchsia-toolchain.sh /tmp/ RUN /tmp/build-fuchsia-toolchain.sh COPY host-x86_64/dist-various-2/build-solaris-toolchain.sh /tmp/ -RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 -RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc +RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 pc +# Build now deprecated Solaris target as well +RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 sun +RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/ RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh @@ -99,6 +104,7 @@ ENV TARGETS=$TARGETS,wasm32-unknown-unknown ENV TARGETS=$TARGETS,wasm32-wasi ENV TARGETS=$TARGETS,sparcv9-sun-solaris ENV TARGETS=$TARGETS,x86_64-pc-solaris +ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh index ee76fafb1f948..4cbc2ccfe3814 100755 --- a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh +++ b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh @@ -6,21 +6,11 @@ source shared.sh ARCH=$1 LIB_ARCH=$2 APT_ARCH=$3 +MANUFACTURER=$4 BINUTILS=2.28.1 GCC=6.5.0 -# Choose correct target based on the $ARCH -case "$ARCH" in -x86_64) - TARGET=x86_64-pc-solaris2.10 - ;; -sparcv9) - TARGET=sparcv9-sun-solaris2.10 - ;; -*) - printf 'ERROR: unknown architecture: %s\n' "$ARCH" - exit 1 -esac +TARGET=${ARCH}-${MANUFACTURER}-solaris2.10 # First up, build binutils mkdir binutils From b13185de8de511c75846ae62f01b4aa6c79e1230 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Thu, 13 May 2021 12:43:46 +0200 Subject: [PATCH 04/70] Improve comment --- src/ci/docker/host-x86_64/dist-various-2/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 357ac7a2becb9..b7f181adf2a09 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -72,7 +72,7 @@ COPY host-x86_64/dist-various-2/build-fuchsia-toolchain.sh /tmp/ RUN /tmp/build-fuchsia-toolchain.sh COPY host-x86_64/dist-various-2/build-solaris-toolchain.sh /tmp/ RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 pc -# Build now deprecated Solaris target as well +# Build deprecated target 'x86_64-sun-solaris2.10' until removed RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 sun RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/ From c150772737eac9cf08380d220f24646028d159f0 Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Sat, 15 May 2021 14:01:27 +0900 Subject: [PATCH 05/70] rustdoc: avoid legacy Korean fonts in Windows --- .../noto-sans-kr-v13-korean-regular.woff | Bin 0 -> 287068 bytes src/librustdoc/html/static/rustdoc.css | 10 +++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 src/librustdoc/html/static/noto-sans-kr-v13-korean-regular.woff diff --git a/src/librustdoc/html/static/noto-sans-kr-v13-korean-regular.woff b/src/librustdoc/html/static/noto-sans-kr-v13-korean-regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..01d6b6b54664c35f8180f7c245514d22751f9307 GIT binary patch literal 287068 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

ff0{w-vm$aC<^ll-;r!22LyG(71$pSamDnpqF% z#50o#v$G3}(P{`R6}-#i@~Q-*$GFSg<7aRfdz@>8d=39pYJ_S`iBkzR3APD2 zAqUpPo+PhOREU-2${h)38Ip~{6KD&NCG(QWA*{=ySrjE=l9LH5P*x-h<|TTP?+Nfk zxyTD#L}-LtLS9i1xRsKU^@-agsZggp3ks%qO)So^&a}=v2l8WE3GXBbqBF?O^mpGO zyvUy22^7Q%;(4Ln_^-&$zwY1;AjaYo(GG|Y{*C1)$|O!Eeixi5RuyPM4WpAuQ!-ID zQdSCE#Vnwf#wxBCx(c7hEyz&%D!mn#K#{?aVVJcjj$~3UDykRfpiGdZ0H@ecdW1L= z91=~y6jD-(QC^4MK^?+OAQXNGEf;1%EiZ_=3A>3r3fG2V(=SmjVJ>kli58X>u#4J7 ztqWJ!DQ*-#iC)HXOIBD_6f2Gv$RnSzE@@RnE2S6FOX!7nLb>6b`7H%kl!ti1KO� zE#XwOD_s}y3;70C74(XK256Hn5mflkP0e3~9EBW(9Z|FZwOCvB3&Ti63rCB|2+9cC z5VxRP*1Bp_6uOC>$F1Ph608%pu(s$H9u~%8tdq7_S>A`VA=)v8>OF=AQ}GI(g8o~O zD{_rri}(D%CvyEABzSTP^Z8IB)R|{HHs1_{e#Z6V^XIHMiO-@@&bi=Rop~0ZAVm;y z4>I={v4yp!!cs8iRN0RG!>P-_gmw+9#;n7sI~Nqxv4q$+Vkx2~hPXva*2b~$I3V~V#jX2%+MRUfH}g?2sh3P@Pt0%VcZFRb)dayU^G?=GXqMKYt)T0<4-ea zbRL<&qj9MDXgG^r7Ow$YnQpL;eAKKltAT0si;ab2$6Eaej}5COXq#@}i_}AO$7!S) z-bQ~nS>5UDhYy#?Q{(;P@=uXhqed^zz-}ML3Z6s@(DgUGw=&-cI&2ApE_3p&Py?_4{}0G5VMP z%Y_Nt5OxSNxRGqc9n;$gH_8cYWD(O0_yP1cGNPy;3-CJ9Tyg*xC^#Z#W*-=69kC-p zAQ&h*@=LTek}8gTtClKFkrzxALfM;rl|We-2iu#7d_)L)i(W!e3;j@I>K|p3)Uuh2p|4kbEL1 z3IpAc(d4x84ap&?C|5$i5%+ST6exVy_7EZ*$%Xedr(;NnuJ1z#;o3VG08jk*^aD z!C{~tggj-ve;aUmaMVta}@#Nhph0WP6XKXCATD5 zFN>yxa`FoYByu2@>)~bTR%OLnCRw#bT3pj8R{X(7&z6aj(T6Q91!mZE40F_3>JpZ< z#cn*>^~J5C*_|zGGCC6LPsNwqUvUT5W*_@A0y;0paF<^5SDcr4Rsso6)m8?w;gH-@ z<%1;LE2aC^+?fkj(7AbwTv;My_rJHawm7rP)+l%BSpU_8cer$ya||8Hy!X zyl@N4srV@7Ck5-}AGk#vNO}+!-VuD)=Z{f+A0MVm>V^LXKD;GafI`HP4nFh`BYkh`F1 zaW^%MbxOL^HKix)i_OS?!R_z(9<-6RXBfd?!4Fa}exQBhj6@iUZxS;^bXOjvGBHOb zvS6A`R}9C<8$Otd|22|z8ObrRg*K63Vb6C;#rl`!)P+Sb`qC;ZX*3{9j(TSR@zpgt zq)L8etV~88Yq9`F?qL!|r!vC099#KEmao6%Om<_!6{F0-SX|EBlxd%tB{*X(HnTeO zHAky=O4?)v&K$=4pV^b~Q3hi5P}3ec4n)H(d$xAtDSCExqn6nuWLvk%xnLW= zp$`29-CA!N9{q)+$*8aUNJDdup52;T#1{Mo{w%)E)0Bk+rME%@L!K|jTK;sPBz(@U zp&Y#5p`t%LnloqEAPQ%VGifZzGZ*&E{HtnBzHOYx{)?MDD?pT=BAL@OLghB+ZQ_(H zXS|@unc!F#``CojKM@Az&uUWizdx)AlkU3PQho$?FdcxA)ID8K!G2iiUMIGA8zbH9 z+17g9SwI*R$D7kWA(|F>b~bYRy5l(}+ADwy4a%6(1K)`w0@}iVvPbsn6X3`E%yHM3 z0)fR#d1!=ypSPcw2#x1GuuqAvaCqyT*RnU>2yIuX7|)!?Ry!AX44xOi_o}AfvOnyj zFWG%DHF+tSCP|YJoIpYJSIjE%4(QQA6>A#Dj#T?ss1WK*@ePky50#gclSfp$qH#e9 z2HCMET7UIpcijG?_O|MwoXK|0{xsV5nP>LUhE})lV3*)F-0qgx_WQjb;kChiArgW6 zT_ZOE!~J-Y0?3PN?(FhQcO(P6kJQm5YVYQLbz*&{kFTH=bSYQLRgr3O4Y=7LC6D+Y zhQmdw^jGxpcHrLkyB>j^`g@Wr0-TrA;aU2R&4JnckF&9Qkq`M@4+cL5z%$#|>a7K* zKWkuSL9Ai%ZupBp=urSJI51G3tzEm&f4(YMtKHC#yUK1o+Gh8Dl-Ib6i77}7a>OW@ z`HKkl#AH_=9Gl6KFjy1|wSRXFmfgq^M&yZQD20d*mak8dB@E6qgLP1X>4SgJpUD`F zWC{~$bSyAt$;_0cSe}VGYF-4(H-0`bMr#PuY=o6rJ*9Ca2E}O8W+ar^4|e|$E5AR4 zPL|OEKu%u9Vug~tnaLY7KAWjKkwPb%Xd(?31c3xAZV4|84+%qb5j!R>nu26yb_P=h zXP5=Hc$V=MacVBBU>1hRLYiUJA7gLMZ)#529L91^*bJP(7qyn2fj6AfI`ulVIXv}f zWDjyb!^n{Lx{+}`8iYmLF$8Rf{$aLbdBNXtJ2*rCz0r`oN8LaXKZSAm!xDO5w@Z9xXY@<2akMSO9Z+M>NCdT<&km z&2YKs=ia~Sb_|E|)A#Ng6Qsxd>5iK`)tx_-rq^h9Ue2g?i{NdA4Bh9TGOGc`%CKYp(r^6#r#YZOOrJLUF?)#3Z*3h^4?$uRN`&fk43f=wXy zx*A`Ck_0AMD|kkyj4zo=*n?{YQ=*gjCtMb-iF^!CYzFnUf6Rt(CuqPMRp^#33W+jS z=oDOfn-ZqDCfu2sdZ5BblngwTU)7-~D`XvaNmX$t){79kc_x)U=CHO&zcG5)tMgPXtSG<8!|eGdzZ4!~hcRp%d(| z6|sB~=P-a5_V|*MW}g`~J@%*cJEW*%arBL|p|!7eY##N+yK-=R9_WFK5B_ZlK#D&$ z=iLEd1^lDzp4mkUe}?b2xk((LK-#H&8QE>e`^)*kuZpfFI|NeX2P|B1^$vc9X zuqx}MOVkGGGxLPrcm<_cHb#J{bZCa;iNBG5D3<&R)=7E@?aqoLf9i!dXZHBDX6l&1 zXRSY-wpV_yn$^rDOWl#n0{AV;2-nj$r@SG_Bbdcym0ChTypGp zJ&s1g5#J4Q5S>sj-wzI5Ly0T62N4BI=_RYgH=Iq?R@jl2B$u+PtSo*CEA2*!Qeewq z)|L`q`T>8Ks2Wow96S-I`liAbSM^U7P1!f^jMZ9S`96EycWGT|LwF1C47(y<{!`^F zxYD86hybpPRdtRtd4z|xbAdIE+#(CiGOgrK2s)GY*L-K5x}7$UrMIXK&82-y`=XKf zu`IXUNtTQT&KAaLT)71SU*&^+;WLl#zti)AZ{E*uBv1q(qn{&Cp#Lm3?0+);6x&bs z&tCiQ&)Sv`##jIoY{zhbCFl}TN4TJXZZI}zI^jv!oM;F?(NfHfZOC6D;`j(0;=f2e zQ5opQ7D(sfAJE7HlDrbiDC3wVw22c!Z$t|{V>RL<&{}Gyc8MrrSESBtWBC&Ncwls> z^o5l1MQl-*ly+j{1cykJ{$ggl)Xz$45|5l!dlh!V)A(*|OAf``!C_?BYnJjt_i);8 zmRv=(aZf}oD052U$IRS~C(s4n@LRwSOY>bJ`t)xubMbwKc;Hm9x&wXG;B@A57T`22 zFVMlsm__{w$*`5i6-**Mm}Mgk8?YKi9Uvs8m`*`Ra51{mk~HF0EN8IA%2<4f^Xf53 z##8bmzZu;bO#~R*qMfp_Fos?lW7^GvxKXwll`H#kgs`#*C5Bug#sHWn?uMMiNjq z=`QR{cdVXT8~nN6NjM9}1HExo4+~JjLAhLGL>_V3j~r(t#?ooVDXt3^O&yvX~ZbT;5U5hdDZvTog0a&R=90tR0Hu!_B(3`wMjR zv%7aV^cpT^>>B)zYDv|%y4n3~6m{p0pClaOPJ`LmRh!*Y(?0fC&NLw#iyd~Oxni5I zQ+h~O_`7+i&)Y8bf$ztE42FZ7c`J7J^zqB?$8scUdHIL-$@60N#&z-zZd~yd?0&Bg zv5@2)-ft!x=XKBR4P)qA-`o*0*m$}H|C8>9Kb#idez{jqY1i@8>FWyZ_8#ie-e%bI zr6HJlL7b2<;g7tx;>l-zv7I_r?zIKTkQk)jEay8|`*aPpqxaSyd9wN>fG^YeXN`poA|LO-AOB)=+v2WmcMaQb8Ad z6`Js^Kr946r#h?RmoaBorK*A{)=Ia+uvIN}7pP~hD=f(sT#>t-F2xspQNj_kb}V*8 ziPK>7SaM6NpiM_x#g+YZuI)dYa3imsX@OdBPivE3kDuR`8inHaTl9>dk?sszd&C>n(0UL;M^5ZR6)lVj%MBmS*tyu|4G=@ilg10pZX5YBRN? z`BnR&@N@hCypYlmv)1?9Hgrw@CreK2x9N%emo2aC#jfAV-ZG%lescBeQr+nHxUA+{a~D z7|&xycWIWHm<2Bz*Vq{422ab{+8B95cX_Tpk9={%Pdj#mo8XqhQnn^8_)_}jF!!fu ziLH61y@b4EmFN`9oGn_Ynh6L)pshDg}K&uFE$- z^jm>qATLBDe1>$QyoEV8QxYh=TBt&n57y`U5aH|#$8gR=O?;CK7%~J)>e4cy+(tn;fXV=M{W{I`SyLyW}pFZ3aN#OJ0 z%&~;#U7w=K)muEkmp`+-xfUuQ`4*pe$NJ$v;0XSGe{hig-UxXlyP(=Dj&!6TPL*^a z#y~WaP{p2?7eyfF4$dGSvL#;0Ty-1bLh?v^xf(JcDTIP*m#UEmcqLgUxdt4(kzSh! z(t-1u8)|_2na1789q@=?Ft#KZ4PwF%#xoj&lISxt=P8xNXiuMD z$M8>On8$EUu6o664Xkd&+#7Eqj$9h~kd5RU3)_%y8UxhH|FBR6k56ZO)_R~U`vl*>WDN`pf$EJ*yu#>ydSdmHLD0l&# zo@ZQ6U*Jtqjpjg2QJLDy9OW75vmITU_<0`Xn+MXt6lpp}hO%jPM2L;hVviP;)5e+K zdZwuwjpLo9yg}C(%)I%qx0nwSv8x;JOS5Y=QU%F{+Ftb^5x2#dRtxAj zG}}>a{Gtuc1umjb6l>ToXL$nfkNAr|b$6 zL)>v?Oc8;=$L=>!g?qS=CXrZho(;|q;|811ak8hIXyMk6--6`?pbY->MackD4*5Jl z3PbqFg|ZqInDWF6j7C&9mePQ|nw?oNv#*(iTr19b-fJO*!2eeCxO z$h;hbeY*p8Fg8#7a=lG6lIPQ6T$$^VPesjvGe^ho2yIxk7{=lVd4juoH|37=(4Nzr zubG}@T>f%A$2)%GAYk7Z@*vdy#+)6r;mztRZs)C=+^6HE8cu%Y^_*NB=Vdw4g2>C= z^Tf)dNKy&Pi8>%nZcfjsKUg7rCjIkw%tmG#`c6M#C+NcjwL_&LBFGzcT@h1i&nzm3 zGD~D0B8r5vcibQC=-naAx6X`)Om7_ET%kAiPzPzJ`1LD+ zK<~vVF@NjjHQNB?6|e6a_-pF09>pJ_LKG}@Oi4;16}Ku$!*rK2*byrS?F&$VN{lwy z&v6ho!r?Pf5IV0xoYu2vder>iR{bXbMtp`tc(4Zgp<^1C;G)lv% zTY0C-E1kwuv#6U*t3I{mc#Ty`&afN;sM8;v-ICA!{`?uY%iXM=_zd9%A7>HGdp}s# z(?>Ym(%X(dOs3o+e9cQX(0J`h`}P7$Q5Wn4u0`t*6f#3|mF&+&{SYFuf^Jni(NDFh za}K2z&_kQ39*|JmESHv3J?){+S40Vj#aDGT;8aB!~dDaN>$zFTbEU+ zYb|${ttYFMx1Ft5U!gDCRCp<<`v1X(RSTZA=2V3Hu9!Dv^Qs?_St?1&(p6iuw|>)^ zR2j3SB~av?Wjy6S-Q*99L!^=a;gSrXT}M5UQK zQ{kfF=2uVuzTDc?DYZ3I{m$w3U4gH%M54hLUS(0|6|3UF@`zu(jj&Xn`{tvzQ+SqL z>}RsXpz|rRU<(Cdn*7{z+Js)#g?Id93^ ztncILA@ui&+RmQqc+-2`{|eWS2U;gVxS&;d*DACR0$QjVEhq>r2%ieHUIlWy7_nP} z==Wb?$0T7#sJALzc4kwJI#y+R7KZXtk`o&7v~Q!)QJMWS22Ju;5A4R2O>`e&MG3&c08(5i~{D`Z1(s9%YOs$EEyL|DL!fP zw2-ooY5s50!d(*r0c1$Ta`eb|o+7i~dAqUSTZLI7fdcD&n}iGlVT1n2E@LE%kcH~T zptd$aXtCYA^g-X+ujHA)8xhl0{gyaR(Xu0#0@+82kqtq=*E$lqp|3)?uwpi$Sfjg{ zSD^ZHPstg^AX|bmY(7G4?TnEb*{0Is4PQ@i7?;nF@ZC>?D;J9U>yE;MAH+CgdX2KA z*0CV_4UV~WmMua&4`fdInyll2%VU-)$W55RL_{HvhA`_gBY_LK z5U?UwI=LAP91`=6DV??y&ldK)EuKw@4n|h`^42G?S9Jy_?Le~GH8|eMquHw*RSs5Fjv-Oe2hH zna{9dnpkPE53EqyKH!>+*Vb0!Su`4kF09J04Q)tk1yj5UHN)^Mg`XRqu|(TUAoJ?Q zvUB5b$_$h?F7P7p>2h=T@!HGOR~R{TE`zI$=w2x~3GDw~o>I+;uoG*8w} zU&$=6M7c|@d{A_Lbed>N{-apxkxxCsG~bvg9J$EZ^m&i)S_^@|PuyMBj=2y@Wz&f4 zBtnpapoL&iHF8)@7-YIlR3@<&a&1dcCa;hyX*Q=|W6(d8E8J)XP7~OjxS=(q^xmk= zR0Z-DQjSh=T~Z>%b#rcl%o5ss@#v#49ztHuCu8=N<&)v<7_AiRFIXOHCvaka*DlRK z)MjX}xT*9{UE#={83h87*K%j5Ktb>nK)eVgw7U?cOK6D(ElhvjA3DU17jW$#p$Pn_ zzTS$X#i-z7-RX}pA4wPZ3cvlO!{gPxTD^;j&OY!_`Q!Nk=6kC2EQtXD# zIB}i$0ggLT9-bI`X;nVdEIW({=)*b;pT9yY;6t&m>~&JBaHSu=4l+m0jAbPWzc6lI zoCl2~=*|*Jo4n8Eb92!i|M`;euVkjnxdeSl`+e`HKJ7_AGh&}@22qfd0KahZQFaG* zrc{+}#6tJPg$|&Qc+pJq6oM5*jD!N+p#h?4eNUBxv+}9GB++eJ26?p@IO|-lwv&qz zcsR87B)e36yDcrLDOOa-&+JUjNuhF4+YU#CHC>OUV5ff~`zT9>W7U#=Cxyn%EO!br zdjTE-F=7;P@DB=q_fh{12|pxZ=r20Xq>R)AHzJ!mr8|uJ&m(?fRC+-w==i=@vt!&D zGw{eWaS%wB6V#YXyAHUR_kJ}u$h5vBEj-B+00G9~s6LPZaNQ#b7FL*knjMicbX`6T zia=MZQPjHjAel_93(Tgb1S@Y=@ zR?W!;1~yuPzHZJmzkkF%nYy(6T-?)okIy?s&=oe%MGhR;4sEXHMjP{i+enQqlmi^8 zboFG=e6)+M!)z}-sF4QEZ>@h8xM?qa3l*HX!>LDSwx=wgRtI6Vu2T=q%!mmia2M=k4vV+?UcS0< zxU9C@EA&`It81;&C&#QU|3$mIlkLz#k|TgjLwv-Ukvy4$GxmQ#~snKM}S$P#~R$skf5 zSAO*u`Cog$LJ(FC8-qp0>?br!Mi(&ZGv;(9Q5>|PJlqf;`4zOdNFrBZJc)E&yFLv= zILzU(BRnj|Iybg-kyq$#n4>OoIp5T5Al7g6sYv>%7zS)a7Tb^_a>fdcDyz`f++9t$ez}K1 z&Kc}emYz!tXNTs(Wzm9Mry(zWmHgtL>*ooh)iF84V z12Hjf#C}B0Bp~#^Bj-!ZR!M$?q&h90(|S!%Geb9%N=SAG3`Zsvc-`6{_Wr_w90@uu zaCF7A6KbnK9v-wV0T*&^ldLe!;V5_Kt@%11e+Qmf-ZXkAp>o@vS7)I2)s? zLMBo6M{qF3%=?}pPy%;B7T&c{48=nXHZcGTZ5|83{fe;r_bmwY2C|qywcda#C-_z~ z=S1C_flNPI;P@8-{_(mrY>&U>xzLpp6yZ&xRno}qf^T&V=FjtQH-?USh?g8`+WRwo zbuB2EN6U72OF|hT$AU|D9474&sHlctG5!$9=I-gBzs;Ku+aW8ng>GG$nns+s;4Xy) z0zp54(rO$zBZL{)l?JrVP!aU`_6O@$ORL-*1S1b;Y+~{d346<%+gjfbxdkE%NeXpV zFPLc2^IlUII9D06vHzq4(4UIs*Op#O5LY^t;^ip!yb-MZfgbTQAHL@MV`J=Acfs;e zSl_DY0~z{ZW$}OgqHd=&EsN|GP1b}IfygY{Or}U)t$;V4ZL9VE99lnLba-zpNc=!w z>XT3vCi2e+&?~{B&rB5Ph8{BBBeJb4v+rOwe>k&PJsF$>r6#QrksIPc&J@95a{luN zO%kc1TCI2u8C4Fx_#doppaUqOh+h)nAc4Bx+eINzdv|X9}BHP z*0g*gGJ1M!@^wU3H4J`>Iz*QgnHfi9;fSI&hWnqi8h; z_tf(8Y^M>)nyD}*D_my}8jNq7a{Lk%p0uU=&7X^R$!(%5cmj9ozZ68`ZK;YBNNn6> zrcz7myJX4Fi9+#38zT6H41cJoT^f|0@qET}gRbGlsr6FX7S{|baBHA>XHp6_W>$tZ za%+`%rSrC2N4Wh+ZY1Q?0u%;#XzQMQF5VH_7MAaXtlxO#=oy*}Vw&lQR(1O={Xq zjQM-9QKFp0*&PD@4SbF{1iBy5uR%R=7_vLX41JvoKMm<2pE}w^pp__MR4(5G{;2x# zDw}jHz0IpCV^W&@G>m2a>in)_n0nT+Ok^=}mrl{U174|lk7uw#{V?2k_{I$W5FgKm z;54pA#BcpmuFcha-UkT4z!;Dx0r6|V+%?H1_X@@}q^GX`lGYQPZ{zSsM!$3eL14Io znkE*ihXDfj>IL-)tB%9M>Jce3$~^oGYLB?k`E?h?rH*uIh4&8s%+XPsFkJ`au~8n{ z=(V1N55(}*DDH4K8E~TK+au!1i`Xzp6Zev>ZV;q|6$o2}W3$AB_VnJibff%ULB#%M z3qvWH7=yO|fvMs4ybgc4PMuY%o=*hV+}TI{!|WahsaJ;|5YEzj5WD^n&}p9QEWG9^zU4b9#5;#ktH zQV(ODn@BoiRwX?IU#k?WWVEp>l(~hf0!aY^i$oh^L+ch$gp`xDH?U65$Q$J|5q3tc zAg(`l(BvzJpB^+aSy|M0Ev>Z|>+r=dhD%eF4>dR054Hxv8>ix;d{qxwQ0LzXm{NBk+VtSho^*4`M^w^@%ck2Da zeYbft8?4v?G_3JTJyB^iZdmf9p`sNu_wT#$#FZ-(o$tL+<~VNpQFJLCflku%1=aSh zipny_4H>QYafAk`bFe;R2%#}|WLq(>u|RqcVtHSFBcCP_f5s@Y#ta@8`s_&CzK7Sv z;PpeqnkRW^Di+;Khj>9UV1XJ*c%B>D4|_ns6-KjaVM`qSiaqYa?|%R%K-j;MF8sNl zpfmMIVW=M^4BS8ocO0a4SW_{PLWF=$Aj)5c|nON9Ri>|BSHl z@M^40FDzpB%_5N6t3V1J#L5Idh>1*!)TiiLY;kx)4rkS*NySO=zwExi(x-mAOVIVF zqN9(5icKwD)_KWyllt>3g1&-xgYXfO)9v8ZKLML3e2B%l^?iHilRq`nw6C$Imo{Cj z6cwapwUy>X24zc%ZW8Hk<|zhZM6F%FMB{;XPY`=6tSNMp$kEqpwUPbR97hR0ow`tj0C}*B+x+R}DPGEdkzmE;5evy_sA0Qx^rmQA z42jVd(KXRk)1g5QiJ*0`ms5PsOP0m)VI2nS9w_>?@=V3q8cpTp|k?IKw zkzlKemf)?iUA#_475^}laMA;~*4<`kdiT_|iaO3;za>enuqPL}`5{Gi#c6Y05&haV z(pC3>#6mz1_Z&!YbMpPi9pdUeX+#OHkGVD7qFUL zzjvdKX!Ql3(pU@^4lz;QYjls9uNSS}vBgvpC_h-{wOwsh%Hx9QMD8odV@k`fwdb=o z*@VN^ph$l)Jz(Pae6iTxZp&JCw!()fy_%AcCZ-b`OXoeo5ptVb0%`{%Ki6|WfZUj2 za{t?%oEBk1?i|%3=)^+qTqdRE4Ho)coN|w0q*Cis5ZBVbL9sVeOVRr$n>XTO8Ezb<~O_5Yr5M>@#nc8CX-SU-4$?+WiW+O?x zeZ)rWJy0NzMjnZX5G`}l)peI(L(XZ1s#dp1rTT|(;UO*U0|C?1O9W>Y?kE-)6`f1Y zWP5Z<%U5?2S2NEQR*EWj6oq6+I=URnbypH}Z?dn;ITx{$%Z}j9tZtu!-5q@*WOIy* zjmYL#*Q>sgHLD0XRK=_^yY=+Rt%lByTN@THG&5U0_DlzBt2!%rupJ}Zb_^eD!Kexu zb%IePT1}N)#mF+uKEgiK8mB;LRYX~MnI>4O%q77HeIU?68!%Xf46MO`{P!S) zKBkE~ZA|`;HwsPMIUJ0}4KkNTB}nM@x(j>n+ji5PvW2pR%#{Wr$;N1~feSUff)>zd<-Iv znB41V60C(uu*x$7%|ok*^@8!L5@+7Y=gh~dN_nH9>p6T@MN2`J2eUG}a~tz`SBnOU zd&|3u_z(v&JJlD1ScdYvr$~SV^A=)#CcRh$0ya-UeRbDg?>f4lKkv|+^22Ira_Yj>WKoq{f|Fz^S&T@g`??_G?2hoQQL$TCZ05yHJkWqLK4{1m zFQw20F02BKD|pfx(5~Ub1}=>0zFqU^u~ChlzTqa#CC!_<*a`)^%{f)o89C+U8D3V_ zo4xE<;e|GiYFkUm-g0hC8@dn4>rpbgzYg0Vr4>>H@Mx4`J_fFnVZcJ++=hC%e~Skf z+WB?d1_mnY<&SnR+S(q7hBuZiF|+oy+bk*cB(kogrDTgM(|j!q*Q`VTKtfi|tXFe8 z5)`B`t5yjT?^xZT-+?oy$2@E=zgy>$Z5PkdoHQ{lqf*pqEY&l04s`XA6nGKWuB2T` z6PI2Oa(8ywtj9Xz^3tR7AX|HnKnG{fD|sQTqYq)9UgvX1{P`5TTYd`8lQEjq?n9Jp zVceeNdpq?&Pvj{2{Y1R2GO)DX?u{!FKGMx z-4d*=EP03rmK}Vs#D?nN49v+bVL`F>KPfsr7YNZdZcQ!xR>Mob1NK;`3l8RIeeLii ze7UksLu2JS^dJ^cZq zXmJE6mxEI)xIc@JRDu=lod0cldj^&DaVk?!(vjS3*&$*B8HQ^nFw~v z?Q$bX(h_W=An{WWTDZ0@A&ywx~48cF5Z$tFXH;;v`gvYlC(f~mJUyp2ZO{}fCW4% z3%0fM3>u4uVAj$5Q#2Hza;){3&ZeY2)|rlR#cH2+#d$25OyvDn%9w=DX6bh@@732l95E+=GnIbf?dp#)N z%3Hkb+e~UR)h^Y>f77H|)HDj_R`8B+fAAMl`Xy0R?lq)nMG2=-b**Pxl-@PKm3sQs zLW=$$Ag*JYi*8bZHi7-i#Pq93Jm!Mgn}Npz5%AzE;9(iY&CK=7Noi@JmjVL9!uOe`I$*6BsVyEa+dKmj*v7Iz_Z)fIro?S+(IPQ2MeJDFW*aCW7IfoSw6*oQ4X-g3iM$1QC3#nh{kFiPlnbga(Pj49;T6e$Bb@V!j~T7;$%LiA!b1-ccu zlEPn3>69=ae2bsCK{z%48lvDkVlIgk(Rbr?kASBX0Tbef&%p$GcsWIn8ZG0vX4zi0aSu^;H1TSxm`0VU zS`Wo??keD6pOuXVTGcF!zArgbkeL8)F|2BXv8`!RQ(5l)pYA-!TS0S0EmPL}@deeh$a zCQ0uIK?m68u3JbHTN_-_*+Ho#FDf=-S57BJ;BN*@9s>cBYRe)#vLvW`bQuv^8q?Sz zqSGM|RWlY2NqOEZ^x%hv%MS6Tt3}9I6H#cAL?|ylVdJGUdBtcUOtaZQj1O&-rE5{R zCHMTxVfe$8Lf^?UKRf@Msh`pmQ^P4gL1gj_s{Spae z)lAyB%l-eAmH#R!rEouKQNQ8CqINe(yW!hN9Bt4zJXW{Ume=i;z{C!i4@(g523pD@ z75H{OIXsGyRtjGUfNtEZHr3P-F|6=J>>ck2SxA@Cv!@_@6hD~$h%VvQ#2Tx%bqup$ zghI9gulG$3@I`d&pivk40dJ^9)@;;*)v0v*DeQg-srTq02#;mj`!bt5S*!e;j?cuMH?CYS zWj8kx!5*Gb*5diAyMf%t!aMRv{NW21MWCVo28r}doL9R`?u1zvYl&CrWBpk=Qf`5Q z+SHrk!6bvVhgcN3b($IaQbY&MY1=d;p|h@ZGS+Ta8tya~fqoKuD2Q-B;Tj(#v9dSZ zVkd?uIKsR?-O$o4zF%UB2zf$Z!7>$gke2JyvzOFn96= z3N0U=0pCTl?wUm7u1n+4td61ie^p|l5^juz|8w-(ADW*@;HPE-3Ms+&Oimny zXjnijAU_krWE^-~fq#7HBupHurM)u+g1Nqr3h;NJ(pY)01jqJpygR&G1JLl857Xf= z^Ji_(>+golhKq_SDj(ey;{qBgTw`s%e*WvZ4#qNvu2^WXc>^RfM$iE zwiF0)vguQf4X|s-sGhzP7fjKeaX(RXe%#M}1f8p=N5Y*ql@v}d>n+b$is`<%mHtMW z``LzlMD^kGndxFoQ)xuuD%yFjTUUPF&UI^2fw3(Vw63I(KKG8v#isdw+%$nR#?!mv zg-<>FR`2_q?)#CVKiuQ`nclSKfg@!U-Bm-4$^9S~J42qmn0n7x_U?O5-@)WB)wrh# zR4F#stTvbh(|Md8OyhI=Wt&VW_!||^qtM@I)^vQ#j_tIG;C6T6V_3xy^gN~0VG5)$ z@J-9W^ZcwGfhiKS8x;}J=|2@#i0m-**R&EoMb+DC#fB8Vm)s3&@-CI!>Llm@_w-Hc ziELNPix#^mtxHBZj;z@#0*gCZ&A9uVOATgWHxv=)H=lN~6QOU`FH@J-$=YO7bSWU4YXkpOy!=?HG2 zG8a02Y&+YJ&O$Ua_K$jyC=#jQ?-;ZLRFEo!vUKL@9tN$Q{~k=iZ1@eVWvfT~Ng>>b z?b7c7vriaS@f_*~ApIU438k^j)7Ij_0(N;pm(75^60g!WY?Gpm?BhN#4E)U*KjEZff49;2*axQedl`c_k?~D=;Bo|Nesq_Op$txi_*U zA%%plvzzfEk?~cZLJ21SB;^+T;}Qj-u1t>|mF=>5YnYdJ9pz==B`3kc$0?FNQ)G=% z_|#FJ7T%bm3^XB$Cxs(?&;d=R`DXRqd*;=K1{0C7 zR-+selrJ>&y%LvXhj?6Pt1F2zPtzO&d|O7-r%pj@wz8}D5_F4wi{L=q!JRurF$ZH0 z#YznDSf+ia0Ij+*G6N=yg*}{m4@~JXtycoUZP01}uLimd1e`i^8*)LR9u=5^0tq`% zF4F+>$)Dj1tlm8oNK}&az55VI93^+7F9kbX09_V)?+v7gqErP-tg#pDEhhFD(`>QD zo_1qm)F>A09gW5UY{3dFEMV`wJn!ZV-v7*EZu#5S(!kmGeNI2;ITK5pznXVe#I~FU zN;q!3{rLj8p}qZS0)K6C=Up|anLF|LYj!nPj^tNO4k`Pfe3VzU^5bFEs=Ypy#6Ob! zM7q_}Rj1GkiQ>7IASUaz3&kkec${cSwE7FV5L*h>zNpS0tLqamix0?ZUp}LTW-QUv zz6to){V3FZZKur>w+qqP;f1P#$?Rag7UNO6B+^%F5fm=f?nj>FJuvt{w}KrRmd#fK zH%DhA7K}M?Hh{bi_k-uNAV1V*kYuM9Hej?Sg2VKo!dl&gDpuULdZLvRc@8gEpn)D} zrTYn}5-HUjM&;`E3ZB2U`;3(NDT@L{^Duqte%Wzx>8}p+;^mviT-kjzdsBYk=E!4- zc_R;>4dZ%?F-p zx5ArK^?1Bw{X=ZH#fEib!+ynZ4Yx$9O+TcM6DRq@+O`Bcipo@2SfCza@%uCkv2mKJ zGxU*%<)YlB8*ZAvw0E49Fh7B{IE1`K8cHzOM!WP>>|u-mJL*_ai+vQIFY4ucVJ!xX zHHm51qMuC=GpLq6jnc&B9wwL`nox~(XH`AdI%X8zLFW=`zFPOS2zd187MYK{kJF41hOrcc73sLa~f5^Rh!(f+`I$wR|@ zK5D@1nnzoX$u|p^{rrTrXgjOZf({Hbc%JxpiAD_(JIaJP-W1B;hDPaAa8^ulYgML` zCmIyuy+X9*WQh``oO}^d!@;%d_X}R|d&G>G`O$1p2u5N99nv=_yfn&p3YYzQ-~7vj z{GG?LHeCta+~HW4ywQiw1yH%eAHFv7(rkm-&^5@Kz>#WXz-JVyx%d>1v@#?~wHsiY zj>)&3%YV7c#z#yq6LqhOx{Kuvv(YdFVZ4ow8|HJ=%JdClU%Da77v8&^e_4G}2HKxN zcSve+0tQf3>Q9@G$hQiX{c_Lzxh-l&=lLDk9Z!TO?rHgSFH%CoD!7+nBS(A&-Rl*P z>qgaN_q3r__6W}JHQD}XQuw0q6sP#^9Ccg?KEpE&T_tr=34WvvNl4+)ccm>ys% ze!k5@I?Rk)(3yq&P$H_$#eVxiN^)k-|! z+ZCj?sny#g1h=uJ!lN(<6~f3@ZZd$`iQF^zXo_Rs@hh7gfty25v@0G`wC{vtbJ3>o zjLrokjCLoT;CA<%Vc)-iR~NWLI7D4GbBN1Zqvlkp7S*I$s8kEh(E^p8qZVpXrRUVb z+}Rt_jp#bHT6Q3bd|F<4{`AIGFzpc;R!`Bs&`Yck85%yf>KO@`mn=~|@+1#xG(31u zA}Xdoym|k6@|(90DnP8NGWiZ9mEQRv_;}Kl^kZ3Dt_E&tbu#hJ=-cf7E!Vbm zIMVe}>hbIVDt~$iRLCr2tj%Avyx+p9o)jy^SPipmlDdID$NOQ-_r8di)RUMqMWUdZ zyy1)r-kpSZ(;i*g_d0NY$fFok9=C_V8t$t37(tA6!sh8}!1>wJRZfc+dPqqUeyoCr@U`hzC@*nb!`^s1alY&)I(OnTE9{72erM&b&gm9}%Nk~8~Q=d{0^fI?g z>RkkJCyL5JEq4C;JWR=FOPM8X*P`f%v?wNSaW6Mo1$1BW8>*Y?Vk>;!^Q&4;^J(8uQXw9r<-Y(Fo*M(k@2ph)lH(0%~OPP?1lJV zD?J*IH@fB&8ve;fbhEs;#tG!agCZ|iQ;{;k^a)K_L>(8ejSH|}U9!w!roWshmG7>& zzv}jS-)s@7=_hD(B1Y4Ccc{_Ba^K>K4f*&w|29Wxr%2Lfk(v5`MekKzo#=DYvUIuK zOr`mvoSd`VzUurM-vjiXhCma2k?+bAMG9V=_XM0c&KhFf#cO@{iq0Cx!JUEq*!EwX7{fPTh#%dyjnS((MU}t5OkfjX_dM-7 z>UCO#Yh{Tr%I@hJ!sZTf?bY5$MSn?hXb*IS-sY6x2j($5npln@;bp>9SFJ3eG9Cbu0$y>UiY!D~Rk7XKhr;4Z@u8)GHhKbL+ z31w?1mT|XPAfScmqYq2P%oJ}iU+Oq3aeh2sDXD^67;2-v`dA#UQAYfjL_cL-)Li`K zo@{k^vXvVUJbzcpjIQ&$E)En8!}N&<eJ?qZOh=GZ`AB%l>lr53dLppY9NrjPK@9Vq>3Fb2!yOEh)k!wmqmRcC_FS+f(T3{Q ziS~y!|Dqg+eRmFgY)^94T_@29k2TcAFElY8On#^yZQdTViJu?0*ca9R&1#v-m0Vr=^FuQ_;bR4bVMHWVQb(O+%)<#7 z%~47Ho83QUm$iM%?teHb8hoY=9JBL}6FYVtKD=X8pI&1|4>V)3cdPiMCXH=L*Kb&} z@7+zvZfT~L=%6LwGP|_4;nI%Q2Nr)cyMzXpnf}+yQ%{I5I5YJzI3>nJQ5&jrpXU?wF|2ZEAqqvLEB&w#Bmy3(dK6_#ss@K0^ZunHSw# zK-~|kyLntoI%**7mv{Fu@_X}t1`WlVspHa$N9{RvwqIn3(!+hqk3L#9+}Xt}I>Sj8xqyZ<%;@52tEQ;7@UBUC)d>{AWO; z^V5t}Ri7M39gcQey>TJC&nW#wR?_~!>VH4yMb5LUPxB)&R6XH=4J@xFVqb7!dx%Kt ztl=K(I}fT=;*V*l-c$;;%w#?qgu2nxQ0Bt%3};Q6$5OkRTsN%9{Ga9DK4L}A{cI0p zlz+shrJNbDH9cTFCb6Av@7}N`Tz%^vgyyS{U$A?M+^%_y3(*=hE8R%IdvOwZ45aep z-7ok^%GLB^7JhrM>HqomfH9M7T#OTJcWiG_59X^szfc&F_bPUFJq;!#+b9_tde~?K zH}CZ7CU<@m+2P5|HrgNa^OhJXvNTtH;UPvMBT7*p&ZDVfo<`5Owx6|^)tB>X&=Hv* zzcjw5Xm1=LPdf58)$(mnAek`8emv(hd%FG0oTGNNu?GgZCTk?H03uFSHIEu0vRc7| z5n6jtd+*nzgh*<=4H%96#;HZ_Qt+wk`P_=?|}$K`+pV(`1ZZuRx6DG^x&2u(JSlct~Ey2u;)v z(_6{4GX@*)ngf*Fz)kIsBwk6~b0T06_Ek6Waol97TMJNwZ{+h0+(bVsrRh!NdMAd! z<2m2T3)~cC+}e3KUMu|HmJJ zxroo*d=>FLp>V?Gsnw6GYwUUUx{n^&pBOt{+>`p|2=9~W@eS&y#`o@>YJ2oB-FDKf zeu%#cwfgby)3*QH=|6Vy=~3~${&m{VaRK+y#}lLSP|X1o)AJFiuhomX^!QQU<;Rcn zI@Yfj6;sc=N9^ECcu%5Avzj*|{~$8Mt2S!z-`>w)hT8N#Rr(>=4}q7l6dgSgkeiX8 zaTS#vUKF6fd5bTH8BB%iGWbwR?#^SGZbovfYuQU0&%^y+KMgXj$Jww99sS<|sK<=! zhf*|k08hXF2NT(UhO5V6!&ENcqt0GN6(%{=*JAV&jT3s`UQXzP+b0bl#y`v6jQ-x7 z|Lvo)`Z}H28F{%$C&J9CtC{f8(1E5>2kysJFg4$%&yBxIQ(MQ2wKh)V3YqAhWxN+{ za3S51mUAj+cYa!q7mgrN8$4n6=|8vbKDa+^WRITXMh-P&g?GCyNsXIibtx>!%DQ{6 zOLn+;Ytw%rE~Y~zdLM-DMAhL>F|D9q%GU9;Pn_dnC_ zM7l3ps+%5XVQ03DGxJLa_VHfviA&QG#K%^d7Equ@TI04)HbOZ6ojvgjR?;q z^*Dm;lKW9J&g_mku~)vgySJ^*c@J~(KJQ2B&!W9Z)7newVA?H@TQqj@I2N}*N>+cS zgYx3xBfl9}b@jh@CMMyN7K~dsc9HQGcVw=HR!^ywEI#q3Z|mS|V|&7hr&L_F-bUrb z=J{h`A>JuOqEkI2ei54usyl;r$-@^8Up#^(?Q17988}d8*xR*gB-8yQUaN+GJ$S(o zUaJztDeaBy{7aVoo>*>LGkG%_ln3v8{OU9q_-KtjaBoL3i`T^k>`4D+$!@b=F;Do( zyO!==vU{no{$9Qalyg>G_|~?DSEX8-K8FS-U|`+xpFtZDzgoRate;6K&<+muy|Sm8C>nmAjcl zjC^$Y;cpMD^gYmAbEPT`B>oSD<-2l>l?qNztZ+heqPu&mO3Vih!{6fHuZBtEt1O(fA( z+>27s(1OSAGaVfwlh4$kb(*MU(WmN@#as(B57A#d<8yvigk_@jc|OXHM$r|t=hFfD zXpPND*FQ-X4XL$WpAL(!t$I62jBr&fLwCGIM{YhsS<9cq3r!y&J{AMy$V81ClnaMU zDS9bu%kSt?E*Qt#=cAzP`1h{Ln!Z#_7fT~4mI@Fn(-LnKPzn`DltjOWC><1`Ucx_F zn}^gvi(z(1RU2?kHy9YaHwixJ*YgfM2|Q5mS`>UzjrUsh4>v?b1O;IQtYs?R%r;~; zyC~!fXmHj`d?R#?>QK3cREFSVl|vM<#~qJ~mxK?ibDPpMOtk3B5;4AyME;COb%zC~C&Op^t;+}R2Oes8yA$Lw z>CCI@?X8J&P=l}*#ZkMm4B7nh;x|O=cJF_hg=&%)atg4{uixgxA*y=o{3*2ik1wneXvAW_GnPu53?&n$XtNemJ% z`A#Pb4!T{q-hs9beD1z8gZ67^O9!c~g!wqAJ`Z2ZDgKNwAop(mgR2;DR(&#$K{86CwWyxQEY{P<^78)dpODz2f0P-Az3H9i9ct9P z6^(aL;pWvBFI!xp3g%eTZY&ZPj$IbaK3aqc36J5d;#9l(M z0rcDs>{EF?q3vXB@% zs@oA`X#TVSF@-R#H0?eWVv1BQP;U(}`g;^3g~u@&6+h8Usiw&lLzdd65EJ|0x?A0r z(pizfNR2L{jeYJ#L)Uj4=$Q{+_QJ6AQ)EFaSUVR11QGuH3}r_`4WHHkbl=Cu;FN~GHKZc^~c z+vlCGpt%B5tq91i)<6qLd|8nr3Zrht04o0$}a&aC$ z&PPR-GH9>cdbH8+XmNuJP#NzYEU?=ThSR%Ld2o1~S$ynGz8ym-k|HlxhcA4uyh0=* zJG>@eb4`<2L-}s^RH&~UGcrxQ_jh7^TZ}~in4Q8997e$u8Yiib5H?n#YOz#_D)tUOl6-T2R^GOUfoTo0 zqHYd7ay~$PK^0HNq7teFi2+oJ<-KBg58Tdc!18*qyvm$4?nH1LnBfm1ONEI2Op!+Riu{HWj-RMoFGomYp zro|;Run)>XQ@7{5oFa%lm%6lUd1#q#+Fn*!c%S-fP`ON7~>b2y>sbjvGP<3^j4^;GB{u>&a7n~crVAR6Yg@F*LSKGv3 zB-dBc-5sY|Ho915Wn1iV=)*!EUCA%HdKI4Ry1pE#+#D7gSL&(7^*d%Wt2O4?j~}($ zkAD~!%pb+~>(5`)=HZw(l?&?_Qo|XIa_p6>FJFgUCNJ{=tk*&%wR;GuloBTf*eO{S zAJQVtBCFBeNW!hRmAcPJ74{h%hF?X6Yi*sP+$r@TQkj-P{RN68~I`iWS4CVkm}fXtGtA8GlR$oF=L zOigbp;zUz9GD)Ldl!jfh;39GB-#ruUvxLf$M(1N^*^O=DmZlF9iDFPBwV|D8Bhx3| z*h%earzBn@DN%_~L`|Eh!}k8p_QsPckwMc+Cp^W+)^US`v|hgfO=1st8U~i$uEUp`n+B zdU3VDFZxRp`BBeA^qeC%4R1{W~-`t5~H8<_wY^Fmqk3sPLN)4Y({)^sX|dmdbx;iH`-c1z#HBaEL4J zs26E)S;z$$r53%59xi%WbcuuhHd|&`u)>11?x1hKf|i%Dll>4XKGV>WR!~a`bFe}y zvFINqUgsZsCW?Ppn4LDF!|v;xW~pb6XLUh4B!(&Y=0aYcBZqTHMTuB|dRlz{!)MPO zJ7lvT8XVY)7_UW1e5)2s>>^fY(F8eF zFK~Mz&JG?Uk?h^9!gd&bKTR#g5LciUhbc^Ynl~eVYTo2nj{x+8@)*$=6@=l`w}+wK zrF-S&?!D?dAzP-Kx1!4j3^G`M)jV9M)rH0_0 zgt8#I!?2(b^ZyQ_2y%7M+C@mzJca5~rG(%UDc6pjzP|N!;O`-)TV3maf@`9ZH3fCi zJP5he+#S&=7f{cRdKXaBFz!VzKD_$M7{E{6rai*vTG!NzXkbden3zgslCB#c-S7IDVoJUAP+PCNfR~fbBBoJzwN)KFaJCB0__NO`|*1RX0Yl* z?sEo-hQgttmR&CwhnmR}`E(;6l0FPR*sXZ?=?lM?1a4{bXXm1k2f0&7N4voXK0(Ng zapzT~x9%{0N}e2e6WH^Qhro|5xmy-V(bjGx zaJXR!7XrKuOYX5H80o6Yl{8mgIP&Y%d86q&H)r|im!YjYb|5Jw@MLcve1uActn0WS z^rEpE&bKQaT!=feVT@bCYdXw1I)@V2{3 ztXzOECG|uOIpoocM=c)1R3#QpgR0bsyCU%sDq^ZK`Ylya&|~>VR5vd;JAT2Kg`*Y) z;xqJOXBDTTJe%_1ZQ75@WHvwI{0RuFGnhZln7}qkV7sDq@P* zq2af%(wa`Td$ZEjirzN-YJb3J$%UepGwfPx)=`gF)W5_mo1RStqQI&zmQ-C#6Av^@ z3DZ|Px#_E}H(^Sm@758l~}3q+$de+G^^8F|BD7P5eVf?TgEP zDqX|b9D*g>nb3#MN_?_V_|or^XbgK_6NZNAQ=J$#%aoAW&2s;IQD*XaEXuhf<|#3k z)amK>$`qL14Y_-j(r}F*VK9c#?yeXbN`q<25oU>5`h2BRkA+RDs=Iy{GZpnac$sPjfqRQ--?B|FT)v$PStPYO~L)g|iEK)tTi zEuGDP)cVhSY*F#grE>jZlRS^Ek-3Jn|;#=Qxx?C zq;{l>Z0KP!#=*+Uj1JRhIx&=$$wK*?Cakqz6CR3M6ms9S#xT_x!oL2Lef=JJ)8t;; z*w;T;&>W4}*L;d9m#)&N31@#3Da)IhFu{t3M-;ulIlO2uBWJb7ds0NS)VfdITKs>k zlCSJIety%1z|EbGrCb?vkoUWy=$eQ7J-uOoWr!dR!^8ABPK@E;i={d6vHFWdC!)As zda6$!aCRpk-{2W|tzcHrT78ffHbP=Yh18)|lY)07B5)HbUOM?A@MJAi=!AeNygE?J z-zoSpsu=I*E^1g7rr&YmcUip)&lr=~Vt>L8`_++i^G?BM>ppW==JR{BmMgO{1&~4$ zx*I9`qfwcmm=UDDM6~`1mtuGqDRyX+w!MPe9v@y(7?c&!MQ#~apS*|Rv9j}zi<_@( zjmqqDecZlt#_l5RNw{|}NPT`mRMapnOkd(es;oZa(&=cyq--p)Keqa#Qz2U4L@PrF z8eFKp@wn?+=(czcHKnTLM`OBdPYA$z-VhPax(qapC|#kE7Pilxn4Px64AfX@84Y=s9rNw!dDGlOFXa(E7e>D!%{C$}@PG8kaR`kWW8c!j<2 z@*el6PpK})zC3-@!-)M)7tjpN4KLiMK!sf~SC}=-3e(p)G2XDJ4L5b>-_ht|FBTUR zb+5;L*SAI@9h!$+F52qGPqCzrdvA-!5#v)@E2&dGUWdv2eF&{hl-2znSR;Mah_p7; za9Ub&0JIJ8)n6#6GA-?V05#k|Rf@lQ;EOLrgoe~G{Yxh%aJF>KymS8Mc`UR$T+z&& z*mFzRa}N14GP6h@n%3X&+>hs3`?~lfh!&PM)5MhX`jnee2=|=xx>ffS*E03xMhluQ zNW%#31@yDh-HKsWd}qJuI>)W>fng1DIUuzeSfWwAx5WyRqP{^g4WncUKVz7tx=`7w z-%UVeeio1*$SSFCsOnVH6Y*%cDNJ8brgFz~sCITgv-L0{m;RM6FiZMM5yY-w+Ha9GRI?jLMr zeO3X+huA3l^|y)PHdM5F;v=3=`A{5Q z!X-Y@_&}k<)jWbW^QE#xo z`gkh7#RUCkqRf$9)m;CUX1ctiOet1yXgAqziY$h|?^^g~hC(&gp@1-4tRuF6Q$1J`oSjvrW;y7f5c zk~-~6X8Z0yMiYz)Qj0wx6z+%c2qPg%AY}f@80|KgmWquUO(3qmNPR@Uu{qIThnOw< zi63k?giTRzv-Lk1*6(zPq6qq&k4}!%XS4O|L^~~>t^bsoG^9$@GyEW%|LHS$A{^tm zO5vf8(A4KflYEEj)}>}21*avVK(PdH1-JN(>OR3cL4IPB?JhULJq|?WFDuyTP+zjZ zO@_e94zVVJrm?`(Nd0qn*iuAah0U6JkA2+IFzX?{)u(CU-RYrHTo`mFqPyHGu7Sae z_obAiozD_em96bFyWAY_DpERSV^}uU*dB1ROLf{xZW}q$!5M0V_eVqC5{EbvL7%a_ zNs;sMns!0_nsr>;XUmid~TedF5bg^`yM!{`%Te3^`AQ;t3MkFP+8A;X5 z_|==bQTeVls-rv&RbIU$-%Ls|`|)_hKzrU>M)$G$^#7O9&B4kb^{!B848K5oN;UAc zLFsTw;?YsVF1a5KETeYqtx&D&-?BSqVuk;2+^#fH`EOpwV|=ji(5$kmQvib9#IA~@ zIuKx$j7O(Ty=-`CM`L^1ze%3{|3mWHWA=ZNJf?21#06H~fRAu}F57eH-($UnG1h1ESRbN=4R??Ax+qcJj`Mdq z^Els;#p8UdG0rt(5|`pBTPGN~Ntk}ui58N&&utz*8e{S+o2@l%&}^&!YrKx3flMg> zzs75>d%W^n;m6Vc2lI8FXofqQjk^xLj~ebN`~FWRyl<0?C#y{O#fD^C1~|LBwxPEF z)vU)cxj`pg){qQ8;}z;`Z<;bp!{x&?Zp`q;`Y}?-r_kGtSQJ_&n zQqWMQiQZ6Xw7d02^OI(grQZ3x$Z{1Q=jNOIw)uv=ZN7RnCC>Wv{5=cmXTQi^#(kF~ z>YC)Ltkoptg-j8QR>R$Y{YZHgsV6WNqPYXtdfS1`b*s}eg`4g=chjA0G~L$RbQ^Qi zonbUx5n@9>tEXt|#0aO?9oJaCSitU2<@9P#Uz1`KUk2*F!gSuIFyetmM5*ye)yKZs zsGz46KiJ@H^K|tq@`9I}D(5&9x~gB&#CP<45eoH(lK4(!X*7>Mh{p#swMhIb`|+lf zYW&1ZPkiDOb&9;iI&pyS_NGfkt_Gp>yR6^CaDH$}o=L5#Iy0W3aXUE`Ru-czVvM31 zT{?qDH|-GDjnRZ&R;;u`;))sL6fKHEOH|#}4_2*6tPG_us81aFNctlzWz36QsEsL* zxQ(QwG3L6fXn{7yjyIunnTB36SLp()o=^GWUX;lw$h#Iyu)gA;jxR)|8yHv=#vO8p z;@)^XXl$RYT<&YK(G+ztHHb!){;a(aU$VEaCdxc0ziOg?!4>&D%+xirtL5SOYsL~Y z%l4A-+B#6hG5N;Vm+*d(d!b<;{-hKg)nEe+F*vm^C| z3XPWxXjQ~p zoDL6n*w`y?yW^PT9Z77@Wwb2Yd?)LtGkPBe|W#w-+08_!H_KXIS7A(|G`YV}oq-6hob8SLDSJ9?ube9!e{yS3G)2`h9nV zZAR;2aeg#9eiz4PbrBjPjI(B|v7Zcss?-t-6lgqXf3d$}ozoonw&15C^)4e?7;#l7 z&7xj$2I5^9&E4YO|AN>%qut(FeHpFX-cbekCuh3KE7uBwED?!vtM~>a4GZ4iwRrpa z%(P2^TRNPKzc#jb=N~y+E^m#_>Uw?bzRUoUcPHMv8|2s7f{EFfX2Uz23xf(#^Co&1 zMe&}&YV2b*wy|OEsxb^(!KG<8cm=CbfyO2oGiIH!c(mc(q?XPpT{6zpW}n?&!VMSi z7Y~bzYdehIH)E$aC6aF)8pO(=aXv-Eg=P{@s;9#v)H^3ey|4DxPA7+M&8`6agK7R{<(tDz)k-adaL z6VvQQy-ajMy^cOyj=TY|QFqy>>7g`@dc>iJq(8)0Y}7?Ist&0n(UcF;4A>kr=D&F- z7+bnpyDg@j*Qebu3h9eX{j%;MZe>aa&l_sx=F0j5baE#kQ)gCPrcph%85wbbqu0Wa;i+f1d=*(O#d}u$NdmajP_+b?SClE{ z462^p$Ll}@ni^ajOG>U^>+ghLNoo;q25im~HfM4uji$cw=qqu{n%2r>tP1D3bZe8J zk?y^IPvCUVL4DL?Xf_A+|R79;>lYV&Rq9R(LdBMIgIv} ztq6}ZZ*opspRl(k7h*-;BWHvo#KhS8U^jM0jiT~Id=w3!YVtphuRVP(h#nkZVt3l&qXI0?dt4adP)m7; zemlXGCuS!qf8O;CC(A;UXiq)$_ELC)#vhj;S1*yox8gLtQn(pPyefQbgO__;pDuw% z8BTFD1FhF6K2MB_qRA8@Z}?;F+3X;Ckbt#DXd99bb?dyBy`UYxbMf>|-&hl#>#H<9 z5)zH$UKVX^6t7s`D|)Pm&91?Um}iAA7ujg%GWNEb_eN9ndv2HfL!<6_Vqp|5G6bDo zlWB3g`v++@H8YYZDdK=3=+CrW)%*)s1-9m93;%0;t7C zs`nTbxU(&`!q4j7A-d&#>fRw-8KoA5CHB)ODNoFZVp?BA-uUObEPD`f<{J_l)*^+H zIv(IC_?^6a>C7!(-X<>54BjUAKMW0N#Hilc> zh0T}$yJMAT}*!&o$epu0uxXqubQGYhyP{z#W|6gpq1$C0rK5rlq)RfjUK-)PUl;xG%6ct3@lp*A;h{Rjha|X^T~ow8h=!Om=R&?=v^u z{qFz${64E~%FLNFXXZTT%y~|~xrF7vu+WbZzMP<+(&3O98* zqJApO^?&K+>+TKD%SpQ_)@DYG2`d@KuC%vL7)Z`R}=t*!hR+(uPf8_d0L4<)a|BiOh zI`@@BpMex50MCXZy6OQuI79(_xbBO+YxnbmGVsQGxHdoNC*bVBGvxQ;68YD1lEaa<>cQF?^KntAp!~95JeGEObp0NUR}O_;~X{gdNdHmb^{J;3zjf zE7F8~$G=eQBz40oYTCB_1IG--82+`wYid#;ozh6dWi2=w4CZavy=M1b%wfhHnwP}_ zruB!WkSra1hJ0UNpeA}gNPP}$_AfANr~$KkHZo?u&HULepc!kg;WBJ(6{P|HESf%R zTf{~OB2;=`7i(I-bIs1(MzsliIZUe|f2RSTH594pKobrBlT44!VMF+U(klNzH;b+} zpj*3tpc`(B(OJ~mPF3t%|AU^M(jUO7h9^KrqcwDd8z-M`c)$@zp3O10;pzI_Yj$CU zt;}?l=gNFqUtl0)s0LwiuP(UrWG=zcNWg58N&%#&m(zN|Qm`lv|GTG#r zsX`I^GLW|vT06F3k7gImJae_?^#x+rRHtgHdwGEx>uD^%0`yhl6zJ;%Sp!&U09Z#n z04tL|K)J1*s@eB=AXeksGzbt&maS9 zUbP%+4LV2fy~dQdguYWBOgD8smTfN>sGamZhuLfRpaFG0_1#b+qNc(UX&^7rX#uIKy&> znxrp&U;FzXM*dj%nNK~4VGs}lN+ZLcKc@P>P%AybyYMb%>cTS$+}VH*=B;JL@*pk5 ztz-LB3*AynNXmcc0T1nPov&q0N1J$8Gj)ZBaqGgNjas@d4y`?WMDuCi36(a6$;5;n zg@@^K`OVAYR7c-H1xtKx5dRez0>}D=NHdx;Uu6EMp@@q&$UFa@3x4_SCIKYI6-s!_ z=4K(hVFwIkI@o#k0vA#HMn^4@03g6%9T|M_H zt*E^CCkbhI3j%!yb)CpU1_@~4t>w!b<6hb7iQ~V>zh4du&as#3Zn5-E0g3@62(!I;_8ZmHQ=0l%U;}S~4StJw8^m7$8obh>mq>6v zl8rkR74=Qa5Z$!0QDxhf|G|WP0w%n~f*NVIPYl)HOto^(KC5@O85#PJ zasD2W$U*+`F;z01wzJ<5WPz#hIb3BAcik~2E3Y+`NBFvydhaKTm1K?3EtUc#7^>r=t-u&EJkZsIX z$-;K%)Pw4;ih;5HJi$e0)xRZjP^f}>8H6pxWq!iqPT0u-du#8a<}R87-u8TEQMQs~ zy_sXoP??$S)S0cJb9hBxwKHF=1o3Tdon8G!qK`y#%h(_u%S*~m%W-xx+rb5-&*)w3 zY+Dz#6vG*w3F*j7R{NB(zT|fHw_V+j>K?R(fg1`9g3sci7=_6(SrpecpJX?5;d0CGO)OU$uuCtQaVQ?V{Pg!zU{d0*mC(D>yz9nNyz1d(HV58c_Ro@l(tw{I&EOJnC ztNP-sjG|m6JV5F&v`Is%BEPt2;_ z+(DY{z@x@yJ++%@8NGwOav;TsWe-vMSS@qg`#P7XePwlkx=k5kVuN|CI#{GP7*UQ& z66H{^0=F3vq#I)55xm&!J^|ath*c31cE656!2yLI>*%7UB6}9*#BBh}{8-ug$a>9Y z%=8#$j5Ts@8&qm0Y*asYE24i8RTS>~G5r;!;}fW%V#rRQPC>^_aHl0^_bE(5cWjiY z9iKr(6zxP>VgZ||Y!r3NpVB@u58T3i?~;tX`Ah=s)EvaknreDv(&!9f6-&v8y+J0rvp5V9E{~4-E4`tk zcD|0K-rMe3uU;|cVP3=21U|oXg2EegIGmn&=P)%O|2q?-V>?Xb{;VO=f#j3^;uZHv z;{*J@r52Bb_9z6}gGJB~M1`N{S z?E-2n^R}C~@%pE4^;75*#c)EiF((hymOwtD{3RxbCb1ea`-!e9+bG0JRjwFMsKd;x zimqoeuP}$V@Z~khUkOH4L9*GB60g;|bfU@NGR65BK3#dKeL}MpEfVW78?DFdIB&$N zYLz0xz|x8{`A`SjeNhrzC7XP(-AkO*yzHh-6Oo@{8`%V93stlhpEDj;`Pq>1Q%U1?%vGJcicD>M%Y;Ve9w;7yYi@++=c(rI(LP+#nvnPrGQzCX@EO zu-k6F@;sZ`i6R8oOeeK)kdG^fCW)HmO)LiU$=2H!jen}~W^{;%PYPeq*w=78fr4X{ z_MbOd)*?|)12Cy0fe+TDL`Gq~Uzo*ur?1*&E`2)LeSHG6nV)VG6--Aj6 zU6h0Rf{3!`a#Y5{OE=Opv!Zgy3*>1uDtCPjL9lFy@wNnFBrCYX3r`q-E4wd`NQzz* z;A?nVLcv3nwx2g$-W(!y4%Xo(c~@PsIob*lqP(dyO`ud3rtunu$Fe^<^i(}d9 z&Z?EqWMvuZK8aZwQ)p_Cy3j?V#T7=iTbZKM;?i$l$Vb`~_L}>&)JqP#LWvDTo|>Ke>0JT<}2jK=Yb@H ze5t`KdC@_7&JXS|v37Kox|n!vniZt3aEa~!6)Jd*Fo}dyMAm(~`7%k_@X_GuITrq7 z34FW**B^}GBW24=t0UF;JG3%1$-JT< zwaf(m@MSuuUY0~!sXsjx-{A)OEJ)q!qEE$l&zfS9?Lcr4d>JylMcoo4aL&i3cqEvB z%V!MsWtp=1h1GG=_?z0_%qr-HCq;>^v6oQDK&5R$6K!icVr#Ca@c?X1l+|M$T}pqI zQ`OpvA`W<=TJm0<1^xh__mT~4`z0}rJJ%-*}um@bPu3Pwfw?zfv zCv;PxtwAbt(RQ8T&jd2GGWE=&A(>aj>GjU08W1k9=->0pM->^Kh+UhdY8YD=K0m>jfQ5PjelldQ{IfInED1 z78^8~*Ym|^qG3@Cm-;nnL{dMB!C%tFS1-79k;nL9V)*Prg;Ijl^9b{uCLt~P=k&Qs z;5oOo(h9}At+MOd3I;C{ZX=v}27iUCpv z46%*@QImZor}bGHxFQ(sb0&$dWHq=K@vzd%=$r=xFr@T>z*GmYV=wL00`rW_>sj<7 z-sD%vEa`o| zP_3`rVOw#pyp2V;{hVzNR=4nJZo@)xY`n54(1y63DtYE`zWHYkzKO-NMXbJTUfkZ7 zjB!c_6Q)`zrV8%H!?ab5s{gfxd{$BXI%>4F9?eoKDF$#g`;!;zFJ)C$`#%fj_a!mZ zD-!=r4HjRlX6QQbu|G`>R~O{dX!Lq2WNYEr^KpTZj4XmC%KE~c5GBEJsL*gc0*e0< zil1M|_J#5!e_9x>ehJ0n9aH)FiM8OO@tjBT15$c_+#V+gkGK{ka*0PX-JqF2Q+fB& zXc^+ltEm5KYQC!;MK@MLK9IVN3+O!5*YIm<*OTLJ<{Nj1exPe>Y0Guvk-WRHH~rEc z(Gl>Br3A^lvo_R8MWpq;J^d&OjHSbt`wxvi-N8@EC={ZvZ1GSAbV*Wj>JW2R3U)`T;bM29y5Wvu9j?mJjx$kC{sm+F2B? zZp^1eZ}^vmEE9^YibKxE;#U09Nv)jZ>q6t0qm-{~r(i4TvyH#2Bg{)Umjb8aSwx$S=J~3#JEd zbjJn6Wc=6-IwLB0)-tD}9&oV(0#d(4Fcp#^#{Dx3V!0M#+(K%urM*%y@F#RkhRNGf zsZX5JI-&7$vE~k#<=Q5=v6NnYQetpQ#U4&uzmo?0WvM#FaD9{7<1OnU&S(z_w*MlC z-)DE|K9Xjef+Y-`!j3BNV$2Hj$D5-kITa3QXO_+Ep1meKCoWTM5t*o zlUo;S6`q|U`zWnHZ?v)rL5&ICq!yp>0T+>hxO@oyW z_v5X2nIbl)ejprJ(Lt(D#v(W{{CsTSWN!4uXTpK?<+^@N8k4Rc^~GPhi!Wbr-9=Hj z<4F5PdktL94@Bjo>-g_w&NSq|&)6!~Y_NR{56 z=?fXJ_P-*KT2C#Y{PwQRPEl)7&1rBT>Cj*4X$@P@(AT-ldlPwCU002{r4`KVkWL+_ zehU1$*{!pQ7~e^5#c-VB1kmPjyfJFH{{3PcqJB@jUVv#9z0mrQ?$l(i>I!utU*ulO zzEgfIv1VT~rj`CI$6Mn*4)#?oYN%qM)c-SfFJ@yD_hgy->+o;Puu6{2^2CJMnBxD!JdV8pteeBgOi#*jS)GwXmN**LAhFp2Zbk^`2;= z_ihn;msON}J~mOHoi-rC?cySfGu(v)5it{La}10dq|I-vF1sPrjTyi(WA z+GQ@+`>HQ2OyV<88%uwOi|fo{qvkeR1xs%2q8K4eB}mdpu_14{>6Nt*VyG|8Y_rZ{ z4WHN0SBzGXH|IZdo4cY-Jwz6^+r~GdvMDC(=|z-@=xsD7OBfl&6k)JX7s`$>U?0UM z%8qJCKRvSM2~Ykaifz*MPwBI$wXgcx!jK>4o1#SF>z=kSwYi$9J%#ywz<(mWsr6`j{VAb&F zSaw;Ij9F^)y>Y1UH`ByGK90{sD(kU`L}(lhyTBPCf%PBM)b4wD*+Hz9KtwY1Y}9Qig5vE^nb$~Q{g z5$hCn2$|UsiK1z`uO^S{|M`a1~sLIgObR1x~cUMBDk5D@vK4$Rx% zL_g3t47f%#iY-BSALTI2V@Zg8yUdW9a=#GXd7s$V#Jt6pjcsy=`kEZUI) zkMuM5EqG<5WwaAVsgl)|WxR+}2&0Wo37h9Rl9FMDm~P& z7FN;BMg7Dn=;ne-dfZo{J5T2Rym9A)nHe_@Qe*PJF*(MU%ydE6Nf{3Q7TohrapYcL zCQnKiGd&aM!(ZZI%bNCYVZ`fhUmD_TD5Zf^<?oGs%P^i)gUkRPG06c7cvWBSyNvs#a5?20bKT1YtJb*u)QZsHDJJReu6wxQ zwrCnUR8cee`%$pxA4Q#AQyWR{Kjf!{VuojQnAWsI%LW>tL*>`A;YpUo9esI&WxP=e zuafe$xo&R07_~9~O<~(OYH$vzZzZ;kk)lTOVX-tU+{G?yZ@}?CoXoNp_Rgg_I9!p= zBd!t$b#)2P_cfwvuzYz3=3~ zYw=0rezl8*?rt}w3{C2>xCQrL!W*V=osj2B(Wv&Vyz)KR;>BBqABUZPRZ{$W?d^@zfUg;|b`F7a!kzhZ3^EHui+4hN|nb%ufnHH^Qb7=DRxQ4dKy zB181VX^HwD?pbq7<7GoZYRahO*pGwsOL!yqZh1|SA8WzKC?T_?o)fzSA$GbF5qxrD z@ipU4fX>v=SyIQC4!rUN-(zt_doEqveYxKDUZjov z&@Ni%dR_?4b}s_XhH&+iI2zi`#j=CcJ~~KdfNGxr-RkbFzyHO}A68zdJ8k9Uq$!E| zpC4JTo<#71@`M{Y!<$XRJbMk@Vy~r?uPk-5^H!~O`2nZID*)@66;%NI^NWD|7ZZ)l5P_VRK_NbO&XJ^M=Hbm@}lve8f2jdx|F!2HgnM!S}6kb)din``ly{6cYzr~6E1i`|+bq_Y&`Bs0PO(+YHsgI4?^E}z*075jJ>JJi0 zzmy&en)@!{4Y)rxR79dUEbDIg@h;rQ!Zz_QTwpvj)zMX!r>Hw!Y^Qc^d+esp*|Zw4 zC(3!rm5r1Z5coC`Gj?`K>exey3w7|0_0BKyzguys?$ni26Q{zK=pF0b6UKdNpauNY zltD?MA2rnDkP1`Mi<$FpuUhxOudk{DHVEch-BoZ*GoPm2&7j(s;YY?mCxd~}Z#e+A z5Gj_umenbkZXJJ%I<0jyU5D#IZ9#RVTWjxbDE?;og}Pvo;xGMAxO^SI8~3X1EL4mO zVq{|ECn%L)&iyd6c44h@tSUlJt=j%EY(sk;2FIxL+?A)8$~Ma6Ux;(`DGX&4PPY@f zb5E5inu*E>4*I`xW8JMUi*X-ep_3A)BCB~9SNTV2O*lpMvjyc5i~rU2(9yk!8W$lt z+S=R{Sn5+GsY^EE<~T`%bnd}2w)n?aB9VDUZ7b*q23No22;}INa6ci4H@_nr9P~5y zQvxSST+dCNc-ML5nckW(6(L-AGrU*&tlAXZMpzmEY-?`aockFsRu0Dul-|9lFO=fXGjzFO1CYSJ_fsW-erjX`M@ zVB2{I+vqszL`ySTh)m3Ww~t*tDY11dOxXmyQF7IoEuiO?6kQK%;C${aoHcFXGaNYo z9Xb$xlHt6cEC8Av8WF9Tv!Vl13D=8!y@2K3&_UKA0 zsQXH1;GEmZXroQ`TJA7`e(qBP>Z7n<#c94?s)u6OBO0l_#ELQ@YL*A9Uc+ zi2K?QhtjuNT*Klqz-Kf-L9C*3enpF1B({phV~`3~SFX|Kk)XFV1PyS-7}XFpzfOOe zg?Gr0G{v%kB9sb%=OlVT`V*Opv7k zNlEKqJ}pn zMn!j?$Q%06*2;Vkm*cos1Crxt5Dg?b4GkQ)oW=+G8C2R!JusiQ^~PnR4Hn?gF} zrT~y``5ZwQ8LUH6Vx?Wp=MHvXBaEco%VI{Hy-6-=aGT;FS(vPj#(06Oqef~GWO+ja zK5zJLA=oAAM2*F8i#6uR3Yw`FM6twn>I(i5d(#?e+nCJ9mx?oD(^*RxMrZ-mDOhmp zlgp$O^}39QI;!mcF~EehCS60#Q)6C-dzEv;en`jAO$7~qr^b#SLlbB`KNdriy7CDg zc6{clAJE4=!~4^o{gYdRBHxdSX(d8lo`{&MSBxUYKgcTcgA$Dd=TV(iL^Vwsk%Wcg zb2#ZBvUav^GW8jMweV+s^mh6-)1e$DMZiX1&t^R0VE-;V!gEdCuE! z=5K<5ru&?98&c9pG{q0yci8$?ti))%ymL3^>%?=vZg+6lr? z4N=gg(m+0m50q$o9l@-BiRV}Kkwx6Bf`N_fo8TRe#j#5&pwN7(;OW3oi2Eawf^S7%cztbd|VccCOl6-Z`c|5uo5ece$KHsi2;9!zguJJw^a8Q(;e)f<;mKRb) z!4qv%-1~H1p;lDmIJKbYvLW&k?mLWE0JMCEB8|L_dhM*N?sm}v^lU&8Hf_#+u8pwW zndKRRPeZA%7lz4JFhaGH)QqAqOagyzm_M)DPR|#!CZLH64u41Kb8Z;emFv2t4yj8m zUS6b{VvZ;^M?r&gn!qjOIRg5q;F;D*gn1KJFoxGzQm8k`b7u0x9JPnE=TeBCf6gkFc9nV6*xpSn zXE5V?_p{$nPj`Jm9ZzVheg?^2W~rMc4D^}1vO+_Ha6{5ysvB>LN{`KWlvafM4%8$k zPFmeUw8}nvd04?y7g%z?gSHZam0JErC zOfQcB^&g;`g}NIXmIf;HKCZ#TF*Hsz37L&+P?x#tdzas`4DZi8okEh#4kZ;v8x<}Wti5kZ}xn_2?{xvu+}p>?VG z^NZv|eT?*?bghDtAGH~Ivt}Z@*o>;1sA4cDmQIAb6%h$dqr!(msxd(--Y%zoWMZqc z;j(+mu)o(>{hu&wEWPG&oUmxMlPtR7S8Jn(?`n%Z=!A|B%Aihck~p%XRe=4usw|@~ z$Tq6Z%j7xxvPvUmT&(mFIkjFOk6g4L_XRAE?a8@s6X}7$h18^Qr+N-~8ZV|7>TW62 z-2(Ot=T7f=)a|96#1V;#;h`6`e0`p3VTpVRL=a{scAErx=`GA%mpe<2rO6 zh+ZLr&T=MnkS@Ri=H3|JU-}mB<7u+x=G5YYsqPHfQ0T>_qn7&*jF>!^DT>&gFK{w- zhWrGy*FcHM*eu$V{lp!Gv<4sR!j4L0<2kZ+(+J7@)pjys+6e7#s57uLn=Dh4(r;cv zsllMiI}eNU5y!-6Km1Ho$V8Nnz)Us^+oHpwo5Z{zb%%?V>Y9m;AhBt;E)}KGSJ@@7 zhQ3ak16v5X33?q41>rotJxg_{myypfN0@LEm7m7XSOr|!9dRD2#{BOe@ zn|(>0T_m0#K1x$FL0l?IQ&)?VIiHmxWv5kRO%%;6eC^a1xMplF`CZOKVM<}8Ywq_k z@VmH}1E=x;n7k=#LS4uazMaNXym3z*GkNI}dH7r|ZlsR(Np-0K4g8kY;%M?$T zaY*03il7P-(yEhqZOY6q+8y54iQfs98_aZf8=09eWO)L|h+Olt^*i@-hov z6hSM0O@S!KA(e2CgpT!;8$>^64fwuCI{S%ok3r^%wv1x$ds^TB;6YX$nr zcCZZdX>7#xc&C-3Bd%xVzjTHb7z(D)eQ}l4q&nNEAw?Js`MY>DW_L~@FKIb9PHo&m zt%Gwt8`@vOYmN(U8GH%auSFFPkqkw#p`e`_3TCSjB$tkt4S!5|8_eD8Cb@NnKV}C@ zm|+durtlg5G$LG`m`@|#@UaE#6CK#Zc2rAVr!f)Nw^Cfh^#s>)VJg=Wus@rzKSv6g zGgOoXO$$>$$Nrp}u8={PN=IQT1qqrd-$|fKFqKAAxV}*XJs-$=!Bj3MkRnWFVuuz1 z!c+`YbuZP%;%L7*w}Fg)A&>1I8~wI0l42sR+wzw=_7@s5BQW)LOg*oVeTTjwFz|47 zX}-iyu2Qh#IyDjlGzPzlZn9|zkh^jK`o z@xiTv^zORcq=bwt=LH%vQUi~V0}toV(2*W$AgYUEOZNRk4K&}JRs%G_aV!}`&!Y%m`sG>&*)=e5bkPtk$=rs7P8+$`O=0oCtOX0z^O}xuIlW9x9e#% zycok{gh7>P$Ns&^+^cDGaje=vSDJkVrj3Gq(ehHOuqp1>nW!$4 zxXD+T=_ZjDmtz|>6hU-<>PJ=5Uccg1JiNga^qb4M{{Mri>i+>#yZ=rT{{vI|kLSaP z;O{A)Pf>DoT4%830;tl}xhC{Yl(g@R6kI|(McdI)bM1do>l8!Le^6^n4Q?)hW9Jot zS~bT8)G8X6eC?tF)d8639>sL%z44USA!88GY@Es9qB?d-`%ZPqryR$1%6ev7{x6c# zifAV~I}0?Y{)^^%{fp)d|Dw4H|1X+*05sPFXbwbz|H3(~u`!*8>5!rezkm^|9$ zzPzJtbln>-PLO^l$$ILc&T;)!+oRBJ_BZfTOADx5zWAj%4)^M^?J}=3s0-JJ3jEvh zt$+t+BUjWsW<-?AJL$eTv+hC~W`N^F%2c43s%>x^I(vzK!gdd z5d{=pK)%Sxvr6=nQfNPUb&mseXZ)JW-6V)_;hm)KGuCJ2l%vC?yzxk0tvoj9<%tbC zVJ_pa7QAY}87(%@pCW&K`3@hO=1+mq|hUP4*VEKg?h5^$u72D zV`5f8daxILW`C`vCWaO6qv>G< za5(#jK0kO92-wMewHyfh(MFXt`=3y_oTi88|K|7^&#t&bauf(`-wiop_!JlWCWtTL zU8HZ%t-qLIG^9iClHnftN<#OIv=C)9uJx9$SO*!Wrkmbfjn`2^2Ee7X2R1k4p_AW@ zLgTs60q9`W0v<){tC5~gnR4u{|2EQq3z?pYmw%EW)nMnOf_;!mSPe>x+zB`rnab5m zCv1DJp;VH8=3>7F@nqgr`tHJp^emW-CfAz?VH3V18UU?RM-jCQ>_T&7gBwM1$lBP8 zk5YZAS3KVAhaW}e1~46;(O!|f(MLBBjL&F_p=hMk$O|3+GkLV14{L6xKDdeA&n3g< zm-)8~0GP)BFe|zhJY)tB#3j=xbFzSbJ+{$g8fc_5JXzs7>8qQo@!HHo&5xxd9=3pw z<~}?ib5h+aPYx66;VSFt9ko}!J11PC;4R=~QjCpu*`KT5%VfBIufPSgJj6r=bVjk~ z9J#*5si&%ZK>@Rd@ktG(uTs~XyI|yzmRIoirpes9aT9%S6OU$HU>hMO4K*9a1-0oS zaFGv5ho~ln8bd^wS5=AaXE}0?~vb^U%pae=5< zJnPO-!b;l|Na|;#Q?ha)39hCZ{91uq7si)2kiNRK7CTTbNyDkUYD4a&H@r%KERp|1 z@b6A++pJUiXaRew?V~yZA>T{*x%2}CF)7|DEBcpX(J$>((GE;Fs{6G;ju+P+`rfWGYB#A8?|#VnrN z$)J8CLkU>FbO4&@W;DD?W#?p!>CTbW?+e-YKz-lY-Uz+dy1u;lhx{8TqIaLOn$(AQ z#Qroxv0piyx5XvYKQ*5vqMd}l^wrrl7cLrkZ_5iTy1`VgZ`??4c!XKQvE)2$#kD5{ z0O(=GwMf68YGGp9gC>_Q=`g8ZCf}X&ck=TODJc+l`tv$K=#Ggh!4PFh~*KZ6W%=(BhN7qfwJd(5Pis*Xq zTy$%Ix1?8gYHmNE`OD!26eOlKa8?2S^6kA-ueVYakPCQoLhai7E_d@F-jlbK*6v$% zV82mxyQ+sBX(YU6b;OqQJYJKiqwtzTTkt9YXK{(PCjCi|*W@!x=MFFh@lF46nhkI# zWd5M}O&XC8wjB_cL}f~M)ANEeH@3b)IWv4wXf%bk)V!y{n@OEbYj&*KzDuMyL@2Ke zL&ZsmxWOxwdrmpFPt$04Y>(%RI4R@NffU<;f84`hOeEfqyy*|+c}eQytyD=YQ{fS2 zir~>M#)Eh`SfjiJ*1CE>);h&P_2GRQ49C4xrL{l^?f>-_0bC!hd5br~TSOwBgtwTh z1kI8#qF+niS<9Upk=DsceOWKH2~~@vdUHhXJYWa+eM|=UjShCIW!qNnIjDC2pTckK zXO#)b(I*h`fhJ;SUW<1#Q#XGX`!wdo<*_4thRvi30Br z@6oy3dng|7(XR6#U&BGs2iBo^kMdR}zr+>qP0xV$h`BZWKV1T1({H2|r;DC@`m8Nl zBg8?Dy)+gMq!rXRhW;X#@~Y^}gKa{%Ag<>T7K*_0+{Zz@0dEf!H)idwRbXL*WX{LJ zhnJ3_+EN01coQx|$eGMnY#5aI&R`&g?ix~fah|FJDPZ^y(VXpuNW6Sh%o5Yp0#589 znEU(f)YX3ZAJ_3J|JHw9N2tejH2l|fOrk+X>Z(>&zB~KHnRRFMR2lA#KC0Y6T76>G zAHV+NNWvHJQRR;0_l$k^&AGzv(mie@NVt*nc6Jz5CE1Q+PU?Z0-g&fDIY_Z7^v-Q# z8b5ELdAfiUUSl%v?#nNKs$8PkDdd0IxCf=VG(wjWx{NDBcuzh3z&k4RYcT&+HK0)V zL(?N0UBkBLIF2|e(AC>v_{;qn-b=PqP3ztBsN^|ora7V{1!Z}9p0z|lUj^%vlg7P# zo0$gcl7}n+IzYw0?=~H2lX@I>qOt>giHpvcdPxji1BEQX+@jX>FvU;VsYLs|(O1Px zy&RP=%}`8(n&gYdU&^P6PYRjOD`TDnCohH~pqS4lolU%Z=Q|E#M;vB{ zfi{K7e7l7P>5@k+kDlI6KUwXj6~X^VQ`KitY-4BjCltX~&r(lFw2O^aL@{97;O!>f z7GpE<D{rLchn91MwGWh3}o6*TftFPE@w$ZJIA* zn;)Mjy(kY|9x=U%9<}nUiTbI#Hpq;ruY&n2cAs7a>v#awS425|7f(5T7xf*B`=m|h zLpLD&QWUQWJKaMh4PG8Ty`kRl zC(Y;Ml)y2m@1~W{cT)=m|9X68o}FysslT{HtRu9z zo1=jV6VAefHLQ2fX%h}g>NX#TLQ~(n)+Z;#p|H?EkNO(v15FgAE?SO5@=K@>xJZqVYYgVy)tWGC6i_@6dk4LiA5$#8 z2(rw9EI!tIXN`v;%iyGl`HjnEQ6S5|x@JrGdBvudTIf67>}K51lQ&+t2akfL%~Ufp z_34>rR1;hSt;s~=P26zh!{_=hX(8Cw*xzN?UMPg3ZB$dU%sQF~Ki}w5?Ae2Y1RSWP zI8ar@fjac>f$FueMfqic19htWK=qm0T+bHrJW*3zn83ff)3pN!C9biFzLFB!abqZN zzK9Q$(^7Ay22iy)s;gD^HvgH|D@eGn$6VhNP|P0*Fl`;a(u_M^2EU93X45#_VWabR z3MGgDVxkCf&MM8#zpU$#j3liFL~6d2F(2_j1# zk=*iq?hkSeEg)}@Houb++jd9^2c`5M+G~FlSoBB;T^YKv9!sWmcnswA1s}b(#z%hw z_v}L*ZAIDiPL9Sj8C5n}rf~-HVmsJyY!!+GPx(v6Z{OX zK^p?qGez{-S0<_<2nqKu6{TmDPL;XN^?v@A>n{taqWBGFd@Ra@W|y{+4XDgPv;DH! ze3V7P7gUp4n=G?C=vn*-1wRr2=3gSMTgBtP|7EXo``y5F^3d7w5wi8#>c9N_m znm#Ph$AIJr^dCW>GbI7~sAYY0+IRrcY5G_h@j+uvABKBg-Is){3=_1j2;PmoBU3-W z^UaiysZ#ebUAhkUH9Yd_a(rBIo^gNZR9!&dcD&*QIw7BRp8(n5aNoPPjhNiQB!!j) zs{4!RW1Zn{1l8zi>YYLH89Cy2b!Y*6kaM)Qb$pnsg9)2A7MoW|Y~G1-VX=AO*UDae z(r22q5C30jn?PEW{NAbA{qxWjp)2(i3TbtT?K)Yz!_pMUSd?Vu)6M7e#*Uj#h(8NJY6=Mn6eQUI;D`I^O3P)bZeRa8T935 z?5(28t>|rd>9u^;{*gKo&qKgP#r&LnCpS0$wkxav;RTz`CY835;llWkWu+@*5O5Jv zO86S7^yJ|ydd_aCXEnnWggx=gqe>ggypY4uZ0AcP{Apkbl_a*C-BEZ-Tfr>dkx!rB z=gSM&Nu3XBxkqGVWaF?20=bpFU}RS-!BM5wa|0-yKKF3pRX!l7sI%$P$Z#jt5z|D{nYqhNOt zy?HMk)KX3-e1`^u)!4>w5$B5GOikXf>!I|_;)5D>c5<{I{$Om^NrE~H*!R75p!Z{$lKQ&rquKS_x#+gXF_f2EOUXRX;sBm7pT zg(Y-Z5xBA*opbBU0t6!4noSN^%m`Qi(gNA=s4PM*ZR3*o2ecojv;4NQ0_=<1YF-mx zo{*p%hP6L9gS%>+xHEBAMa;lm^*&yQC~QgK@*q$fyLST}KdE)QUrL{h{mnhC<| zu6k-^L3bSx#J^^xqImfhE-AZ>L`2lzIs7^MhyeyJ2XLUDz|Er z5?sz9ow;rgmZH{B8z{Hf54ek-#j>9Q!8*V*TSpHEw$M&#HY~~+k3|XcYy!(>6M1bc zFd}S8*X4mpmt<8EHU|2o8liQ~O-o=m>5O_)6uCP1Rsm)zW}uTeoxw;$T!S!@XPoK0 zsys+R?n4_1_7K>Ohv*Vpw}pfow8eh7o(Au(cb@;Ps6D76IIbDsxIPQw_t;&!7bLM? zE2{+pV2sSTluhXvexPe8h7WUL0{3q9rOap25ZpH?{secKTP;xk;G{nDS{BJIpy<8| zmJyl|s7)T)jd%OsKy-dtNSkr1#aZc{I|wX_&9p`fET-@tzQ|ju%M=?;uu`oe z+#BDT$*fBWS;4FI=Xk;Q=iv(N4&}Q=BN%Vm9m03>-y+?oa6w(Q(SU!#nZ~31l$k!zrI-_&%;dg$14GlKqZDSPs^^Tm`LAXaDy3MKH=cyg z_{T^I=CcZ_uZ#IIFL>Qh8wJ?u3uyD6BiTifE+CVaZbEQp=ZbC*8Lf}cmadlL69Z9X zspmV9HEU>ndD6I@AGLrqlN`Ui>r5```6>+jn0fI4z&N&>FL%*J{@wc~jml^z(HXC^ z>yhINr{FKWr9?3G@CwYhUEM9QrASQeMRDef3pgDI&Gf!5rSHlPXd|fy+Snl-rq))f zaN4+oA43tgF1g?G_A~Gq&KIJ5hW?XI`hfnLWr{|RwZ~b=m3hjhU9ZK0qMSV(hO!8( z$buEs((NSKdh56mT_r7Io?$Dy&uyvaTcte$ZT(@~Q@*UBD|_H}zsi`m6Hk!wOn2p}==SOASzc>=1)8e$XG~8m-D(v4Ypm!YM1|2u{s0r_WQ?k1Wb+OkhSDUlI%i>|T`a*zJW+#4Lf z^i3@EBhe}9@Zr5%!10?mapLrO;P^#W4u~Gzqi5!*n>RE6xNNA*Rdv|UU*QI|Y$MaWDfM)_Kcgh!1E$cg;Gvk@p|^B*Rg z#A}6&*NRBd1LCeZfP5G4zH0i3`{q3t{KD6zn!XE zZ)Y0M@|k98pfengO71d?%f7LRvB`1C`rTq%Gk{3uo2eNp!=jTqP6ururGNjF!QyxP z8}jmRtX^~5PnBJ0`@^d1Zm++);l?-MFO5=E8y^=1!1_HHiP7n|E;>Qs+h^;aLp`8^ zey&-CD0i-1K=m{p-)#0J@}&J}&=40xlbiZFHHcRPSLN+&Y6Y6(y$!d%S#hE6hsm>( zXMYvm+&}2rvwnBfu!(Vu` zJ91_8`~bb-$(a6$@k#xY^*ezAO8!u703TzpyvRB2^eOTGEbn!W9h!Ce(O8XMn8QuM z2huJ%50Z)eoRj;CI*K?%6MnwPPY9E$D^b=XktmGoN+c9{;yj zgjf?x@Df#&S3fFnUcH}xrx3hlwiz|WbCW*AUwVzPa2~KQ%1jmL9aF!g@DF(f-;qhf zlSjgW5oz2%Z~TqNnyIpAbC%LCDd+<@)|9d1t&>H|Aq;muXVuy(e*8&+=&?yJbywD3 z+hF@fe}Gq1D8j_&=DV|z@eJ8imL`j9y5glHwtm?ZZ&SaN9l5viog%Dwki*&mKJ=vy zee&5K;cB3c=kQvBgjkS65#TrGY{>j}#re7mljkSRPuBlbY|T0;gtkDe;mQ3L1^F5Z zbA}}jO&*@2-}=Jp{M~o}4Rv$41y|U^90Vqy!9~sQtWOy|&N`|7m(ccul5@G%wb%T* z@x2QBlh2hPgNuGCttPQk?1iFc6tE19{1>MW=GLicr3+6i|Cep1VHdn-%BkE=-!A0?B{Mv!?xO`~wA+3X~6^ zvzjVPW0Qs~?&&)m;zRpe?pv?n0?`?$x+eW!tA+GqSH>^w2JMe6*ZyB^&gHIx_6=`i zx2RK*lHW}uR8_RViDUc1)IEHHyH2`R8qhWC34JSfcZTOC6gV#5^oaf@0OnF(sC!U8 z+ZnC~Kw0x3baezq>Y0W%oJcaWITNsht ze_;qP`S-&Uhb0STKDRo46Q=ys$Sr29c}T- zqzF?+-VWwDl8~v4#DCul7GJDkS!L-m6+x}Nq0~`-j4J#S;!oc@-FdLUaCw6JM0;4p zY0WBXh?NY?XS;-spa2=FQ9Q8J6;!xcl$)!+}M z9%DsfClFbk>qhjB%Z&;BQ0f@jflHHpkHp^Eou0PmO1&LD&P0_=FW!3=*Y@u2>3#2f za75G}?6=&x3zDQGr>~vRw4K%!evIBS4yxiZ9B?;a!OE&?&BNham#zjWPO?ix4h6y&5)QJ%9d(M=X?0cG~`oqLZsJgCX-K`Bp->f`e_roN(vt<3| zC)T__AqT3N-qWRwNQ}lED%@ET{=!v-jLV7 z9Ga`#SbzJA;_p{pgqPJec*_fG;VI*<9_6JBMKs+?5AF3^*-vP12Xfc9P9k?bt6Y17 z6T5%dR1*uzixkScR8CJd`qIWzRV+v9X%UAe&=K{*6^@?)tI!)V7Km|Axg28dkhy*gN}8 zFn@?R6cS^7XIkcu)t6gk00P^*0IuBXDb$#lfprQj#;Nw@!=n2R>B2X0p`DruF zM9`hsbS5|H4Nff}7d>3h{~M4;iGch)1muy3n`wgDz{MKS$7+Kj{Aax6b19o`LsF~A zN&E2H7wK-Sw6t>LI36#$P#vRDDOC5dF`J(-(+nMdp!QPIXqlCo=fg&hn`xRZr7H?g z2Ju09K7&^f+}#1FW3kguTAWWmxpx=Ou852Ab2PuWAh)~6y6KVqSA z2*eWu0JKGfd%BN~`4GG{p3Y$gyfseQcI4=Rt*1^Om^*&LlsQBED6VpQ%gBfb+sM23vi`h&J?hVP z2%-Ckx5mIY)*OvQB@BIo1}Y+&dT;@ju_!cdge1;&?qmY#N6+v1iWR2N< z#;&!$@k)Dy=Bl*FF0v6Xp>}7O1C$2(j4CTgAk0x2k_xSmRQOCwDhQ@R3i}Mvx{vkF zNsN2cj0s`45pz)1xJlZJ@83U;kl{D8(9)0<5wr3A)zE)z`pb(Y;@3uqVq5<_s_y8M ze<2qHqnOK4Ci>u|LKA5mKNd@qyYLBoUg<8`;kP`^`?KEh$&KpM9kQZA#OiJ)hnZ+C zbyP$+_2>*D7vx(eBFtMEG|RK%gJQ*}AeoQ=A1nt%#Rpc9p?h2ynfdbKs0)YEK1#m> zLbR3y0kjV*wB;Uid{sCy*D(DmO?$0nKPKb<_>owe(3X$m3r^~oUN-ztsHHllZ9jHw z-?rl?_s$tNZu*DA{Ad7D9V5DhXO6geEAx1MUi5L%A3H_~>CBtOv1(eD1Hb$hkkAwL zLO9PpAvm3l;FNEc_Tz!^sd#n&-9l6G!3vb9;e&Nh9InUsEHZ#ouJt;4-c|Z*4I=fx*IuYFx2y&^|5wB%;JRfOYAb6>)mtY@_p&QqVo){M@9_RJ48+nxu`{a^cRjlb;^ zL%#F&Ts7eh_b%RW>2n%`Jg*kTEAom|%|h`sfT|%>p^Cg(7W!)&N@))TD|@iw=h~SwdoH0)vv@UeRUFo` z`lp}^?HWZcu;UEzNs8Hh)(#k(@g(g*`a>Hf<1T6|&fG>vB}#azu=Q!``Uh-hy6RSa z++G>#0f{BC+1Sfk+ADDRZKoMc1!3w3a1B03rl|Z%8nhfbuOLp_NZH*KMc!)*DI%W? zMU_fKk+&%GGRJFWUhid%(8|0{(`1@v+=asVMmnvIYZ$N3J7uHztuqbYPyZid{{bIW z6}%0=q3wpHh^&_um!9l8`KoVKXKNE|idsDbkS(C^D1m4JkZlq^9r`(~iZDLU zIY1z9B9FT2uq=v^+Y~sdt$`H9m0uOnNZlI>HKQu~p$WK^V`E|+27I~{m&JZELujzL zgr-&oe7YXnS{?28A`tA(JNcuriiKRM35n-H@(s6UhqQNc=>2T63zoP5l-d}B9IiK* z`GEr?CiE@oN}>Z8XJEc8;Sgn#DN84Gt`&FWb#NJP{Ph$xi1+eWqORjy8mar@tXOmN zo9J_a*~)i0KvvXZ4E!{3Rxz1WUZRAjnnIoq4l4Vbm`nQ8QxLD9um(2~8TCvwxCyQX zqRNDOJw8U|1@86a9U(48fVdbTD;=$=bio8ypDdVQ124yd<=a_nPYC+;?K}`RnWzj#9 z%UMDTsRo#z1CBS^p9jEu-rKl3Ms5w0>HQc6tnI_;7F~P!S86Ez8y%Y{Nd7k^M^R(x zU}Gh=5ZQ~~MI>Rc8az2}LZ5HYSbd@-Mgv2m;$5Iw^~~Wl?~oZo=68t8+;hd%9`t zyDxAP|1^w!+%Pt|^1sHRkDaaecs&>Q3T@@$&{*U%ib3KB2Y{6HgF#wJs8)?^2_|VJ z_32YCnQD+$8fQ?)^zv7Hnp968Z+}2hfpJQ>o^!?`6|+`=I_I30UgBe}&6R=34}lE_ z6KInUxEB3maH&V2qHd_8ti(drjO*#;@A$MSCP7;}tBqB-=19GVZ5uUo>aBRRqRo`z zRC)RZL`H$P=#Ih4rZGkl@=w6ZmU`VKGV-JuiUg6-sH?A?2Bd>)e8dX)MDv2_Ot@b0 zw3Ps6T(ONBIrT0)QlU3^r%LyDhlS2##s#RK(4=)Aeza|@Lu*2p&5HXUy7YM}eVl(p zjzSkQ)C@@aM%6-=IuNRz(|SPRk426havq24F32hBfS3kOd_9$&h`)Z(a=qX@Y9Aqf zrS-1-S5@)|YrRqi0uZTkRB{iwc4sH53tHJ+85}+NPYzrLo|FoTn|CRRnUR0 zunb1;FCL|6lfAl|bF~W|eI`_%pglo|;nHzEKURvQd;U(n?zxzLNm^dy(xC1S( zN6R1cE7OdYkA~|Ov*qPtb5MlO^F6c-{G~S*Bw=kzQ++bXzIQzOHx_(-a-fVti7vgL zO8rGh+O1Q5cej)W89ov7LALOzKZ7JA@4U7`FKMIXaJ>vfRHiB`Ln}UMOeyhcMC=?c7lQ2cv_O)y^yO3wn)GR!5 z(J7aX8dd`)OX<_JdnYe}(|zZ(&kHr)#?cR)Zn7Jc?om)=l_+vDTrX|*)l_8s1HB|V zOK;OK-jzUuTJhUFM)FpqEcn|00%3dCaPrYSg&aJe9hOer6toHAb}%N4)|}Fz${U6% z11HPtOh52DGHx5gnWNP;82;}AlNdA+?8K?sEL_tBX({B>Q!MsCP#}^1R`5%%EL7M< zDov4}qDv?Ra^7(@!x+59KCQ0bg@a-cR>*>U^u!yk+fQ4+aTxu;{-)|(6ulmm(&||} z#r1j?Y->~sBdeuqmT)VLAg_XN3nwg0f7eg_Cp$%WaFI=x}HjH)B zm5VFkLk+?P(pQYEx-+2=f@_v&76`7O!drs6amQp?s|w9^>6cX6##?M!*^FDVTCV4h zv0-`t4H=VUdDD0s8n-{b&Q-9Q+s0cu^FS$anidgnP%(<5?q6bIiPJ48ajIEhIY}3O z6Flj^PirBVIxZb=F{7>ahhRy!_s}T!b#nzx^=YAo$p@>jDkP4U^{KD7ks7YoFnYEf zCc{V|lSCVZD~29G&Wr<85k+zbckLQBSgM-tDb8KFWQd@y}ErS-m#O$w#>WyM?8Gjj~ z7UYJh)Z8ET!2WasZrLfGS14{?dEZr+SH@W(ZiVH`M*IrOo{itu4dui(kX3(Vqe|nq z;ex5b23GuE-U_DaS`=c5Fny|@K9(d2i7D5UFDKtVoomcuzgA0iU9{&1VI3_t_YQMc z!on{5!mb3a%Nf3_Xd{#Lk(UK@?9qd?iz)g-**C@qf`sj*k5*|2_Kgn7R6BWJD#~}C z6B!42nXMPbt(5)W=<&Ap4lbsTQ)(&1}Zn^XKVkA~_PCrv^e50AI=T+8{fY#BAu$}Hk<^PqbwIRFyPWC_Y zEZ5ybFQ?~v%S$U+R7w?swDz9%u~KV%vzd)y5+q%;AGbcei}C@%PW~2~G`!JTUNhFA zQjUJlqJ1k|@bO%hhDphLnm}cFO18F9ST6Ke`b94k{6(elSyVQ=nDzv23?I0b9cU84 zYw)GHCJnp>EmUeuXg;$EBwlmr4USu%+(jQsIys8(D@gCbzi9zUKXf1bfNSa5p7M8n z09{Ycq|#6sxyT-C#}s;r-^kVmMIa=8iDIMlgiL9;no@m2i&;(4@Gs%a$E=U6*b1uEoaqHu| zi@uY_I`LZt9c@|%epBy|KhmaMrd<891@BIW!ODgyIF3K$Jc-llno?c7&26(^gMq#l1MSMzawB*eJ~}!|pAG}nMqx^u{Z=*? z2ldxwFlOr1HyAU>I)O^5n`~OKjN76l70ag9nX7!;Wr{pPo**hG^%qt}@K`QKL!$K0 z&|Gz@Bleytx@Uyz%5m!>b0Bf}9nZl^cn|H7?PNp`?28R#U)(1o17lx|J`#8FegCc_ z8Ad(SZYZgc4AS$S7=y9qreSHfGHz%dTbKi~*Ng1g+1kDco&wn)nO$*;?C~;*%=iL! zlWAMZSi;}69AnoCLqlI-Xt+&6!!sp5dL9}+MunzRMoIr_n6m{HRJw{NkE*3xj34#4 z6b6a20grngC%$j@{XgQw-va$L3z|K|73mctP*m_ksl_ip5`?J{$&E;-#@@nU&LBl+ z|3AXHKRA`EBAh#@`Mvsl3oZz<6tAQ{uRyJhpzckJ{a300?d3;}EoGlYVDmf=JcTh> z{uW#3|5psw+pjIma@-6kg4fZ%KKjw z@;<+pW4|j=NOrVDAvuLn2-TA0Fa^>RH3;S@@6s2lR9?Gf8|o-q=vu!-fty0_8fG*# z2uIoIXWkXVupJJa%fX?d@&Dyho%p2TSF7T8{}0#dn~Kf$Hipj7Bt)3z@3?tRh@bj9wG&IQQ7^1S#bA^ z!W|h1wWa*C|C|G^{_bgN;Vu7I#a%gd@y+vta`Fb9Rs7mlVcZIMC0cCZs$BMM2jE)B z90D0vuuVfoJ$eb+I-GhmzopPeywyjy_^_l7Jo2>?-o?_SPowIC!9>m4o^-cOFE2s01Cbl@pIi+j`K~YY z&93tOL}EX=nATzP$wGB%r( z>?8T>Y!aELYoDQEg>7F-!&xrfQP}YJXcz%H-{efiNG$hr0=*Z;Lye3|rQGw40KLQK zJ?A!@S6Kq|OEeRuwdQe6OUFbbKHsO6D5!1I)_>^$rizyEDo~uQWhLF+?Neh?e@(fZ zLG}Jq=R8&LN1wNk91e}9DPx{%^cVcr3thGUbORcxqR|lk88^A1|6ep3I9x*>SzEMT zn)Yj@qb>H4qo!-i6mDQDv)T$#sPAq(`M&0UaGIK=LzgW%T1$Uh92PJ^-_N(%%vocO z-VZW*`MjUsR#oD<>V{SDX za;lt)=nn2)eS^E#UATKY&KkKyP-fh8 ztI?@KQLW_iE$0(5GQRHz`Qkqi*OKG6G;BErcw|UVQZ>**AAzs_NhH- zD61+7gC6-$`sfv4c6{&p!~RCh3^ndRjj>@6zdV+fLyZPlR~0!JYJ|`)VXVt6Hnea$ z+dEq8!rcD+uVGUnjyUYJulY`uOBK`TrGHO zyj8;MGQ%Cz_zX=>4}53~jDUMTbKF8f_m_a@>YSQU69EP0zgC%$8pt zLG#K@knnFL_sUPSg>seWF=HTHkC5gOGnRI8TfVH&C*tIv$^-Mmm5hJKHD z)7tV`u${NVyo8YYWgq1JMEz_xQTJQOby?}yRU!W;m6oHYk*E!id8Qwbo^Cg1au;*l zLNSx8;YcMK+zQv5NM{$zxb4wPn?ZJ3?p}%g@`lDsm|Yq1H*JzYyJWW-)g^moJpL=0 z@&r_i6iNF)mEo?vAk&HYD~q^?khlU zayLnqi#IN}eis*VNSEu!Z9TTF#qqSbE-y}?#r%%nir?%r7UT8|D&l_Pc^t~ zN~16iHe6wKUJ@r!OT8!4cw=t%Y|(j$gPFb5O0$5es7~PlM%MKZzlWQ z?sPTvVyY3hP^-s;D>5}wLYD{F2}g!CHbsqN^WUI% z1wGSdYLK|sJ5yo9-xU=H18uVuD6VaMv$^r7m78={#&KEceu!2)T<>c1z8KW0h=U7N zXe3#?IvZ{_?9h;l&r){Pe@2l{PTL7L+YW9P3rbRU!Og}OGUjo^Cj|lJ^m;n|hGF|C z*aC!$E@YvqhQk$Cw^{L9kj_y1J-VhMH;BFJ8seLnHh#k|sXM6t8G6+VxP&;$ci|{cAGbWY zw^;n-w2Yb)#J9mu0var6({B8-@t3X?y36khD$0YyPA|XP~1gt1f1yJzRhNxRrvh!ATUCk`E^pddJ0E#IGIj(hN^wS*l{% z94eyF4B8?!r*aV!(t4hu7cHn^Lu7Z&gIB5|)JCNaU~yoxsYfj&QOjpYm8k0$dQ8m~ zDhp;y-CQmo4y%=3Bg^7<_?fA9X~PcKVV&P>{GHP|U0EvC!893Wh?PJpc^q zn`uTkpTu`@?S?Y%c&|rJYJb{!$faQQBJY3G1zu@Y!w~!xNa#}0NqDQi$Bo)Qu(*UZaqC$JY?|{f%-rBj;qIg#V8;5 zxYUn(az6`gqn`R*8~%TvjjL)+hB)YZ4@P#Fi+?~H78sx$&@NQ|AC7g`CYYF z9@SD|$r^cfJxP1}GX=W?E*mx+IN(Kn85G$bKiG-i4DLFfOIAgNF8OtIgFz9IcLq^3 zwZHRomi#)q!OzG*QQvWZx+^YM{#+Y=HlN~^tF+mTUcBMruW4Cx%&pE~ZhOJp?&U52 zRDG(_Zq-GjQ5v)?O7I}a)orxH#rLQuziFA%yyd(o02!&xJbDMz*=?0)o$UB!*AAoU~PZk3LT7+6R92h?G(E@y$P_mC1i{FFMocs51Vu+9y2ebve2R@1u+wu`(c zNxFqorS$d?JvTvH5T?)Lk2F0^-y!e#P;>! z4gJA)4W=No{r>1V+Al6Wm>X%7fR3OKmuy21()HqU`KX6K)xrfq8ZK|355oDH=A&!4 zq(!o6v^!V(8D&}hMp@P*Io1`SO8#5waqUYRH=zN>V7M?CLwz|6ty~UsA->}iAxSH1YlIqf{kz^7apZ|}IntQKE?0_OI>W}i31BUNyF1}Y1 z)QInWmwuEsUY0gqmNveZE%q=4BPJMI5N4GB^-|?RCyZA51405f{Go!Ri-DqE6l$Te zsGv^$xia^+(9Q}}nJP(HMQpTRhVyZ<;uqr#ha7Jdi8$-M?=>AVT6tfrZA1mC4VpdeHHofwCLXm)RW>pn<*PvZcnai6xQ+crd^lxb*-qFZ{pN>U2*^X)8 z8F_)DAX3H)>nd>e99QV52>IidnooLGYw1AQAU z3*+;eZn?=JO8zkv&*U7HaZ8aSRK> zF|1u5dNbB@{dr)fQfD7Z=0Yu1L80ivFbp#$ns20o?M0TWOSFQLcRWA6|Mk}d(jQ5I1Vit--^-TLX43=NP9QfG9yU}I)ME;)t zP};m_sms;dahr)!TF!~_I&tJ;U(? zzb8^MQ=+)kyPm5?5C`K*5I5e|TyL$I!5gAE#A;?hNAa{q#w(~k)+V|44CtZ3EE7zv^3SXz_FrJ2Op0_a0sqZ>2ExxuqZ_SL8mAKa^9*5+cQoArC zOKKO|S*y>$DNg_oCk#9sWLNQ@tMYBc1Z&Hf7F^=ps(ZR$*_IqQU^|+&<*)4>QhQ$h zXs^_!-xYKDDz2WprzNL9@!)#SdMA!FXP6r^1iT zXZtRe^K}${V;ql}%bn+~=voPkl7%QLm!*SFGdttg)G+GMHiRmtN@pVdr#z#=W++B$#*Vy!NQA9EWc8SHNpWU z_%KkUg(FeuZ&U^=SVWD^!R1Ad*rD&J(Ke7qE?fho4c&-|ss@RNtt1n6+A%#hBY;=Ww`$P!|mDlvYkh0Z>Nuy}Md_ zp`x|FAI>=zw04s{>gwZtumfkNdxFdWgkvG1P7<{=a4S8N{q4j-C>L_`!q z!!49l!J7{v%tsu;m1DF6JYJ<=xfF$13%B2U-m~WRt8Ot0+(`lxa|7OF&T=$3n5QF` z3BP}j-ZvXWuDg-IBp14Ta}T!Ov&tSE=|QY0=k_K!outY4)IE~J1Ug=nCf|4Q4pYZn z;yK@=()6B%N;64O<47rL97BnUCqF5c05)eEAJH^A0)_XaN-5MrmG0YhfbeAh`q zG~bFuz+8^=$2-E1J_i-=t5Y?k&ymzQ)tp*G$}gy7!xs=?RIuQqaU-oP&!SK>UxF`Z>{LNeNV7?R!>W9937>(ic*-@2F4>wGt@Xr+1>d1r5Q!xqUJ>SxvtP8MQNesK`5X z(zxbfk#b)m6T!9`HT@~Yg);48TLsY&gjks0N7^4#{C zp@fDDo`1|R;;9)$95AAYl?uMtnTl(jWwLh0-ccC+B7mq-(9TAeJx`4ImfGhQ!+wFm z{??q64=uc&=PIEe7sk3_&#rvTShqf|d|oINDCq+AJ`{l_J7KzGTpwY&Yq2<#A}nC9 zp$J!(NsMS#YQ`8-SfW|{y!W#^9_o$%5E0<_#x+mxs(L+)fYpXVzc;{m5|hCnSOx|;!idqEqg=p|^Ki}SGI=*#&Bh1$^wWXS7}EK}TPtT^9J^C}0b zYPy+dYIi!^61Y_AG*xSj7ih^eRTsW*gisDO8i~`07AIj3CywKhbMWPrT`N)4vxEB` z{u|ww5H-Uf<_{Z{pli91X&O$Y* z`idRY%=zVMz_9AG^9v3M(N<~K(Mu^kU<0KlNY&P;0zI6le9ZOO0s2V@`EWKpYbC$~ zS8k&gPQ4S4mv^9VRk~yrO-xqwuT{DAhOq#VryxJ@7U9@t#8OUlsVnVJMlwn?AnRcW z-3`-QpuJG4uo6W#oOX?`=p_^y>*Ajc;G+9+@~yNhUbLfrt7yvuW<++3)3y8dT6$e)BZ`G9?bXOwAp{kAQjk4!kdFs zFiceNUD~DDq=Ml9ZH0oG#oBOjgHmOnnAkyGha!eT#(4~rPK8OUbH%A#*F=^;MpFub zN$Ud{%z6BgqJ{C>dYHk1(X~vvXx1`3r0AdqEHNH(OQivLchPA2J0FTl%6$poieDK` zSCFO!g!&4s0&>wx1GuJM);lPAODd(cl>Mcp)Hp0H=v0>v#N)`Zh02^c zVpKUS(}^6TcDk_v{lHG#1{hTiM|*OO9?Vs>u4*I}RQ|s|#JUU<57T@s3ve#8c`Ee!irn#%P|eA79x->WOPV`z9RzpGF$9#L@B zCWWZ;sjOSS6-VWGgp?c12LX@jou+tHb4f3MP1QbAT{PLQQTsr1g)XP-t@Vp%5c!jB z$@k=tx7l%AfljV%Cp`p=~PyPU_+=XiW_jI4x;!DQ}Jeyfu)+vFAF)j zpq~vn7WW&>7>7#f2&SYInTOu+{GI+J{gO1b8oX@Pb+tK-fZz;mxG22FRM?5ePz5BF z-vVONqq|wvd>(zCXgEd#(RH|iXB^K*(By-Zo9=9Q<1?P}H+;)-wE9>*)uh3Bc=sz^ za|U+^q0dFfYI@NOD`rp;3|V>LW%w-TDcYw3$TVs>PiYK1<|M&muC<_nPXjiEdb;$! zD)ptxf*ZMc%I8T)&Gp{!UKUv&=TOB$Ud;VLkT+4};f=k0V5W@{sHh;(941G}C@7w(YY&6hf-*wQXkG0^-Dh-{C%IdZ& z-iPVuq;c@|%4MB8{Y%awbs#v-*=YT9>11`I^*LtiWnOH3XfwSOXXiJu*;kj*TIyg= z6e)U<^5x{K_fjbVlz~LdLHFJCzteBX99)s3)s`ibFH7bfna*p?8Cc`Lb%-2yoX&lv z2ICt>4MqXxoFbooYOSDbuPWiV2ztimuwYSP#CqT%P{@s0=?~NMM9?yyRtGa>m`u!% zWTr1O})tbp& zLTI%)Fb?#r=hG!(LA>y@O|RL{;o9f%sQctbT74%r*7XioGEj1HY>DR}4kAlD;l-OQ zD1JcDCXHjA;SSnMeEIpKLx5xd2eRAPb*@x|GQxj{z&2=eTY&! zVe`RXQ#U_+m@;O-+ug>1BQpRTnMQAghTVD#u|<B7u-je3mg3SsQnBk)?&YAm=@jdw1aFZ%pH|c)%7h0(6kJF1B|Yt=g{oXzwDGBP zMtc46ZDw(4Kp4E(Wm#uC-H6IRo2f;TUH<@?bm76C;=h~5bmJ^4DP);^?DV~rdgEKq z;*!8aZJ<>izMWUYl ze$Jt(5Cz{dS{uNJ#UHQs@=f?-zm0qFYpCX-b>i3cPL{TD3O;p}F6dV++Dh%X!lR(i zph$r5Xbf!gX|}+B6HWMUy9+RpM->UbsVK@uHiI>@0aB2A7MD?`ln_X<=O)n{y^`={ zEct)i03_P*RR7)vm|s%31z%a9{h&zYb$UaPkMuS~y_cc?KW(uZr#%rLFoagB@Xe($f69rQWvx-T3&hVUntLgM^`$L?HJpiPTL} z)g}YEXGxY+wNyXj_jGzABjb6PIL5BO5GLjohKZa1cbNE3pg(!cLVwk0tOSa5YplZ{ z%E(XNzz$R=gFtABPA_s-)wbZw7ZYfqPd(Y&Cmp67FBzFVMO)4D{gkfXwrH!h9ECsQMKQF9zw~QAN+wHh4nPcE9J|o!YwB0W>2=lRAAr)t zS}ZVmr2uSe9zy$ZdZj$C-dqn)w@_QCyOHcpM2ejx^!$*&Q|SsHHtO5ad;A@uJNdz{ z7JTbH?Iaj=rp!+a1YU!yl*-#`CRQi@TtA zrD_=}q?78^o9eHjcM(q@{uL+xz~_Zg&09^b1lUNhP#LLF_eh0C5l5+?KP=ClKUI5M zdw`}F@npZYDvU>3xdFFC)0PIaxJ?MWQjSM&tcRlM4iA9;3WLug;t$=~Y@1=Tn+OrH)^<5L$7!9CJ$os`(n>!uQ^H{9j__Ky?#!;<4) z8hnhMTCz4+)UH2E#``;DI9x96HqmQh5_J-uBs}zl4>?b82t#R*!OC#)P$Nz(g*w-{ z25q_nNDznt>23E$bXRM5!U}Y3BSQ!d`AdT~q1X{vFRBZwx*EExwaWEy-O%`Ye zBag{}c1w>>J5LqW=yUBs(AcJ>Xamu0YrR?0?TsK(EP;x!ZY@ll&QK9ux9@tNFY+N# zaj-$t2;*Tq`gcRcZ*rZy$7Ub6O$Zt#qxDkYW^9LE^7pp(_+$ADZ3)yfRqK!Tfm|JF zJTLZeUzJ4dw`3}RpF@$dMB3)mbYPYAFsx>b#BOtywBbyfj4~%ET3ha+w?#B4n|KcW zrRPZ6lT_Kb7s;gg!mq8fmMuuMQAdxLtln!P0H9Wv2*BX`Q5H-aP$(fRguXW=G{ki3 z_`n!zY|j9KDnj0{8sv>6DkgPhGbw<8a6`BSZOj$c9R{!k)e^9nZZ>V=Lb^z=srJZA2DxvRNxGdMG$1Tk&O;p-; zo1z@;)9Br_zwk1TTT=7~0aI7$PlRf&mm7*Gvee*COb{_)7*$)X8Qctf1*{izFal!2 zpF&J|td|aYX(3J^DBKI;#88BU261A`EF0l2(09thnA>G1a`V;=?81!HP74KULDKcE)>hSY!Ssp1!fnYQxoC+-UL^ zgodxKqnDDC{70yd98U*%vSl{h@M4~l!*}HPIp1D?*cB{Q^zMnV8;ta8v%@gcxh}W* zZ}@&PH=0(MAl#NaY_V}jY@n#zBGgEyf$0?PDRR-LRnGi7s~EMF*lW25ekc6|uJ0}_ z`tG4~y0`I!wzJue*sC&a`pD6hUegmZ181Tv6eF-vibVBdDlKNe?W2K6v66XRH5j?& zw2QEM98b;E)p4`&Mqd9|A_oXDE`)2YXK|7aAsDZNF;x14dW=K zmV|!A5Gx%q#dU(Xmv0~hvq%VbL747%S=Z8KGrW=FcjtN@rTNeg^?)zuD3#B;F5%0+ z8G$1xFgFS^I?;9|o?>}OmiBri$5=yw6_{AxHJeL^&;nX1B3_1wS1&F6mV%s|fcw%L z+H!hVzaB>@474&#Uyl1yi;>jk8qkj3YhtuRIhjeY+6_b42F;Gm9b82opQ%j+%K}0| zm5B`_W^?%v+Gh5nv6wA);kPhbSMI9FB#7cZdXy}BX(AWlTCQ+1P6P(o63hyq?aq71 z;=O1H^qoESOki#X#wlQo)9_5~{V47Qfh{1=9H(zhfi)qpdfp-kwCCp0S9(Q7kED`X zq+IYtB6iC_UFoL~`xNn8p2Tk%3&26vr)O)^r5ce3%kq}kmEJzO$G;@=R<@lBw%PQ1 z#<&F=(kEnU3!`{Aq(>=}VKQvjVN(kzO=p@Z62%2`9fPy6-N4$E z6VApFgR@bkkh5{a1Bl9XV^WsLULyvc@a+WOkJ$q1K2osIhQqVofsPoa9%IxBd|J(QJ<|?*zRBb402bL$SzyW0rX_lVf>=F#+C#RxYLC zgz(u$a+zK9wTEx(EumI5tj{M-jQ3XEGT6~(cN)q|fCqKpuO0wKfA{7EiyC~j#1>_}_w*5){5yr&_!W2?H*e;%CNN`vL+x`Cx<2E5I z;Ay

k~yys!&6JFg;|dris-oOJ`wvd0TIza0?jZzud46eB?YjZ=gCI6{0JsI0`% z7aU}bbnqAWKZJ3ChGE>p=!rn z9BScco(HvxH8MCKDb^U+U$jbehoM17sA8d$aVn^hj&*$jPNw>$#Ty>r{LyrRY&eFK z$p=RPSL$5W{Ok4$&IVrKTTiO{w)+5<58S}T^%K1@G&>Tm!2WMDETH_x*|;|Dp|=5N zUyi`d$kkAOz^*v_wVPZ#DJxJ6Y%NP|Jg(QD7(S~u7FDkC$!Q)wqrY?1_*}`$i#Fg8 z$IbbmLj42+tMzj1O{d8olrtE+ z58-VgO~91XX^E86HqV*^Q1j`%_@ME6tY zJeS=R;ub1e8G;6y5UN*{C(nwh69eRuR zCDO3)+cq#hBf46e^sQahOEQ+2Ow)uT=B*{(mFgPyQh8f}5)= z=o6&9szK;O{+8CXfGx^N6c+Br9k7Sm7?~qs(-@VyBP6FO6s2fyaJc@4kvcL!f9L@V z-NRr%r0)%y$PQ|wZSrD(ey6W%>we?0-c3zCe|xC0fpU!iw_h3rAhE4c=Aw9Ej>x;= zd{etmH(l}^`4Ywo4c3$f8=DR8rLSw{|Ah`pY)w%{V-%YUoS(MQb|k-ujU8906iQ;x zqx#(qV#ALVg-o;hQ$9v(ISAZ>FdM?>erailt|&aegN6@CcBX|rEZaLRr)G)hS`lz!SE>yj_6rs4~(qUzus|~M;1Fv{eGcMni>rc!_UHe+= zxWd_qmvAjQmzFBGWQe}U5UuxMy5eT9QNcg9_+&qlv!BNUJ~=%y>my|0fZ#YaN70s_ z!gZduEm>#29Vn5k?~|$DR=G`E3eD*>7tkhJ(-7-Nykmm*wG8?|j^FnIV^Uo-&h7_? z$^u8^)r-?4%J=Bqxd6dStOZ9{^?2Zb%UlhnQKxE;A*$UMu9-r+C^p)`*Qp(1 zDZMqeiS}#-Jt6F?&L~<%P0R{uKUM~=j^W`Ifs$SK>MJbTWNo2B$6bKu(J3V9i>8V~ z!nl;|OHH6RI;Gum4^9^}ZYkf0oV|WZ5<&zI^V!es1}CBy0P3ML0l2?R(Qdv)mFTh? z=ZLQ<0xgYdW}Or2n%6O8S$qi!qxTkXr9`K0;iHN+p9X`GflMMpwT0pOS3Df73@Lhd zd$%@UduZI=f1%P~tNr%YXUvB<&+A?q;VFOFcRriOWl|6VQ@S9QZtUSxu=JlE9f&7t z#$7FQ+jpAR%V0sgM7?k?RL42%RPPxHv*Tu0)*1&&D)v9Yo(rNUQTb;wwI=XH1G4{7 z5QVO=y_HP~S&>w)ZO-m2`})O!V%h@bDSwfr9ggJ1G|FcGxW^-^>*Zgm8SVGz#rXi$ z$NE4fBbUDw%`TSMSWbs6%ydG+KQXZLmz*(1+m0^flgg zbdHn4Wnp?W_GR#4wOsmLPDTr~iv`QE2R}*!xb42zl;@i)Ajb^!67tGw5x`|eeqqSF zL7lz)H{{*)>fwkIqZ?XhH*X1ft7573d~k!P@6O5@od4LNM?NY%72R~PPcj z=VD(mttj~w>I-C$ zQxttQeV{Gy>KFOGcE|D%bax=->0eG!DMc$TfKi-kWor+AG3o(0D@lPI(+z0(!0NXy z$gy!L{vj5@&?rCc<@Hp`fb;C}-ttm{;l#pK>ZKY8woQt@of1rUcSh4e$JMv-YHV{$ z%~*)L(PJe>E5)4wo+r#$c6f*gaUH~AK7Z~I{rh# z0bc*u1pH%RMf9eAF=+Nb$KTZm@Vt3wHys6i2fg6j(J)fsD)=Qrf*^zhX-3-UpYk3F zZ0|nZa#`~&R1Li^f<&}=tf*FemK3c>bqC${T=GzB1O7{$^Foop2NF(-F)iHsXwYJ(?{?4wz8-=6l^(d=qE4d^C9}za-hrSj!E2q7Ax~s zcBzzl}Uxa z&z_k#GMi?g%uf3}KtIf?B-c=Wq)C!qgB<8@i~gC~!6?0(wHZxRcn6iC?Wr8#dGwEk zC-QCu=d8txQ48L?$h$0g<;)X$30qu=BcAz-&Nyj>-o&WyS=Y7W_%U?{)uFoTh~7?o zp_gj}*Qtu%&7NdFTFu;lJ(DfciH+Uzv%?UJMS7EKrqOa)f+0E#vq^5 zR>>guHuwBYt%oJO8Cv*+N6+J~Vu(zWx{#sLS?k3`m!+u43GF+fE_kTbb}D`9im-^v zQ%&`4^-q;fn6v^=7a|R4Wp#ybQ#f7m>TNg)dpIxUBt?DCp)Sq?qhNM&rSbflL0=GJ zp3o#NBh>9%Sfq1BpkxiiRo74Dr93@$HjQ4zEUKdp_w5u9AMT4ZCF!3T1ctQ==hCZ` zou)U!xw1LV{=7%upG@-qKwlnEKbeWZ6$AuHlboHbZ2wU7_b8VBTM z8#v4l1I2~|ym&YD($X2!t;b2+E7cJ&vN}w17M_A!>;&3L?Sdkn`Z7kr@70?D$J!b= zJpQ_=1Fo0KTm6eJF7XLvVvSCGba7>RP?hmJQb4Nv zjva=p>zGQfr9MekrCOmF;XQSy55YsbXTz*}p~@&qQTPfqq+E~QoOfw$ge}oQUx2&* zUCF1^UAXIiuY02FJzQ+mq5|dOqDxEjR?JE^)cXkPN!WST+)NZ}`_V%NbjR(DZP@#B zXMI?;EX|bXI(i>t5SIImLASUAuQ^?@>+qZJYxBK&9^ZrCe86QCFv6q=$a|dOqYRpe zX^X$!HI4*9XQ&vE42ToOhu-s1O9O|zMfUAj(=B+hZv#QU87^>Mz~a^STR4H_7IzoN z`3RTI9PgueddKjD*F0xEec|3q8D?I#~FggCH zV9+AQG~;p!xD$eFgkLm1RP37R8?QMoVr8M-NEJoahx+#Az{QGx5pKi|{01BULHI9z z2fmtzQVHtYpxLN3T*`Lb_>w8lXcFD3 zik~S+vWedr%)wOO(Pi||0X+<7V?xc3KdxHWabno7UB9nNC9M)ey@%8o5<~eUlyOKX zvr|H*M|w+)L;g^H&!9=vx#qYJpuQ3LXuXWE=a781ooIUuhR83;H{|x`6F>ce+n?s> zd{-L|K0o7)m*TzVRgYc6SnrUrjyJB9I0G_3kK76)7SbaVNdwG0QKGCn-rHUfTg@vT zyAG$DEa?6%6sE1i$rv`(@M@2#lC5Y+xuNmlKoO4+F5T*YSH5XSsi{qW zjl$4O2f2sIOvl1%kBP7K^h2SQ($Y3+FVpCR#uj$#UqC~yUU)52ovO>VjGYrgpI^&x z?`O9%=A6dGjGg6TM(7jusWwO@`kQbSIfB<$0TjCXy1MnKn2lTJJG}sQLAy^|s7twJ!w&AX{1TTwVsx>2Gb8!7h+Imve+*FiCsj67FJ854;3` za-wS?=>H!rU;99mTw=Idy`rfku%d>NS9q8p{(I_SW-`Z2I%fj@Pw7`|g-P4G=6Y$7 z^dD&dma37!5siK#jV>~K{tD~1VGh6ESkYUNMQbI?p_Ng`#uCoDcAj*;Z__rSzJ(yQ zHhM9>^sRyL7fb$)uD7T0MtV=nOpXVpf^bvi((6H26sASjL!6@y>2FJ`~Vljv|0=|->1dk;?bNqhm4W#F6LWpn$Pj##CgJ1^jg9& z*yr`;?xR-$?Lv;muy+L7wWIh_TUo;NwxrV{=^bslM3|D-aERN+(KfUjiOzvNJWD#a z$n0DNG~bg-qWP+l{=GfFuXuITBwt|tq5+o=2kLYipaqri#+7>b+Mms+WCB$(k`vVZ zjumz4o#3+6I=w5Zf@WYXl+W?u%7DI9UGyGE9IXQlK6H3_yv6>x?%robtiLW7FE>5E z=sRoRyvno{Ni?Xrm%qg2rtbd5dOc;q`U}qK>4~59nbidkJFn3!xdT<`i6mdvM&V#>aa>-M>LgeD3N*c^|b4rcszie6?yA?_Y385f8!zzXelNBv)ATy zLZ8MMa{1}c)*GkhugiAY;S)V+B77Xx^YD1qAUypmSloU;uQTUJ;+v0je>~9n$=ZUZ zxMm%v<-2jsiiWkX@JcIHB8I6nz$#e&l1OreEyMi?SnI2z%f_7Bg_h=ixX?iFUxTrw z=gw!w{v5`h3uBvocRn*VvU0|94@C>bMiN?xGP*!#kqW!MBM?uwm6~Gs(FSIDB7P=@ zm(9fkaK^dxI4Ix~1vdEZWYMf=#z-F&D5bpvWArhMvDh4h3NS{>{B_8abRmXQJxaGJ zy=T7#m6n+*Ro-Vkp0QxvMJL_UE8*HCS(3?WZKNgz;`&{AWO<%Zc2^9}E9pI`KV>Ko z#wC$eOP>rBvi!7YjQAQ+^BlJMDUvqhcnOm*r)o#X|g&hJ5m z6Jw*PNqxgOm>Be0sL}==z5>@o4U17#e*{1YIP=p-A6HJQK`(XY*0wEN;|_K$nn9Tg zEq3Wx*axik&!$qzjty)27dzB$Hnm^}4=4G}h6_Ij1>g-haVQ<3U2 zNn}~l(>hA{>&7c`pQ>Sh3_-5Rq=?s%hCuKNX2FZp?Pq0Mdm#gDO2VZNWLvZBjl;t- zWM*q6jmi@%4fy%wXbNs9%;opf@-k!@-H|1`N`3rnCiPYU{DPj{Wg)Gm7T#yN-dkK~ zudmIOTjSYeq8h?v&t1$Ru6~ z$l`641eK6TzX%Nf3nQP>RIA;;0cr}4y~e47DEZ(?aHpsLB^FKb9m|@nQh9X{v@L?h z`eW^25w23=3kQ0rxd^X6Uxbf#vo}@gUbqzAHH^%+puKngx;!V<(g!Ow;=Vt4(Ea`6 z$El;=emh|_65GCw#I}vz3=0J&UJ~2>mg_eX+a934f{EXT+q-JD0%cNp%Xbd?imoWs z$ECju0t=OOi00HvHsID?O2h_yKAQUM!5{rkUU-~k|1F7{1}cIEm_#L!Uw(2DKtI3j zvg|(b)!K8|X$MRlH2VYW#FGJqvj3U{{EG!&;r{w>yDfhv&tHEIK>EH@`p+IRw=(^! zU03v?HRxWu{IeId(8u~a1y2MK_%NL;-s|}tZ3iK>@2Ly7)u>GSKO405sLS4O>f5u2 z!AxLo1U7(oZ^19PuikK%i*#-La0Z-4=b{f~fsp*dpA3}{c)s?0q4>Ik6L4is*PCwvl znSsVpyt)p}Zm0iy0eCx!izV-pKj-1&#Er7@)o)dj-zE!=?N98DxhT z-CvjgvhkaLwi;c}-wlZ&(sh|PtGTcLxP44)hiN6mt86ui2#8PZ!XyO+uyds*+Ukgp- zH!AurzsZCquZSk|zd7&J-URAKkAo3Ewb>7!r63nTWp@QscDP@-G_weoApC9}6pPp2 zyFl+e5XjmTTngVz2RYtr4wW%)hx=E_gn68Vfm(%uO3Kt8Me&R}G`5|-${46uMa501 zivK8lAUOpWKz!FO#9y(pv6{bF)35~CW^<_p&{+`X@(YxXt5TBc8ukOPeP3v z{}~Fuxn(Y;$1+=Mh#K>uhUTgviBCHXYHnl_#_nz=K8M5&&qZnlkmk4)SvQy zumLi(FGWgr#NGg82z&TYRBDL@XYZEBFk9~~{w?R)i^})?E*V9rycR0Y$<%(1;?L{Q zNA2`^hRRN*-xmXB55so2${64>&j$EaQ}6TGy!-INH071GnmxdlrPJ$nCISEr!svi9*#pJX-&2ujNF_d^G=M`s-ixpFId$-A1jOLTx-e zTmS2z<)(MRdLQ=6*iXC9?ufl|zjjmM9Bvmw?WD+)!$FH1l(*-_}wY+yAYt>i)LJ zMK#?#&Wcv_lKZSjaUf8g?;0D}*EB-E7l+^6(AKul*I)xHXV-dCo6QjzEJD`<#+=h2|?%ix+Y&gG;*91~7g}1{h?J6ifgB zzo>;>VvfOn?OiD@nt;5AV^R*LUWEl8Kc&?_$d9iKWkO}--jz=a`xDSjg%;0V^ zwsYD+lTGGKswdO<{)QKa^?R!6fq5HpFWYd*L);b1wyQV?G@;#~3;GRmPx z(|EjJTlu_fQs;CLUetRD^!-&E>odaqR{7h9^!4$~5G1P{1w%q!A zu5pWA!h_vi>8b@U*3y32?CE&P&Dr8d;0zHr3=yMYnlK&@5pA9uek*PrA*TuC;NS_v zi=gd@j3KBw1ZmcWg$U5rK!6T5>O~}{3Ien+P;Zwk6_`$$fx5Y!4{~3`b}qU|Uk|7m z7;`n!j{$qG3UWI9>@rkoZLDuo6{E|If3@B<*S9$ldKOOBZFtY;PxPiTQ)M71Rxhcr z$wb>jktWvIAfkO&oO^(XR=oxxf0OO;6M-3bcb08`lB%6R&fKzCJa+vwY* ze!JhD_n|-RuATa5M+4=s0kz@@C{Yr|iBPb*68l*XL&53P*3I+v62DmQyA1_PVKo^B z`?7HFdALY>90|q9HK|tQWIJau@c4*j*x2YAix^d8- z+vFg(avpfBTy(YO9SK%@wW0z01P8S|jrr2kOD#P{Pd$jM2XUN!=qJlA#87`Bt{ymT@az%rCu6l%iha@`s^GEU8$3w=b+_ec+Wc?j zCZx}lezOL`Aq}SGihc41t{5Yqp^AF1^MTXR7IJMU$OXRyfE1`v+I!uMXyW$cj{$?I zf4d7g5{#=c+7LLc7`Rm=m*iO&v^DK`sHHDQ@|U>3KpEeyfZJQ}TOOdd*kd`8HXjbb z{zp9y*d+eVsrMAW{i7N5Z}FpL*U_)OIqi%VoXjp>DBn^kBfp46+plFR`tD3^x8a}; zi%R9Zk7%7OFVpT@T`=92-zw7rSHW)_qKg6+aUO6y92=jM7o`PDNXgnB71zc+qA{oz6Iy692iV} zqtE-Kq6F0rq}IdJ^~ZR+rurP9EegVBYE7kizjd#($ zYlWD6OrWgW*l&BeZ;N$`0C!lZWX_W3L#9f29$XGXb{n9HMll$%kr%Wn?RXH3)Eq0V zpW(kZUvyA;Oqp8Iuv2}p(*jYiLXfC8XxdOiy-k64Y{FSiZoGrPB9f(li@H1 ztb8>n;(V@1ssEwKYU=EeaZBp}GdZDNzSpVUn3hL1qqmV2<&7OaQ5zcu5{DW=aC{%ezcIW5A`~HvbONjq#Ez$ZLX#Hy^*6DX> zjh{j54=-q+wd27sakwmq?N+o2Cq$`VQ_G;2LBuLc`ryAvhO(frLt2 zv-R#Y_r=|J9T(q?i*Nld*EBdNuW_mF@C&87(`$(2ZKvQIY^RJsz7{Szo_eVYIJ@Ol zAN7C_-9Lopxm0A8pwK`wg{pgbjK%&%w0?Q7^$+)a#8Y3U_d!_y4tCn_v^NzB_3|7f z7{Ui|;f&B;1z#=pv+lDy;{$uOrwTZQfnheTV!@w!RrQ}&ET~2STOD-gxVL*uxBZ!q z>a3e|vIkA(UgEz0n4_f!>MC(mw=M2+t8v{p>`*aOmmB)E4PjtRH07yE%%{DKP<5Xb zpQkVn&(*^Y%IEGPTE&2VzM6AA%4?s$F?$F;wU?@Tc%&Y-*LpZ@{#u_?d&wYqbb^b2 zR=MJrh=JCYW84q30~F8uDklRbJF zMf-_Is7MvONC~%}4m>*i7W)(u>6elDuZY7G#}XIs-dA zg&Q*80O|@-QBfTtPb+Oi_drA2wcJJDK5*KvPUYdqj_Km{8hiC^7FsEJtzV{}t#(iJ zd~XQ|3x_ZZJ_un4W4V%uLOyALAkKR3t(fM<_Ag?3<+4IUEP~s#S}EC7ok$vL5^UZ?+!i-p+kg1#FUoR{Qm4{~7*~Xt+Oyt$NXz zz_F1IJhsr=8QsL@!#(Bmd}LQAuAgYW@(i`Fi`MR7UD?+raVQPP%eVzU;xG6vVVV6H z&AW1yUZ3|juAJYeIv$?DclTP8ljpC^avtuj*w;t9K&_eEvdz3G0j9T|N5dD=>)R{O zI#t5%sTN@Zg|)@BPQi$Ac`evgU{|&N7X0#wQ5@hBaOr(JxNokUiqd)Sq~A#`f6+Hx zJ@9W(EnzcNof;&D{8HXhq3#g-%@3m~9my8^Vx0|uPA`))l}B0aXFrVQ#e1wNDH3?m zftE_-m#t^EnH_vl?y+xu5S_|R2?(uJT=Tp&6`hzFQ^zu=jcZB@?qRHJeY9a20p))ViI zb<;bZ@_uZ{y~bxvS~m&*^X7@nzccM?`=QL^z_*dQ$YNg`1~#AtKjJs}8V$DC-TipF zsto#K;H(d@84t7CzwSp?4}QLyd-2U5EnD4R;a%-#)FoS231ze_bJ}(Isz=BQ;NgKH zU$ljqI%l6OVc)qraeCL;UFQUAq1q#b|E)#0qw>#XYHk14-^(=c@TJnFlrBK`k9_1% z$8Q*)LrakbIS`BzK=wzBR9e&mVxRDre4pl8_{TgY5gy_Vn0W*>@bIU6f4|k8Iv=~; zA8&ybDI-6pNwcq9z;IEAdGyhI8unx5nHc#eVN+YqYz;uVCtySFzwTc8#!Kav&hUQf zfbehB-TwxapBh9J9Xm$&Xq9Tu*$~(nNKst*4ONT&HtJh|aNg&0xO|8Xr5bVve+YN* z?)mGpoph9KN~BqMfJ)MEF9O^_9E#61h4QyI@KiqV2ESsN(?~QE+3h zFf$Kp`M}D~O9xqMq$dtb_7xw!17yA37dW6zM4o@1LZj#t5E1wZrCV_7R9a7NFAEp| zu8}m(!zcJLwpG7uQd$ePEBQyeYC(KXrE^+wGh2EokKZGeG*S4G2CJX>shB`bc1U{X zvC!yaZ{VD5QU}?n@vl){KE}s?#}*_TwbqUbY2ll_D;X*`j-6>PBaX-cv1-`B9kb(kq0s~e5+p#9Uo8(Z96Y;in- zw=3Yd1%kZ#Pl6=V0VfV-K_yebfRJ7FoN-ePw+QK(L)}zy3_dUkAqXW!ZP%30iR83t zjkpao1wOH8a}!N%K&h`<%62$DAm!@GfycHaPfVUo9b>#{!UvP)qO<6gtXb+?zkT70 zII}Nj|7rXCHwOiN)GjMLfkJ4co0E7QC0qF3RS1cmg&yF?W8CP$I&7PU07^i$zX!4} z4%$HRdYba)2OD?q*}3ue-*%20_U;Gc-f~js;w=&eweOhv_LWPi2md;k@N+Aty=2ko zy%esr#o|fS$|iFI!SK8mGaHpg4ctK*LgJ@`_%NuId>@w5huW~) zLv8w0Uxt!!8vuq2{|_=={XfX~6KmP_X+SmJcV`KVTg=tnPYGyQe2Ja}>;Eak+**eD zSM8{cTAL2#*JqZY@p?NXUmuPd0rDCH#88U(mFiM?2B;zU7K)=)`MM1-NUdmHivX{C zH>y&T&)6Q_s(*~zE~|PUTSZ&m;IvWHP}ZQzdv^MrXEFFda7%U>6Q5luOKC>HGIr~x8keRCQDDO zt?pz!@$dm#PjL4SKAb!In(jd#d(iY*H2q@3JrGl);j=F|&*26Pd!6>LSO3w%-RYs3iaQj~NV!7)md3mL zXp!HZkH&wK#-q_V9R6gp&1kgwqQkc{f5f+d*Y)behXO$cUN_dj>%tZLJ?CF=#f!xe zM>^mMvfzi|A}7HQgHSM5?~5}FzSRvK?Pj24Jph%q^*sL`oKqe7-XZZIZN-E9i9kU- zR82=HPD4?FhJ}7gO3RGlTR_g%B^N-qQcKQFVO}_;aHGA~eKZexs78B7q`h!y@9=-^ z6*}&4(>)!Adoo(4aqxh3953K%k&OHfR_q-ES6dO5q^xv*p%oF8^SS#WU{37*Qu>w zW2e!ddG<%cr^CRabICC57gEI@Lqm+FHFE6((lRicIA_8je1pDZH(33 zQ7fWwYYI14_hFi45mef?JO%NvaSC&p3;eL*N7iRK=|~f043_S=dB}LV3MHgE7~$?f zTy;*>OK^%oS6Qk3BfjGfe233{P8_?Oi-UZ#d}PH;l`WbP+Xd1T$<>IcfM!VFD^XK7 z=EB$LJK$+J5a3?*b>rMsk?Oj6q7~obulHF`x)y#8b-}=F2$Mj zfSgLUAuVu3ki1;I1wEQmT@O#>1N*F}U=7ttf4E?cH>6BU=a7{khep%LMcYJ&qtSXL zK@BFdOHZ_f;}-SkR7|`-^!pZVt&w)fukDjZt*374Xgr@%eW)|vM@3MtK?N=V+9ZoM z4NPr*gf{lFL88zzZR$fCvC7_P{?X7#o+u7=0BW;ep+<4fGn`IfD__bdd7assWbDxy^J@8I6Owa zi8qE{wOECsy}U%vz@vA@f^PxU^mh5I`>YPQ8C!xJ?Biws`^$rky2vGD(#Y}Aa?JAm z81u0Fs(uUCpgBsHDcxsxHMZw)4}YaM{>6IPD}XzBc}|$p1A_27^J%^De(TA<=C8l( ze2cG}SNJl=y15@B3G#I}ee5oO$+y#Y*GDUWRBrDG>=*yl7jvr`RX|&>&k2K^k15j4 z3;Dq>Rw{CG!8bt6s9q%wf`IzNFWb0zHa~!%GYi&TcE;;nQR5odTKe6%^$u-aWBnVR zB+tx78h^5SX|@MK_vYMyP`p2eIRbUHca_dly3dk6&BkWP^YzjP(WixL(I=lriT_-T zhu@ifDt*9u;*9jE2MzxbJ>|Ud6{h9^m|D%e&(623&sX`_3{u!6+K}<2t z5UpN=Xdkj0q;G)iQIKugbDAl;#KA&)+Ak#W*)$~v7nl7YeugPN_<%L}+=BI2CG@GM z=!MHVGN5d8~FPOP22c@636(&JOfDi&FpL-o-?ejf+o zB=oVPV!xjxowUvp>2^q;tJjM`C#?{_0wfI=m0G+B;t_pvmLLb~b4R_tJa+@z^64@KIe+;{#MN$b%Za6njpx zs9_qREYz4`+PauF)0VB5#N|)2UWbZkb%b|a2QNr@R5YCb){^OOlzB`B@ZdaBgaCgE z?lp86;nJt02$B3$bRe&n?5AT>shl5{j9?r zv|jIh+tGHY9&XzkG1S^BwgFoP35Z~OavHg92}mAwsuHqwTlNVS3~wi=wX%YJ)HfLL z*~8T&rFJU4m6nZ5y3}6j4@H?-Iph+{4MyQT8Nl{@%SPoOcD6ZeC7|6>nVU}*a}5A~ zlV~s9F|fnCG3Wns$c&^!q%Wk>X$k310^N~(04t=vt*?U~0t)extqH$^MAe^Y9c)+r zY)MwVnT-|S=huVnxsnFEr6Q2>wJLpjPuhZG0h&Ee%+({~Z&8r!NCI}=w^nsMsg9;; z1C)#tCCk2`BnFj-O2RzKqaNIodsyf@>WP0YrkC83q^~S~SRqdP$8Et!@M;7+#646D zqK^#>^aNn(=M=QDwLd|xocKA7Ebd$By_4_I8k?Pxo8ph%DfzGD*Tw&A4wOifoY$O8 zpUXfGbm?EJG!|=vs;7h0(ZdUNXL)}%b<82F*p^W`UyY#^9Lr1j%1H|q zd$0&aYn(IF*)pN=?AqW_oYDTlg(yE|J6(#(|0`4LKz4m(_CK#!%OVJcudSTY*F!OO?FwDP$LUf2u!=z|s(xq>=V1 z5+>(m2bxCk27GyOWPXV(3oG=NGQLJDq~s2f9MB=qW0|Rk9eS*V9?H$dh92>Jw6F+2 zAzDRgsJzrn_mkuvNG1hYzxfVjKazCWbOWLeL)5TrZFB^`4N-}adS647Rhdw;)oiwb z9eU#lB#q{)aUd2$&}S!&OwAi4ZFWzi80``SqgQ|h;Rgo28o_AM;SOUf^Lxmi@|yQ= z>EiD>5SvA%a$r-+fK5Zu8?mYEVz^Z?yAliu%gnB9APXdL2bpwQdu(FujZN%+hISE~ z*hP!BRJ&j%9Dh#|K+_~xcV@P>(+DU^U{GUgz9^?AMe}3S|dF z_NPYYYC`m!|Ey@wc|g+zJ{3hJj6B=F-}u|b_aXeg)&Bc~a0{?k3$!1>`h^DlBJ~kj zGz=PioUP5kd^+aAY#QvjTR55a`SDa_jPD^C-}NwhYPR+?fqE}_)a?B{q<%o>j<3RL6D@IE0+Y}7Qm5Q{E zDSbST#26HuJqd%c%(p$;{(CeO`VIimicS^Ru--BKS)vHirJT zVe)Vb8$y!9C>F3c-S=WhGB(Wd|7S>2Ff}lcytN%53s$GkBq*UP;Ob(Nu^2zdO zJuUT{^j}^KR?dkZsHPxxHKLVS&!UwTrU!lHS+t^V;8YHNAzHbQm)-RJ5)wrkA?@Qf~{*!pkpQbi|>x_QFZg|aqiEBHm$yZw%t}`LWAzw6pQqEGg z&~1I6z74%y`@j6w?Lq&){MM~xt|4Vlv{1^g?Xdql2rW8YxG?PLz$32+F@IJD7R46+ zwzsbk^zk}LU*^y_AQq^t7NyV`^6Ir?=p6R%zxYvxg+NJyyABa|J&qMFG7}Y_w7nWj z9C^=#9Z!~Y=*@-5T`_ftKsc`D&=)y0)^ER$Ow7&srj066IxW;|#L^iq!|A++^KE)5 z?iqN=rri=}FoMHl2nCOk-`Lodw|J>m>fqA|dagnh{9QnguJKLo#jN?sbL z*NCUn^&sOj$Y@T*A;gJ_3?P=?)aD}A^vPbFp?%dtpUWe)eB)f#*^?)M_IutdVx=E* zs7#J2lO$<%q?k%U2Nsy7Dh*Suf~ojN?yN{i5XGI%B)Q_Baw$bpLCx3xQur;?eyjc3 zCS%_%ii2FV7dWNV;U2#iqChPwStu$e52AXZJC(WUY)P3}1`_A!HDVyq0*Q;zohD>i zh&)5seKV-GZd3GdDyoIcu|6C-a31hc4>gq@Vh7HU9XM|;82_Be;jvI+rr*FxxxG|5 z^<(cPuQ?sYsDyK*iXj}V__h2nKuvfUw4UOyt9rp!g};H=W@JS|v{!+FDKVBSa8Vczfcb>7-_I1w_+$&gW?UG_H2@K}+mUG*Ld^_U6NypyU zTQ`i;=AcwD6%@QCb7Bh!UNTUT5~xDM4bbo~G`yF@Lk$hN0hGCE6ONKtX2E}}>T67u zF8q(o6n-^)w>!Q=??%)GiKx})eq37jys1vY(?4T+teBoFnT zNyCE6%D#ZgwNxSd9e>zEgn)cW;zRDpZDV99G^ne5g24%z$qgg{EuNIkwU8le;Zqo{ z6%~hreAU@i?|=;>ansK~CvPG!?32e18k9Jei-BcWoSQct=yF{jh=tSg`Y)>5^cQZ4 zquS;J5Aw^|q&!1^_uJ{z%!n~tXCI&*QJIgjadn6&69oMkl*Z?gHcu{of&>5bh%{No+90dpq!_?UqEC z_cmyM(ncjq+Zk!WYZkw6wdYpjqA~IhDr$-1R}dH=7_-g`#%RF!(-0V(iKXcX45sm# z6Y$OwvXqci;4wnzAoM2A)OZRnlKieG!;C_=WgEh8OEPWl1M&LDB7PYR(HG*W4~JXr zG?a_R%0D1Jl7p1m6I&Y*623u2V2E*iCXS}phaJ9v^h#GS8j#Lsxtm@W+u;%#Zic3r z+On1iO-B}nrcv%|cx6j|-27>)zbVhyyoUyonM;Uz|lfPX-Xb|{Bd zV*-Z50xf7Oy#y`hn8Q&LYAlf9xV~@$S)BrRN|X_4&r$iBO&Y#PN6g68m+v#40}!T$ zpYl-2l=r=vqRJt4%L``7Sq@cvP-P@kxv-qU3%Rfvs>nY^Iofg=rPf4fQXHD(WKv0J z@};RsQD`z3nv|D7-QuLV{4Y-ItMy1K{yg{i@5>*$_^y^mcd?tU4!1zs0&O=xwVA=| zQ15LcRBR#oaF~CgOcP&{j8j0y=`7S*hh`2X@q1Fu3TnweMmeImf>LV&&MDTyKo)8( zGKPuEy*OWsJ3SGKM6p&gBe@yH0!Dh|Sw`~8<91*_ZLvv0SZfstQu?N*c&HMLb=iy- ze=?1ASK>w5ExH{Q-L^ruB{F)u`7MlIhBjX6|Fsq=}{H8Mx95|o>7Dpv-|t%hs#*;@AqlHc)pXEW}jqam8NBj4@FE-78ifwnKdH?V%P2J;N?)e|xKKB5!W0gtOTg~AxoS7hdwkg{J*-Ie1^R^b5+>0X<9 zz_X!n0!>i~Igz|mQIn{jqM~+!1y@%!xKk{3g5T&AN1d!3KMZEU2I30oi=z*eTV+l! z1Q@OHMI>gyZ+czZqX(Qp!V1z$^M7;5T34e~nUV7h;@Q0?_B2sBE z0-i&j4XHc4n=nki?~O;hFOYKtM;w@GgQ9AOUB+>xT40wA<{6Em28MY6B*pSOCMv|z zNq&is8Ov`NlS~+X)wRc+rW!$y4?zz;9Tz?fK@WacSZPXv9!q!XhMiNZ+ zVFVcsvj3phqcR^L_jVG33}Ck>k%!Y_=refGNqqUZ<;kr@-%=TDBpfuc+3d!+$*P8n z$G~tKH?zo}zRbV{gcn`bBD@#?h@j_`_v@7X-i_wP(n|ff?P|9DLM3tVZLm9jB@X^2 z?2fsWxE4ZS&km&KdB#;wbXb|sW-9B>^j&gFJw{;8b_=6L@bSmw;#tF zk6Foj6`B=uqH%7?`{X8@*UFt!;X$D7QTH*=f|NbpWp2Z@t$`|+#jl+^p`D@&*rdmc zUpv9Y;nz|Oxj84OY;B7@3;&A6U*|-N5lA;5HoGRYIQNvwL5mrDA`V)VfEJ6Oh3)b} zNjXp7u%_70orIGs$|G#{11I3$?!dp@!Rk2~Zh_PV+8#w;kgYAidil+h?pcy@!1Jx> zMzynlp|?2NzcLH9`pF1}iixeVq2xv=d3X?4L5YrPqLu_hWw|I`l+1s6@lQ+j0m`Jh z;j?RnAj2qCgObZkC0~J(8=z##E7-+~I4^ZJT%Lt%H{zD#s{V*9GQx<)llsvH!icW) z$&aZp=0>h_i!4>j?)FNd{@Na@<}E@^d=%$L8dapvf22?(?epk|sJ8Y4eXsu$qiyGE zAg*tN6(W%=yoQbJm|!;%cil)s@pB)=_$kI0rQ+s;YLZ>*&cCM8>ipss`iEXsZqm*) zecw%Mm_yq@AM1~hLam9ufk)Ds#z=Es+6KDbEbm>sjNCO^i%_Yvv{%PLGbvuuW+S~C zt)>*^E*g@w;QQ{Pp|M6o_0iB+T2tR>DE^fH`1z9=DQ9Vw4OJ4Z*l2@RUpY(LPJ*|R_MRcE zm5u;@!NxuBdlwo)q#CcttN1uTBANr|`s3V-i##j9zo~nLJ zWltTwUOA~LmF-SdCv3%49J6Z!hxjn2_WXHxxV;LIrrPftYPW>E4`@wu*r>X#Lo!7q zr+9J+*DD1Zw1HnJ+Q+unT_18SCrv7j1Eb}QMvckRkKUlZWI25E7F+({zQ~jDijs?V z_oF9Q&6d%V7HD|{tqC;@az6t|gemE#Qm{UO`+K0?_TiS>MWeeowBnSB73|i_k%e@c zrgx8{0tAve&!jkRgsj?O$kV>s$kYCAVV?HrsjgWr)262HOuhsI2IqXHZdS8>^s14r{pa1e1uBqe33bVt1u;d3ql3@Q< z*146WZEvJU8{w;eH^SFlX5RL@1$(g{-bqCwXf-A4#92eiRNuFz6ePjR9|S42P%Avc z5HvgZ9Cc4&20V`X=#hzZrvu;O{?sn=1=$fa!jO%kG}s4w=n;3c2+4XIaW$ONEof3x zN&fE9R{k+p^D=IHzDM=e?80tdRa5-EMS+?Q8QlsP-A2?yX*;#e%r>)vuNWF+LxZ;r z4cbD3x2RoH>+Dvo=fTFfA)QYjE~VaEE8`}+Xp|B*+Q@tB;x^-r)b8I(-dkfQF4LV} zov=-==QglIrD8_;pXk)1o@>udK0*DV(Bvvy5i-l`d4@U;sMC5@XojsNdMf4|J1@)y~_^-&HckXbJKe?AvJbIK@vb{SE zkABccgMqXuM)|Y_YXuhtyKEE%cMsQI3$A^$>Drx!YcJ1HJQ1!POJuV5LF(P)JB7{| z^-=qwNGj6D!W}2T9e*kAxGWG6)UOWrv(UB*52$+T{zA7r#&9_e;26fx%XN72bGPhG z$vl~P^z4c9)X3M)_lwzTBnm?fho7#XjYD%$W^s+lEM_w))ZQec_r>(s`n|<`VrHH=z>Zn)|^u-?+(^!`#o=h~AeD=I8yNo>@9* z#u&pvTqkSl6KtZ5REk$A5xBDUnvNW%JU39zs~;w-ww*rL|BcgjS}0cU4!#W1*YiG= z_G!f|U?u_nm-&B$e86u-1}X+Dw!**;Pze1^B=0|pnqkn2R%*mDwRK+S8bTryjk&rJ?`!{4tnZR1N4@N&p_RpRFk`=S|vO z+QeU9$EiK-M#?YLCD!v-Dq_P(l@Kt*qJ*a?gL=oggP_mQK=IVVn6Mz;mOr65eyzvf z(BdsA#r61mEiPK@e8u%(pk;Nq$kAEV-0(Hf4eQ{kGPy;^xaZTpfNjR*fpi<=I&H|HI+YfM6G=&#YxRt~hK6%AE$wW3iDBW%p}cqMGi7n4*9l(5nJM&lb6<=0n?5E7weRf?r? zFiC`!qi59b-=fNk!Q_<&hd63!)odJ*%BOj9Gt#b}x|mvo%K5LU6y&F>@avxiiYa;! zf1nLb(_g--1<^45wFIrGg_;VP`SppC@jK2aACU9aLemvp3uGPHGcLjhiXfU4!XbkraH5}_hr z;W(|+aejD)uD}7ideJotch+YkFT4JLDuQxxb$Qf9Di+|p%GROrB}_CI=r{X8i1bQMHjhet(Bv$(p3aq$sVcO_ogl5%W^xAK;lqlvj6 z=WaWi@`HDK*RaQ11q`elx3yLz4Yx7(4a2<$}kVuPu)brKC(@x%*B_$wfw>4wY z=_T%!!M}ul>`0(C9G?|96KSEy4f1#}EBPvx_w_W%JbYih>ZckQj`5nNAg&pyy_Kfh zZW7T)dO|z}!1e*Z_!I8WW9M=w$q#?w;#WdN*e%GZyv3K78xdF2CcTE0GLTeLKc{Nvj3orCkq4-fXOT;0pDfrx$ z-vK^1S(|}1I0~W%8KUzbdXOoaTj^d!?dkwqWVyO}#!2M*@5f{3A^E=j-UD!bvMztM z=$f++f3HwG_`yIaJh>+4p2$qTa?Er5Y|@!yQm^L2oSo{O9LRLxk`7)hutopU#;52B zZu~|e#)#KqkF$1`Zen_&=*S)9n!CZn^QS1e+FC?#^{-ejFS?G|Jo`wc3E1<;e1+bx z=vLw{O!r)8YqloBHD1xyMFChlFi_fz@EW@xq;)^#P0l%f{*?54Le6%>%m}^EbC|js zx;z|R?r(HC2VL%?x9g5B)5QGu5X;@5)3({iD+x0Eqj?-F{aqDb;(YE`3ofF(K{4Ql zFVk+r-iY-s+9)!`ck)7tA6*x5=hO%OC=mzF!uJ zq9!`7FS@<#`kMc&+(}}e(^>Nu_)zMX)+6Bh$ihKJz%`-j)^7CbdMb1B$kob8&8aMI z%qEKSZS$=JTtT?MPp0UUTPH3g=bSK2FxJ1rG=ULtVes`UhEAcP)0@xD@S14`gbb_l zKT)`9_pVuNra8+k*Qk6@Kj0t%Hy1v0HY_TwnOh&d^JB%GXq(>DT z!unDV{8#MHTerE`pWI{E2Xkjj`GGM=_(Vlh08@hF-KNrbb-UkAaJ~OxKIq#pi^_T6 ze2c>QeyaZ)YdYU9aK7>~MZ@_IkYi}P`PXo`VT<>n_d?puQ`g0PN-2xs>W}cl?H#fw zi>Le8@SQiY^?zvkP7c;VNF4qUU#BA#ym0F@vNpdGvtB%N50#d2>4)N(?`L$Ok77N( z!q~4FA}O5Uo2pxV_Vo|YdKqbb4E)xMfu2R&Sr7f763$ZtRJJVSPcdEmK>bl7gX)M;c4G z>KMN@^;x)DQe1okxcJB<>T0nMNaAX$RsK;;G8Me|&#pDZ_qR<^-5vz3mkWc|wL&iX z#up9xRJA}`Bw*6l^9W<&UDej(u>3GV+aP5r8tC6COWqx_a6ri0@64I?uJbC*!}e9~ zZ=PTT47ItoYkN|XiWGfDuq(mC1jU_y1doyV8|ZB=V!@}oj2$+#j~PecKZzr%;=p(0 z-Mw8mRi&cVvZw$W>ZLkTUr>%cTHl;vfezZQs7b*)0%hd1Q%Cy&?&6Mf4<3LAb5kNtyp=Q_@dnV*W$E%zcThnwWE6;?+!< z`^fFA_sOptD39tv0p+BA+`=)ayVfmmq_M-ez4UuBG1)Jrnv-3N$3(9t+d);#^8`q* z@6h9Q?B6yn0>F1YTVmS%R8WIXn>UyLeZIB`9tPe23ry=H*d3>U0fv)QJ}_DZJ{zuv z&&u(|I4x0(TvistmlcTzKPcRBy2@OfWZ~jm)x}{Gs{W85N2ixg95u?sl*3${@PpK@ zGIsCc!tbgBv&!KpIm2@y?b`FhkqnE!rbC8Bl>5+7?i!RcBhP3aoB!!&4%fC9=Fsb| zkL18Kp*XyXrC*aK|4o}4H_QW*UY|l>25OO-iLP8W4}K7ZX#=B)oc9C8()7KTwQq6p z`?vJyntonM%`cHa8>|zWaK-N2bc$4icdjMnk7JjPwW3$vplXw)9#_*fTSc!D}cQ!$P0=53Y7T3(H0INWxVU5?%pDg0TlOB zPqi3z*TNLarL%gg7`n*a+0S>*S*QuUit>SN1l%-+n{%ZZ05^fE^^X*jXz9HtxG*XO z#$FE1@zL7|`);9`aa@B-&O+sCQYecS=tz2$!=*TrSLK(m>8-i1qOD=PF(&D^Ey&4n zqhPHpxvjX`ND*G}eOzCW(?OOLf3vvz>iW|G3_1}k8m<%J>T_h_fusby@^DesN!wbRr~-FaQgto z9b95IM+!B=hsE7Ap8WOM$5YUJ7Ybgqk!ncho#x6tZ3d=JR)STkz|U%>&){*|69XL* z?YPZ(7nZ^{c8=yVk{LLRqm6l;4>u&&pQdCdPw??|74YctXZbHN%`y3V$Mx##!=c{KtlHs*UoAKjtUd$SW{ODu+JFK=;q3aH$cvl~366 zI}zjI6$WY#^2lb`A1|*mPQkO-g|}A-UTSu-9P+%u344`LT(p&!$KY0Ds_sZIaB!Za zzbhZ9O=V*Q2bXFPo2uO)982BQ*L}`QY~YZog{vtMS5>uBtxV%)h_5w$2tN(GpJiO>g*+}=T7^=B4${Ikhr)|#cm5$8Dj+ozsPUw_a5+C2uNM|=6khjfiz~mjN?vPS2UY6m;PtP_k4f!$llRI1`i#T-w2_M(l&w<6ScmmZvUO*Hlawgjk*`S zYU^fHO0mES*To9!RcdJ1;YtfwB7Z7G$4g&U6ufWKD?ubi=u-hZP4ehzd``>p=yNS7 z>^DZcqaXpOz5-#j6_JR+LGj#AzUjW=&P~q@9JWc7H?%fJTAPH{n9-VGQf6?ab;f*t-Y^^O<-r!9QTrW z8z(FDE)8KM8}lc3qxakBjcx1mR{*>G3eBf4q_*dApoA*c*UY7I08M3QL#9Lx9qz*Tvq7SCjQG@swJ^>IMr0(fP zLqd5Vk3@P}E3%>>-x^ZWcIq{!39{?jNTrzyId~R3kX`pgdRHR<0sIn=Ch z3W9)DQ;d}$f|g46Dj3G9##1G;VIA(H*D*^=$OF56N=i#4&@Cw~QCUXeYnh|O@=Kw9LXt4KNJ}BYwF&r> z^Z{in_!dMAcIn6z@WEsU1w5BfpxIbIvwgh_fJgraWURId&!+V>+v0O8dOf|mRu3gf zH@8;8N9ql53$dBXFtT@FHV9rfaBqTq`BbT)19f7CxSx7%r(YFS=c*L_%pQZWiBJ`6 zy48m2W&1hW?oD&&?4io=4#VQ&!-sNZWF9Zhu{_8|u@py^lqXNwlFV^Vd~GjXRcNeB zNA21#t@RyXZ&4o)m4=urh3mfk#eyC-neIUpV#9j;niKQCv4uOpt7@ePXKlGkllTY< zs$V|kPrl>1Y1$HzcN0UwONbU>%l=}^nPSV5#%OKe&w-89MxFxgRGXZP_3}jXC+iC= znCzcu`3eoeU6)G3FxlHDQ_bXks3weB3>QSJqdq)ecFE|HKN`>HbLdr@{bI9`dbj+h zw*Ayyu~+Nl3ggZ3U{P7@_3D91MW53pgCaV~= z3Di&!+JuAI6&0t@P3;ihv;?X>Qkb|5U5?5>D|D$cNEd3*rJ_B^vHZw;C9V98OnU7C z%Ci*1LlyWF|7xy}9JHEVvs_4180AIeGT}4sMz7m6pTd(Fvn3Ms#OYJA@YL*cvRQi5 z?h7Kd$c@aS>M?1{g6f_5+809{d^J1JEP~hKTk|9HgFup5N`uk<_UG+4koGIFR}aC4 zbt~nP`)1ljPj+hg>zRjr$rm1ItZauN{}u{!Y(wOEc;zX{I<$v$=7n0ip$40A+ z%-IqxlmU*gkA`6W8c@nRI9Qg|ilqJRy=aVHsq9%$WC5r^ogHX;E1I5|t$iKAW6|`G zNPU`N^^)l1^5;#zf~KJft*NJk57HxSKSvD8vh6~){DdnXN_yoI`(h-)rvCro>^dH=t*`r34~rkfP^{gobcZ7oU;Lb@BQCl*>!=_ zm8*{_pkd+P6ujO=L85J{ms{n!kZX$154Sce@fB_DmGaa*;Pja}oPPPiH-rY{9XD2B z%zr`hwSq%;Tl4w0TmMIEF6MbVPne@nvQ*J|A1+{=NWKrS?=lH9+aUdKZw^!A+C2h6>iyAeEQVSG3Fm?TWqQ zc|3_C^=^85nA1V9f{PIKVC(`HI4KYzUwCq}y*`BG^#<1+yoHZD?rWZT_sfM8IBNSNBcz#*Im^Fj)@Q+y=j9C%};l)yIjaAYm zTk*Y+eA;;l1*4l@lB3iI@G=ZGjI(d-a=3nEz4g3dpDmK&{V*|36kwnEXX>HyyM#Y5 zhY#b(aVj1KQb~{dU$i%ESCI+9Sllh2O zqgbBLlZ}>!Yu#YRe~IHjNxw8L?|lAElg5``YA16W?}f(*GI2uY3qKh!eWO&{6azB1 zI}9&!vED${W-F<&QzS9Lra&IfmNZnf(4jX1Zc0XiGl!-sBt@3STy)sM zV;~07PyR(Chy2rbkw;Z(+Kof@e=Cv7fP>Wj;E%aD<*LBu45Z+&=bC$r7fB4K;j3~v zBx-?7=qrXqwH1ka&a2IhYEJzmYBJK4=egbXn0W1A6thD}lvG(~LyL`@drp_*d&RN)H?jFvGVWSR;FR(I$d9<{zr`tF3^4iV;n*xz3ItP_r#h!i^%V`cd1r+V4`Jf6gL{pQlXq;9;X9wu?hrbUk_5hT@16Cd#XlNg?F1>h?1<#g% za$iv9N$m8M+%_;DrK8@jE>E`;(!ywWQ zM3Br%jT>FtOxY7ZnzIxj<`4R-bs}%JAm+b4@?BD1+Ns$)>H-E0&3-O_4YZGQ&3`HP zvsriBhy*kMI1z=z4fWn$IG^26Y#IvdV!gg;x>-^PuHF+P2k*1H_)hj|&`mhMTt`i^cb5nM z9Ygn`Z2C*z=CqXOdwjuR6(>U^pXYu_skav@TT6snMFS|92UvM3KX6BVKLqW4pI>|5 zkNZdN(%w4?kkN^DghrMUHnizQUq4kF&%5;T7W#&NP-!l$*JAZsdMx3nP!FhO zh1$vyr6nH@T2uK>PxWF;KLJ+tie1W2%=OZbC_QmOTZ!tlBX|H3a{&iFWRiS|?bEOF zKKhg`fEEvy>cJl8wR}o4=u~^&EIsF0;j!tN)QtL1wllJZIr$F@Ea@-96g@@z>Q)~G z6q8Jfaq2Zt+yjbx=#%z(JrKm|`vUm@SwN=0o48n^A<`%t!3CP2N~*M4m%i0v19WMW z3KAns62nw#1R94x;}BZa2(5}yhUJ|;=*~IjJWa=x6gw?EE%maW)NiI~8{=+0t{}dB zxo?iD4d=G{a0}k*uAT;sjrtYdNNXac9RRSUXP*OpA^qTCq`5#+PAR0F?xqGsZ+Krh zL=SjI9>c`8jebV*^r2K>^z(X>Lig1sD;(`l&BtrCMXG-iZ8t$UQN01edqH?F zecBd;5ez&!_pqx9nU+DkOKD=Agq3!(YvUJjbF>SQR?i5Pes!Wyb*Ezy#w?PxkVZI1 z7t*u&O|QADyj5f;pY^mM@Kfe80z?m>0Bd6uL} zefo|K?fb{XlP5yHN||c!9 zqp9c4gdm+qF_B8kV)dO~dKrI+s$&c`k~vc z#(|UCFVg_SSEALs(CS?@pq;e(-NCI^4v`>$8Oyg4il^6P!-QT_IVA312M)Twrx0pY zGBZ6Reg?PtKmj6-c2bE-D`It*m)-|NuFx31MujxYNv}KWQDg6Q?+q{6ybWlAFH)sn zBtannfDn=qS_Azty#b|hie+i9z6d{9l}vq>(cJgw$?d^QvSVM1TGAK5amkKeE}Ce0 z0o~`MRP?YFq~S~N1vj-ta?RTRD7C%47QI0GO?sFrJ?zU-$bR0}$bK%l9-VqWhWK+M z!T18*EEymjH1nfPKsWcXGx1L<4U6Ruj0BMRXL7vw7#lYbpE?wtC+uEwe`~Ufa|7D% z`?l7pfL{yY7Y=^56VHHUi#nF&;P^E-eog(XcpPxdSMY7KY~-_l#F zXW;!#(N7P<(4E&-#_B7OM!&w~bhw^J-3qP?ut@m7;`yeIKVoF&_?{Hb-K3|{91iGs zv=k7y2(~|h?T^&2qoBC`{fwiT28!FsH&xUa)f2C4iE^5hc-Fy1QjJtABl&kjocwr4 zhiU#(wp6IE!TOB%Kb(*@RAN{Of&}#Jm-B6HWLHP52FC zUElh4q|7Q{Tac%xKKPe`r{)HcYRnutn6~%fKJx@5(P{$@$#xqD(~XDg{gsnAkZwFM zk5clo&30hMgFP>MH+m6l*wLHd?S+Ez+)vRDYvWZ~i$<)qXtC0W%)U!74%O5T(eVlV zJ0)>F159o#UX`ZsvpmJZHtkrQvDf;DP(4eH{l>lto_MB~ zMUdAzLy17}fDmNUKbvO808eFpqO%ejFBu8*56Ph1DWB15P{L=eMx; z;+gqk9&v_Vl6%y7K9AZ#Uc0%I+&>BNpA5uJAuX&BlRI9&Daq%>_zm6DT^RW7T4!g~9lQ3k*?Na}C=44PrKdqJLg;Z8H>L_0 zIkeURJ93}j$lV)ZkfH+!j2AnHBXbbhU$zfa8ovbj%Op@opBl8=)d-1@0u~wNFW8~L_3hD`K3c$6T%L5OmkEFTUNDH!B>eu<2cHMG= z8w=J;3*a0tFwu zQu*Q5FAA?C3rO^KE~8Yyteuo-5^3Ohea)|510OuV1B5jwWeKH3p|l&6Y8!KzO3(2^ z3yyU?^f&LdP!*KqOkOCzez)ij8VVS4Jz#@2u+?M5V`RPcn~2kP=QStvEv5zPfzrLy zA2J0Fn`x(FV|_iZg>0?#S1}ktH$bKl!vjbqJsg?_ZN2F_iHS7;a*6)_M%Y2&-@fJw zXBi#sR(o6tL+Br`<6XW6PJKJ|*1mJ{hMShgrhixAJP!X3OVgowYuhN*+y+C_o7bmV zQ|zXrcUs&&{;^7cbaYBR?_;-?Aphbv&L;-Yvr6#_bfWU+EpeFBxhm>|E68Q@FeLk zs=%W}*WOYv=P61!hVgezqu+U5wH1K5o3J+t<7gU zPUPj^m=IKJkJU3VJ~#C|1;D=QSiYcLr3(>%X{df^uR42YIb{l7b*8ROte3hbfJ~ zs(S>heiMZE31Np2{!6?1yq!Pc9co|SMul2`P7mzaQx=@nmzq562iHV@&aIDJ3DHN> z>rxrwrdF?m=c?B5X{mocI_Dgkf5*u**G;J*Nxut|e!^rATHgs95p7U_VJ5dh@rCbm zvV9kn5ur4cK9J!K=wanJ6kO;Q;(J%QfN~4*ABUc^LTJ1Pi?c5}PviqSB{-f0xA{?$ zV3+wr%owDl!)f`(E0bOTBc`sK`*UCMZ{1sp|jm_~A63p8*UXN}~6_zRCV~g~OAVPu+~ryD8qk zydF1((e|$@z^r~#N6^q7USA@P5Ul(fZBXI4@Ji}ND=nzgsz(9F5M|-Fxk$yBOEHEO zB`cS}GfjV)=Pc!ch~K_hg*q}P%HIbp_c1>0D+2VYXz$SjTWB4|0uVi5H&(qco z008@8pAv6R%RQe%F$cfRJDN=o7Qj92n&ZtN{!6cuA>N3Ay_;hEV6~gd(xc` z`A4;sdRoespZwUn2I>8IR~O9d6#`y-dgLd_e2KjCVI+wEk#hHDW@E~ zAEgPxw2QQVvmK%5VPWq|RmgNsPN(Dvs3&S|Og|j_HK!zpTIEP{4tvj*4sy@>nxeg^ zFoI58Qqw7&>v?^4)JVeVG)7>Vj6f@CUXCmeb46t~gCTrAVOJI54A? z9A!kB2k7IJv%y(C1&i#4VUY>qE`pkRo!nNbvQV}fVGC$?i9~S(iz=2O zhyZ@dD9$x%y{(k$_ON2vrMWluAI_y#xe_S)6tLZHw;3o3)biK04uxIxv7EKE!dZ(u zSJk^9H%b@7gZftAsGf!|KUojGf#{18F#!|_a<+9Fpmev115mm_|B5%l1NhKqap^k%U8R52R4M-W{RSR}fnQfn!zdCz z%kTW09BwzQ`Wfd@E>V8)0OY<|g6r$dJNk?feF>=cGlFXWtGTl_E0vz>#ZA%xFJ69^ z!8eAd!5P14gs0)8gj?N}e(oQI=y#qZH!yW*>|XIT#1$H9$EbY*$~T3w!WFkIXOilw z{X2!84deU#)-&iPmYSoyFTI@Nx(LFCbzADKDy#Cog@`txyIU+zf;Pe!)vJa#!)thn zIGZ37+LvBbQ0m}2*tVFj*j`Te2{3yAj2k|-2_+66PvU4VJz%G3`U%cgCVs*B%EZr< zHuhf&aIQ;#7#{@Mc;6TW0AxKuyQL*q6Oik5y14`|V({D64L&r0{*^xPj!!RxEwwO)<27tx zRXVX|5{*IDM#uo`nb6}4>3gNSy&s~x#0Dc~3)%fSQJhdKr?DHa(s9>$yy&cF?m$s8 zd}g@3@L(`vFW&8*8!67eqWkiY+9C_pB48oqO)_Q7gYg{U(m6vOeTD7&*UBIdX43GUwr$ANL;BhTb(cCJMS8H3WwSz~f*x8QO z+R2OjC9k0`t&PV!>41~A%Ntw0)ZSo$z~0)H&AEn1C`qFa&BW8G(xp4Z%O~slw0)_@d9Rh3#6l?oD}4wHBJ-q+8G^%_3duI z>id|cD%4m-9%pSeu(APqk$zBxn^8o^5jiS@JxY(EQP##hML`nf52bBekS`n*=(JKh z_z_iq0Q2&IA@3hzv_6E<$lRiLjZy$`$)~mQ0_JmgnItT#mbmN7#`HWaL%UXnHWWi^ zyS$;lAz&)E>CC;KmULku8>#W3teW7gHgqqJ)}BSuTkicWx2_}`j@A@^cP^Kdy3a^F z;XeX5T?5+wXRSneTa?&UjT>nhJfRn|D#jwMP)W%C_>st9+nF0q4&9N4YT`M@ zA<3Sh(y@9T~C~I9By)+b~A_r~ZdzsSFy<^|&4d4W|*> zcx7lH;vFZaNCy5^Y>)Zb^R#VF8jlj=^vI+JV3Ge0w60XX5+6>PicIn3`_%Q z_w`KL$+Og4{`^!-6n`$su>x?c@h;9a`f|6I1O(se3uR%=1J|{Jl&($ z(<%j&?xN9!&*e8o9Q{f+^)SG;e{NN5CE8T}PPKWsBUKxvE9U}xGSiL|l~Z=I6g(~I zA927#eGQ;(>9YzC6j;t%Udk3&&J_S{eX6a}MA~i#S`ycQG8`cvw)F~ODDiqSlGe`J zMtyH7;FqZ-Xfbj^)Je|oX&j)it?;Xr1Hjwf7G_EH5 za^*XV?P8LKGi}v&F%xX($LcV|ugX;;LH%d|fheGG4nUM+h510wJMOcdMXMGW9XJ*S z_6fp10_;(w(@kU5I18?GFn?sl1qycP-L>9UJ&@y68?5wH25hjDcUrU`S0Rm2rX$1B z`=RdPsA8X1yk+-+ZwrGr4bB=>JbNdOq>d$p|MJke(;>DqVMjE(k%NAXfv-K&Q&olbtot zc?HvDOxJm-J6`vrey_-&#!9a`8-w~J2Gx#Vc8A^SvbYK0GeP)-fDb@cZW@iz!*#|* zD=v`g&>z%#gIGDg&3~xcD~N4(4aFmc+QJ_C%YgD<&X*bsz6pR2H!|SElX<-|Ea%(- zw=*s0Y<^9_6fk}SjGqiOiXd^ zTslyebJ|&5Fd1L>W6+i<0xDkZp6&+~*K|Z%#z|X(>7&2xZW<#kX&7b>gDvd#Fq9wV z-|^>O#kRTSb|9PtBRwzsH(`51F*@b${xfd>pjwJ-Kyl zw)xJ3_}?Htu0)%D8=Rab#4AA?*)6du$6(Zf3mU58OFBxyc37o}PacLTsM0=)6eN^+ z6a+Z;RmhcVRv!5L6wh42~eO+hK5gE=BJtEezvWBawH19^o&lKpV7^bjVCi zn+MpY3H^P|#4o>8qOCP5QwGT%WRa5s3#J&1yxGDi&;v#%3c*MqS8a@0cpPKW3S-hL zLGKKXNYqU`Aj*0o1sSyzb`@ef@&QR(-_0`j{yl?tkom{*=Ci(1*?n+Qe+T+&!h-rh9;slVQ5WQ zg5C$Mp$45*+n<^GvkJ=CH5*E;79d;+PfOapj%Sc2#(+WA_p?+=-bOD49}RHu{|O+S zDI5h-e#1^}4Sr98pB?+B8ww$S?XwB`GGTiY{lp}T>|0;LS8D0> zwBa$+`N3BuB;kNJ=d$yva~9+;9X;9O*?$_ zE34tpTOeRCIinzeRYjBz0mKDv!g2wr%@g$Ibj8Xo^p;3z_2vQnO|P~*M?VQIaHE~L zfV&F-RaswfmlHVORtYDtR-3?2Y4^bnAO|M=ZEj1C!<9;e!?E7w%3EA;mlHU{b|L^? zV3K%&(3H921-b;B-Bc|g_@B)M%8cal?N`|arwz{rm+rSTHk_Z=3y@ZPp6ibPBgfqE zso((>B;Dl!-OvgJ8U1}Gx1dBL>}ou+t|n0nw9dHL$2QnRd)=|j&C6Dhc-jNucBN+@sDV>f{l8h*5D{? zrsiO6T=dt!p5&Zvc+(%a39!^ZwHTVK@&}YjA6RIo)=*sPlRS++i?iDPmPD-ha$)&bZ4N&oyDAv~!XY_b)GNn2e+qomZMI9V^ zf2|{qn_*NY^TJXiM&oZM@O4iK0gQPQgG8AYi!`Kop)b9K@%Kzq@%ZIZU)LC30eWN5 z%`%R}{YZ!Y2ng~-{#$3_&q zPl2Zh%13hGsJ~MXI>F3`CQNYwd)kyd<@Msm8O8%&fzpY zny2tQaw)d&$IvNy7eMm&{6O+w9tM!yDnRmIhQ?4kw32pErfSMC9wo^@_hjchK7ED>#W7Ww~F)oR&FD7k!Da|6$6Q6 zniyv=TV=Re3oyci9ah|Ei(BCiJsLc4g9d@ef>N;qBb-Lo^8P1~n;Uw!1ptAn2h z3jBQ62CAojqd2Vm3$;~+icF+C3q0NfxE%}zpeLx?C(P~g5d;pnod6EwOSRWT;k&9` z&-;aSQW?dR!uN{Rdho0GuJcTgsdJWU|B2znAU47QMbGWEWW}~~XB;;Wtjpxwaw%gt z10>`NCR}7I-fPNMPgO+RFI%&P*0NGP_= zRq>*#MH!5wS7{_-8fo&@C+)O65%4IUi>q@JBzwwYJFTVW`p9D6u>`AN5L+nE+N<+1 zJa9q{i%Qm_i*nDf0jt;Pg7keuBY>T^AuDs6#RG`fXt)lb&&4`2cfsUXbKAZxQl#E68SB@ z7gZMEPjMHJ?~0ddMe z|MG38Ec$lKHyAB{sz_Uu$W!ZDo@KT?j2%)wU|6lD;5A=?qJLgufYu@3hBKC5gL(A( zVxWKNwl6jS^x=(&XJycTvPheq$WMZPe4_Yc9D>0PG2AmNe6w2d&8&BPv+MB9uKRtn z6Y$NpsQMDKvejinz2y1kE4DvOz<5ouOvPhh7-29hnvS`hSEPL?u?P3kK=Av6!{L)- z-%ormI9^D0Z1X!_nxfDRm;&^p&fP*sUUS3W+L?)o$X7r-5X3uzI9xEJH?xbhOkLJHhU>X2PV5)9Bk}eCYwSbMfK|J_1CV0`HNh44E70a z0$NMCwDK_lhFhURc}Gt%-v!Xslg~KhLWjG|H=V&_ZT!|7{?+mP*PM5mZz*adA4E3j zAln~y2hZ}Gax6{{hl`S0T*EbV}w(V zjy$9?5YFgVqb=J1d?i_cn zckau7$t9NOSmE84=a0fV%QFQTYT#jy}@6wx+3DrrM5({7gdo13i+)&`*Q=xyKB8OC;xSq?*(P5%mWe|SV7QgMbx1K7XMXT_HZ*H z_8^RI3_mC{O!wOv*sD4V_bJ-8(D^@2oK)`7ZmQe})Ebc$(>k`!-r=6VeH~DsIR?6X z@>#U+;s$Oj_U_V#|F(CyW!gL3`@h?}w477fW!Wd4YxDO)g+9ui#n=K;b{|^ewOy!! z2sBdL^JJ82(yJUiT$&MzX5f}z4w`timtq-_XlO)LIi})r6$guV^G}s*HMA3XcoH$^ zr?dsx`hqfTakhSpNjuxkjzxD2hrX*^cU!}&T7P2X7oj+6&T&?T@WVD@-HLg%;`(H2 z3;WncmhxTpk=o$#<9As{W4V0m%*XV=e8Exin=jGH?`se7>vAoTXFyr>rZIB4h+9D6 zEi#N*N4~c*k=od~JJf6U1U&<`Y=?`+I4RbJBR~(Omr@2GfiG*DRqaWR)t|J`SG)!h z+O$D?GLED4Cn?H-zmRf9_bL?TJcUBqHz>_cQ63tM%+#KKUi@fFVJhNve_(`lZv*uI ziZ(z^vui1B^%Q(>!ZhEc)%Z*zh`6>=q19m~Lc6cigA}3HDb(In=r!=XDijBKB!nV_ z`by{lz!tB=OOk!tly)YyzUn1fZAFQQQx5B3dwV^_3Sa1&gHO@wE}+{)#%u-Z84Xd) z7UEr6Ob<(1cz+PUjm-D83#yjF*1IX99xt(jfMB$Mru>q?MUyCk0&-6sEY3OZJW2mC zf&xy;Y34X1C?Ej`*3)Xg1eWY$Ul)+=BUD!d-+7YO(4UUJdJ448pR}qE;QBC?J)K@x zW&X8X!95P}kKzEg3Ez(r_QUP(gir14&ZFDcAbi2K~W#7H3!L#CdoePMUX6VbkS2T0bPrl znr2+aUguS5q0Gu4LG}+ek^OJ0(a%eToY3AJJwNn2)EN5`rCax049@BbC@hYpjWg9R z*i2AhgSZ&^u5nM@!0eAcWT# zY3HXJY3G;RPCLIVNn1;wAzUMq!?k;j;DAR6A@AYFHoyvO0_0~DT#&V6^+?Y7GhTmi zz{PTU6l#*zwi94*FOC4%JyyW(*C@$qJB!Tku~t0Pp4ZARL(=<)`yuX$IGpKJ ztTcHxPa61bS!bg{lOF!|jvMy7Iw(m&WlD4;MrQnk5z z8tLw1qsN9u-%fY0{i0w~ZXk-3&PJ+x=cdD3F>ImvqEaD-jRlLto5C!Xk;&6 z1(|lxQy*@nv5@K5%-(NG68r+6Do}^E&QffUTt?QjmY$1}s}y;6X(ke>(x%S5$)Y*n zRVF}K0A@c=gXu(E7v2PYa)JhRw!YolNRFN&3Fzmn*aBd`K9)yFVK|8slcI2+X}()) zL~Fl|7<{UK+TIjwGQD4$j8GL^A|^(7Ex^w|4~|@4SjKXDH30<@5WaAg20QIk8E3_# z9Kf6KBf!CxGzbwQk$v7nRDm!@T+0@Eq_yov787q)X;3V`t^H%-s7m0 z@9ySE+l_96@i{Pd#`WY)Q14C})Kwdy7?B#hfps3NYKh#h^y@&r5*{B=K`d*)WWh|P!2DwpvAIv8jwZ@hd| zjPw5Bfi%GGKLmC7&aJ-`x>qXkj*BotVzXGGAL<+ctsTb$_TMPi4)br7n+^38{AeiF zzmY!(V7`+ATu2|EN+ZS68VG%STmc0)O;B(xHQDp<(nu))Qpxx0BeBzQzZ_UrTd#9~ zAF!Y0r7S;SzuHxL+mC{FPB#1~Uo8AEJ>`a$B0I<)a;Odq{3Y$8wT3$b&mJzgeZ$Xs z7CF`d#TLtQiI$`~Pvuh(9N%Qq3qaGTpU3uFmTxVN7qfsx03rO8?pkqytmqo3+J4VM z7S4B72QL-0{SOvSqtk-6#|dE;5Aa&?4hFYDqz=v+H2Qk30QdU)TOA>7{t<1y z?h8}6OuJ|?TiV7%-fuOL_Z6jvu-MLxO{WR`qX!R?znn$E~LjR1&)8j&Pu5j4-x?G;dYYTBv2vq)R3{2nWEnT_IK<@iW=*Bb(`-~pgy}LAccQiG5gu-6g zlw-p44_^{^{(>m`ZFD}e^yN@SPPx;ae=X1N8KNiR85#n&Reutr(GOqe>9M>DWMM$Q3fTBSWhBK8OU+@1?QjqOe0v#R`eC_+04X2y zZ!t7Q4v-4(H4jC2ZGU8G^WlK-Hxx+UU~>#>yFb=8u5&&9#)=D6PtJCdt;LAkAN`Vm z?o*^5XV&V$4Uc*Z;Qev070*+#3BF$q@clZqHoyem&jR>{`#(YOUn7`sG$oG**fCZgA^`kJIITZnU=f1VxFr7QxPy`G$B&AC$3(?92P(d= zdIEs*VYgB7Lx74OBdB=VzxRiIt^@7^!tOxHi0lzyxX-=TYx8Y@Ca6^(qU5n&EiYD| zB>W`%fm`@VMU({osMx`q!4J&7kc{l*AD;fWZ1s{oNQpj*=Nf7Ehc!G@vh4jb6y7P< zLILuKd&M$vLTul0p)tQr^d1fQ+-lRy<6p7#8Pb~rXN3MZqGEH7eo2{Kwry|jro&qX zj12u05Gm!H=cbV zkxxMB?@BjO>u&x!Tb*ZPTh0a zizE$g;Ml>XUnDs7duSs(I;=&R{i|?^Hi}P&OnCojL###p)p=$j_yOYnN>cWU)|}_1 z0t2yLE{XOxN}~NXE(*#Sx!>zNXLudwqyU%Q3%^)<0eh?vZu-gsP=@O0&R?B(aDg_+ z!h<@=T2a9tr?LT_ZyNc3RRvixh%H!azU@B1Xo%(9^qz06Q9(u`Iw!Gq_(lu}IZ7BgQ z&%DctkSae?zB>SwR%8X&K2CsBH`Ui57tuO7l$Lw-U}^qo!_k^wy47Qha6cm?z?TOf zyvX3c2mDVP{JW}-Nc`Wy2ZTRw=&!$yz|Xkv5A1h;Zz{Tg7p8wV_RD&Udd;LrdNWWhF5|Mx4jZ?hQ5K9%4e*v zkxSoYVH7=6Qw6uQt&sacd#$aaeiVtHRd;?)3AdZx#p(QGxhHc>Bf3o>``>!vB@Q4~ zI|gS%X7nLo!+FMOGY%lXHftz77g-kv@Zau-84YmSZ=kO^4Fi2QZL!cvAifapRYldN6;<;9K&AV9Q06_427&$1j zg+?-kAW4fIyC8J)aIzys`@TKCM-`6Qz@c6W67c%KDEl4wKTPxka4czu0soIO;r~%a zUUu1VIpr+AZB{??(3_rhu&cIzgy%N!lz7+_#2c)bKKX<3t;SDU`sVc3mjo%Phuy%e zi139=5Zr--rQcH<3ir-T7vsD1R!apV0UOfDf=5%HojQJ0h-}r6{0Z87H5AVOzNx#0 zYz(DF*2V}#NOl>}{Z1b3NeM(iM)>L4f3)dw9D@zV7%RUVs67e1|C5Hld=5ze8~%+# zEd}1P?dIQ__12S0?NsiK&R_96#TLCvD^nRhR;6~4Dj;AtjUB>D?EK#3*g$hn5;97k zIZtAX5VUMJ(DOww)MORM`;uQUZ}_(X$>JBw8W^fqB@F|_SUQd?v023EMvz;n3$`T)S(|JELmu8o$n z+EVnR)PeoFN;r^ce}ta0*4~@*R8x`=U+{)qq|Dmb*bVIMEJt-i)BTgico7{yQNG_) zJ^?}}99{L4i&pLpLY;(A9|V+f30%LD*dBWNIV<-J)Y9AP>5@0xjvi9JvjQSt&)f;5 zL55fJEo2>{`CQ#@V5G4dILz1$%<=CArpaz#p1B)%nyezEkwP!r1uS{J8y@-uKBTvS zZ%j`+3N-%H+*;eOpQ>Ne9NIO9l)k1#R^AgxpKvCB0ttvghFB+c&#QOUL#sVNgg3bA zL$pA=7Nf;GIE+_Qn3X34(rWI`t1T;eh?;_o;BR$4H*8jD(J+}YN+8^s)IY>S0{&_p~VO~=vCh1b0f&*(!mNO^`sDJwlSas zv`9w}jWBArK*9y1K0`3-HT#oL5_MftovXyB1@GYDaiQD2{92q8SLU zz=h@7(%$-8{EX!N9-5t=eHArngcF>Ahr#JJBf`S-sz1WwK8dh+Ot{n!^U%Y>rD2%K z<(@F%5-MDtIm#QQEcRrYz&l3J)V_=~PQO`D;{E+k%UUnVZur{3QA@kEA}{uKsg1>! z*$jrZjrDd|Mtup(Sf}dGd$s2cv_&cq@*QLVzeQLE2GAdtu~yZ4V=j6-7_L9raaJO8 z(E)RzeWkTl^>tot9m=^PTEnHXQ!65;KUyPIkD*i~A{?RMlhxeH8Vl;*A!I|SV^EK0 zUG;5H^{yb_)nO!#3e|^iaHX z&{&`dYe6U=Iv9nWG;j#@k6%Z#Tb+Pq@M=F}#Q5L(eu>?%3e?s*g5-}?ptja*@II=wuV=WCx>@vfx!iP(`36~0CtAiGG(ulhyCp|=-)*8mdYscIgt zJw=iBSVWLuKfXE>5hQO%!R&C?m%jz`R_o~g;|jHP(ZhvLIeiTjdICv#=mVOja(!C( zjNKWCe_tM~pQmNo`5_kCg?Ps{w6MnF3~WO$C*%53?R@eEY#XA=oD}`O?zp9TwC8Z; zUP#0s7k~x#6yQ|;JLHG8l_hCEYn{~y>cR+P>JXu&DtdrZZHM10@Vgy#NY;~RiG_P} zjB3lw)Hd^n)YI;z!#Yd2t#1|~pf@auanu&4Z*fzmT%`tvA^Ocp)`I!@O^XVD@h&LX zTUd3d#2p8w?kq430@FTKmP0g89n8HWsCTmd2pE~%`&_pa;KmT{-LCG2?VF@=aWGQb zd<|Usc8m5dK0#@HTy0x79km)fy8v%;86h?m`Iic2=7Q@^kIA*z6KC+fc^-Txfp2r+ zn*qKLM9>4ty3OF555CQXZwB~2(5~)=ZDP94x!XmeG8QD_lCEt2&v#wZl3 z?JTxcDHL|yT7a8FxFtr#ys0SwI@_|A>TzVz;$&MEyRaLUP@sb~%}W|&BFG_Kdx(x0 z{jE<^js8xTi}kS-&N#0Wydu(h9j#hkzS^7`xRhvB2h2-nSrQQu6p^g=tCLJzT!D-2 z>Mq&_WYX;ZYTtRHEZcVXE6WGJq5EBX3}x9Qh5INQx$SxANm_!Tr;p@GNq#G#c`Utj#DH{&pxn2-M9Kgv|Bq`$%ZapOebmAwR`Wu|`Sa zNrcReDBqeRc?CBn?M?+8NAd~^9A|jN9Kdnp5DFkJG=#I;DFJ{!rad z$ha)?u%8X zN-o)Tft=2k^tRz-L2NzrxaD9qe9nW=%%q3yZ`u!0nmX8G3+x!c_eCH^XGVbj zr(!G{cne7ZWV>$NX)nM-L*zFeLJ9tl2gySetH(odmIQ%VRSkDZng zV6kK4^yl3)%lbCD^fb_YlD`nrbtv~_?%z2TIr&FQj$-=(tLd}0j|*q+rn zHNWZM+%kQwa>6_4FftTt&!QeuG_@_W_l@DWG0hTXsP-gn zH-Cf`gs$5U-D-4+qs+4g+P05QS)byJb?BGHWi)2IJ1r)HzKbRM#Thu-v&Z95<#} zY)b+@4&xX zgLpy|r4Q1_8|>=|`{vJ36Jb9ZT$)8wvo!qygMB{OHv#+GH-_T|*q6WYi5{X}(0-t4 zR@=nD+WNz^pZX%vM5g{DKjUjNval9HlhJwd~()P#E_K;`_Nz>b#WBT7WhT{f0wL3_gjhxT=1hQ%q zL|;y@*uD&`#-^&TKHV_XrNtK1Y?Z`^Opl^R2kEG}G5HkFJgmJAd8>fi;G8DIUxuOg zmd9Z5G4uPgF!XCN^f`w$8pN4V^vodrD`V*IlcE1BfI7<1Pe5bBqA3gmQrAk{u-v&Z z95>L)Hv(vDwCu05!ri+WpI@j$w}FCP`>KNXMo=(}!GiB{jnA*{7f8W&Wu?TenCl>S zZOIdcSPZI;`wgwzyBw|i60LjTu(n|kzZ^xg2I=oe>u#cP(6E>$>)q3&B}J>YC1G(- zScXjK75#8%^dFPTi$i{kf5O@~rHkbF{bdBAle4!;baK|PlQYYH*j=#k=+>lcGqeQD zh#PKCId{(RiO1%i&X*Q0 zLTY=bL4FBsYers&t3cTKX7SVz!adhIxl2*lmC+!@+C^IXcnQ{tO@90 zz7Ws}=<+Krx)&=^+p556eqKpN=2l+jrGi?k6y1*%f1%14z!X|91vnZ|anJV77>h|@B z;}syAo-8nb?ioQnll2Uc<^MRoIz?LX*L% zU6}EcmRgW*axz~~DMkC%srxwJr%2k8i>O_95)pG#ewreE-0PmJA4Y)4Jg^!MBX0A} zD}3ffJ5P0MbK<}iJNsbO6{B`zp5GU?8QsfQ!{j#EZo&(ENG!TM5N1BG6#G{@rs$!- zvwjIYYqf;s;}i!)zoDw{%d7Ki;f}hdODlG}pOIEvDg0I3+DRf%qaaYD44r(jP`d${ zx?!QK6ot`fUuD63egY3SgXbCJ0O`%*wt5Q%mvE~AzvRaEzc`cB*flv{+pLHKxzlhU zJ7FxnnT5~Hv$NOjv&2CvkP|hT?z3};hZJO2rI#Jr8HM{k7rF&i0l%UL3inh6XSJuM zLnw6K7EyBFaN7&i1WN9@C;(hQqrbW7`PwK2S_=axt!r0RZZDjJ5q#B+GVc5WHvo0f zYTOo&?aa~|^-<%-NuGtiMxKQ-H_ubJ;iS-?p~P}>wjM@o+@93(+1~H>6nuNs*GoBX z=ARy&f7%d}JPqA6B%_00GMY>$zx#)#HmYb z(V*d?sJVSKwKvqX6?Ox9`5N>x^h}wn6mVuyG*>gvDq0YbwaAGcPxU$8%E{bCZ3E;t zRF73u4{q@SsGjyiti2HjQm1;TGxSbio!;5x+MEBX6N(4=7x3%NS$Aok6k4O!h(@Ib z*y9?xfm6Dfnh3J_1wMN=aA$6C1yVaQlRMo}L}42)U=}-iw0~La*2g!lth`s9cNWOS z^S_G5{jUXbtfPN{Xi>CWMLL!CU_OIWdfc^G;FNQFZg5uC$^;HK)=I~-;1}jL0$hQ0{ZY(W-^a67dCDca+7(O zG`Fu|9CzhF*i^vEIRYztQ25U{~5l=uRb;Mi9mmiX)NXdadraQ9Z_DW9LJ@n)(uSB_y zsF>~l>N{ty=P{_iveC6W?=>eDG`fy$VTWj~K;-57}N z2`-8>G9@Ex(9+VSB@`j$W2eFXF$~~Hy9WX64(@^s+WHo45Twsmnn7*a^W(}j!ivIU-H@}Zns!oILMJ)F<2F|?JIeul974swn=DW0 zgi8rrW<0zz9HAxm3U=##Fwb}!p9qlke$s$Py;Q$=@yBR_w8d78g8&n|jXJn=N?@{W zxB(Ie@x11?lFi(P8lVB-{<~yy2e9$@45~`N#_*%a)QDe?V%cw+k-(RSNZs_~n-eT} z%e*xMVcJ#n3pcuztKg*gKvB+N=jm08a?fUupopfV7LRe0rTC4NZ+PD4=6kZM>urG*HyLM+(=fIE94G()TId6L3EP`}A zT5P*q1d#bPKgj&FoYP;YW3d(v&_d9X(bT#lw?+=D<{Vl{p>U1bQFlQ3DrpCuNa$?E z6Wkj7M_*24*I@Zcu7u7UdO3klSmogz9U&$A1SLK^*Xg{t@(outMy0Qe%IH#RST`yS zN*|U{F%aWzW53^jz`Kpw0xU5rW26Zjf6oApkM7XX4;-(&%0YVo9H&67tvO=h7_n*@ zu^Jh%_3A~8*eM7yhKyw#J71|AG2@Y9+!*B-=u^g(on4KlUN5APE((S$XEZ%sSX1!o zXZu&aQBYHOzSMTPT+7yy;7$kEz*Z&|Qick>5thaGW8BAO(fvd8mhh(ahAtHxy9VGn z=-&WipH+Sv&pi=9_a__Axn`=i#bL4B#j><#uXkewQbK9;%<}JODp1ami@Lwr1Mpop zPE~KUDE+5}Rg}nBIr&^GrE&=wfZJT3f)W)!A4^Yf3`EP_2F$twSCXg$Zce#%MCvoA z-V%*yeYj&M zvOWxb_z+pMu2ix$iys1jX9};-B19F`!~AIVs9xRwZ8t}Ijd%{EOi8ff!S*88H>X@n z;0yS1DdH?Hs3ltideB{CcR zhxd4CkB0qUYK@JHa%T-BCeE*Z7mK=S;KfS6xxqJ1+ql4918zSldb*IuMf|k>q-evq z>#ZyW$yBs}Hh_}h{ClRCw(>f_EYn@I(OKckRuEHD{I2&kA&b;0p!N3+8f90E5#lSlH0Fe7i@27{h6QZElgY8c{hyQw5gokwymWNQ@)^x_F>AbRoE zX5U!ZoC&`$#9j>aTtaUSujt47=}(KEmZNgm1t>=Ujj)OY;|AIvDv*KN3_^I?7dRVF z#M$^119@>$`RV%sz69?$=~ht3cG9cn zo3AJEdEl$`beD{rl8J|Y^*@AP#zU)@`yZk;`UKT>GDClaI%|)JClqVI2|MyS{+Fm& zURMdX$L&1oyisQ<7Xb+QmNB@#Of+LNsWMCW8#{Byd4um&1+d39pHq`M*yF?0#(+J> z0QPw3a)|yA&5g2SGY4!ul?LuHn}%nXx=y%|G2)J%^ZK%u$o&UOw^6vE_XLlTiLA{4QN%Cq_;3$kfUIN8HMG0(Y^U8E_i<<`I`f+ADnP8F ztwhdudzY6SE?Mr~?Z%phpwEDyx1cuVa3L}v<{v@Kn;T*-qlri4rYMCH+>XcXIODc9 zq66eSMN|Y$;A}5t(_-_ViGDnk$93#Z_rCP3f;#xf^ObZ@&;Fm?n-~Ud{EE6_#-!Uw zlrw@vIo0F_XWoTGLC*z=QrB}?7HtA(JlDrYS(B7!rcN}FD5Fgz${rw5!ov1V-6=?v z`qsufUC0O|P;}F~DiYtS0a<)VRy~#uXk*34YY%t@KNm>tITlJ1OSgsprUN%4{5K;#~Lzm=^LD0tU>W-3d|Llh3+jeR$x-y3e57az${}025<&1ki`1F`Y!!PNq&Cn z)&L1T!@4`+JeqS+)}5LSD66isnt+g<)BX71?NxUXtImHT>~w;0!*(r< zN9(=BhnZ@^Q2GIsVXU&#t}!*F5&#!H zB$ML4C z1|Hu6RX=xH>a^&v7@n;wZ>ezA%51>GNd4%zxKn(%R zC|`ku;GZI7+-kFDp|L%axpg?fXC9Bnwlx}CiMwd5+=-ypR@|vVvmuM;oz$sLdX|>0 zFFcI_@a^hpkE^x1E&K*eGrzzK@tC)^(KPStfc!p$2P@g+1X8eijeJ6oNl zo8OhaVa})QesY#?dQZE)&#mpV%3vMPk341PMzSH*NNbA>q8Kt`+sfFoGPbf><2hqH zE7TU3sdtmCn$kuO9W;`6meWn& zLbxb>EF9gQlUPj+{WG;{cPRz_L@k1M@co|fi;w;rL8wi0+fy_}hS&UI${9ho%Ey7_ENr)C9{f-C>#>S_i(GnLwBUs{8ZxEel7T??#2DDP7Bf- zaC~i$Vmt4fNY$zhvEh^%3seq9)OOxT!3hc3YLI)wLkYK2ZyweTY4}V$#p=#TYJl=r zS7N(aIXH?NajS8{dr|pySB8ul=xEwG}x=Bl%{J z@X4XO(oSs2+P}FVc+-%qk;QW)`R38^pC39`5n?-h1l0xoc|jqChi=8f1ZmUJqA}ig z&_x7zp4X0QK_JI1e~%;!-5){?W4QsHQEGyJ?pB;sH7&??oYT}Dqwdfx|Ke=^Q$?JzX0?J_stCH=fFq$0MLl|y=?pASAB z`peLpKY6@A-Z1)kWk!(gI)B3PNX_Ze^SHoF%?T3EY3Gd+=@cX0BX32EUwT)ARblL43@PGFxz!V)KM$pV?cS0fuLu7eSv0tEW{~Y4 z{*r&?wFa`)m0>5(~s0O{Cya_SBpU2Rta|Piw%hz593X`z7=$I3gWl zAs`r!*tzAdK2#qdg+s9et=ww4l3_RVZOZ3>Kj-G`EGu$u%4g6rdJW`x4?YS!S_3oX zrW+|Y$Hf9qN7G-nr{s)4A^*}`gQHffAj#&=a&#^OQN$CtugNgZ>B(;j_nC9z4=~lH8ynT(3%}??~m2NKX*Sd;0lD}8n5NfccsR}`~K9J z*QKmKesi!)-v&q^u7Rf%QXfW1#&8bzdPD;ODoQ_`KHVsc8tkEIBeih}EweIWo_S zv};>kP3fzWL@&MLetpgB#*+R9vd|NZc7YKV^jR1F93t` z%^_@h)3Zj7(HCG+R@!BQ^6@T6Ls1yYXwqKK;6~b=yqjn4=dZFxG_H{ zGg$qzIfFfl`d^+NWb+N<%17;vA9Hd&KT@zH@Eo4zm?jB4KQ|J1W`wt;hI%ulnj0RF z)SZ{j%$=_onrld&Df&35*p08-33ZPA-8kXj7O z&F!9&AFGTtDeK<{ON#)^r?d5^OSPACpan=P&C%b-nw+oQ0&vU7*f|p!JGIuxRPj~` zJzY%q6gQw_z8BPZ?q}g1z`1jifuVn=RqS?FZKX!RTf=gClt1<-l>a@>Wa>&0A;#`I z*YZ91)~`KUti{tk`b^2)8SA87nAkT#)}I2iT6OJa}tjPHHLE-G|(dHYi$!nZFZ>JJuCbCRzBc5))&r&2{+}D43aA?G+?7 zyinqciRTS?ba_H;qhf&h=^;s!XZyV6f> z&pWZ@RPfe>gG0+_2BF@5Pra#n-pmd))Y{#yeH@KIm8bp5p=hg1`v%(y+Iw0TY>IKv zuPLBMN<1sph`}7BuUEF~U6olunB!jDd#_@o<(!hBvH z8gcv19QnLJ&O)?v2;oeoR`a&z!FFnh6WwU=ol`>n%(R+E!FD6qE-cZ$j^`J^cB*s| zY_EXp-J>#ygE;8X(4E67e#$$(wJdmRzno#hc^kbI>rb)C9c26Rkvvo-)xJV*L(pCW z+V7TVf5r0>&_>oy4EkQ9WMT9VIXUo^LIC2Ok(MTjGbN?d=LPiG9T#Z6tqLyCYo-en z)1Lct^OVqkr(T5%)DX3a;Q}>rx4r!6U(S|n%Z{MF)F%XXfAc6LcZAR$KhOQhOu)sg{Iu8c9NV(KpHblVFt@?BJ$e#m8R`P&^oq(1x*F*U{gs;~mC|4%>U zns&532y+W^!~&~NGhkk*1-Mk3Suss7;T8K;=WRCujCh8}VTWEChZ^JDVn^>9x)*kP zkl`ydG<=0r3i!zj|4Z~za^;L5hy9MPpeNn!EUdL_w|vc2rxlO1KzsG+UTVA+8zfGP zT)FB$K$i;YL9RL*TbGmbp8)N!tg4#M`CI3yUWtnh^6f>mR8IBZ&M2rep`#= z`>9$(3_7l1)SJiZUwWhMxGc#!&1*quO`YkD0|3TlTHiYj@&=eDxD+1rZ!lvRn3J(l zFk`U6Jz#^U`)#l%2}T&;B-0B2nIzc(B~_?!_X?+b4O`qqE`z&yEf97&0Q!FCG~Jdq zYH9Hs$^He@_-;EnouBYx?Ee>r@(KI@(oohQ=`;NYGKwiy$u28lrX5#F#i$t98e^Gl zbkU&yzt*fn2>pfdBN{~a@F1)9LLe`JU3(^>_E<6P#kH%jYglbHPU`9u>vPlhwB}K{ zD_f|mmFEVMg`Y7DQ4+57yvq<())}H^@!SlCsCes{+lJ`o|1?BVdDx7BE$U?VJ?(oy z<$54h&&vIU_`N0CbI`?Xskv>HY~W?xnR-pkQa5YcyUo%`F-yZ>mOA~HS!(;=W+`0? zfxt4s{=qVdr4!3k<=4UO@3u_c?P8hgG8E#4ljM>l(qXhhr659^taK=lTcOqWCg|8f zR&g!duv?~*9tiM~6M8xg{nJS0d*w+hr%V5O7%ICxt~6r{i2uK+Z0%7@@^&v>LP4|! z(ABY`s~v`}9vb@B&?-|`2SZmk^@d%0^bgE&^BnnHjSitp^oGj&cuERQ(Z80ksK!Wc zLd77s*-JM{8)(P0uqW+MB38N|iwINuU>}US$Z%@)FVNA|!9R5?O1d&Nh%a(?$+EJ% z6u7c0l4a$D%IW+_3O&N#mTDV8Im1cEuu3<3zD8d5Qd^OBMEk!u`|tRsjwWmXr5MSa z5Qm_gfCZ9G@8E9Bo$lV~z4s1*^n`R;0_m0BO|!xD4(^uZLUWPiO7C@!-aYnvpFOe( z@ArN8k9&Xo60mIV%+Aj4&dkm{(_Pd^u%YWWX<#4N<=i7y#($AkTAK3j9ngruu|?Jh z`^!oehMJ=4NRcKXY>%%Ft7wvB5?Q2!-cFme5%k8H$*9o#gSW>3#VhvFlqcGxp99#y zx^HnvGXuN`_>dlOvRWwg;VU=zkS`9GmT-^Uqm-Xe^4qKjr$3+JYP`+PsHF3Mih+@; zUc-8~pQ1kzdwuV@jGYB!;coCQ90zl)A6V&$O>-MGdxhOvALw;c%p^BK4(fYLDX3hts%|`~^!xSN<5d!X~ns`Pj=X^xPIu zsdHI<|AHdXXv7%G9NvFFhgZCUJrXHO`qm^DGqZF@ zfey|=9W8f5=2;XX-2Vj;1|m}fm>-CMe}1_j#Na`Vskzn`h`|55^>-Y&KV&IMeGIXc z48#=&clb;B4FyDat^#XlcVGxFt;Z0~dz@8?wmu3)|I+=Ize+D$rZ%?zSKwMg`C{Rj zR=~*biv%gA3wW%DrRENeL9;T0Lt{R(Niz_2%ZoPN&0dmoJeLmD^Ydrvg=_S#E&Q5hK>_%Q z5j6`7aI5rHd@*aFLCxBDF=wV7r$2^69SZZ5^V8qK&mIxKMbl`C0)T8_=z@!?kT;BL z|F*e-GnOi7CKN~u*Aj3e7gT&D{rE3GYWya6QttUA6I}*7)5|{N3xWXPb8zCVtTViy z#yrXs*h~6HC@XO+?tq7iNwbQ1aPZ?KIjG)yE~9GzKbBTXnIaqLptHj!{egMcLqE_d zdj{`TbA?;dSDC1cE@&TeEqcd`2~5i)0?!YXm8Cx73*7$^yyt-o0jiP)7|N3h3MKnN z;0eoN4kABVd9Jclz)uy+vvM+^4s#5R6Rp7S$L%&Mf^P~f8(4qPxHt&vl!Iopa#@yI zQ=Tf;3O3>&14aKOxByruG(tjQM-;Dud#m8$Bi9R^$t40+aP`-ChdVg4T%v@0W931%Rv)#m?u}S`+l!OP=2(>XLFYK=>o@x^|`G3HpVn}I&iN+0G7R~VcAd1`}R421OHYKhEKq*ykV#o}?`T^dX8 znB+&1^bS607in+WK_?9Y&96(VX<2CT^AenSm+i|Pc0-?j%$L12Kz}x_=AsdH!yB%9 zS>vo;6(dg~upwNIfZ@tD!22;_#AWa9jajmC~2RcO8!K zc{(ZD9yd02; zWri@_+2|LrMA`(iHfr}F>@C3k=}*LzAIT}%TkV=0lo4T>?yR}VI3C0rGQ!nxpXlQ1n6^B7G zd+rO63x|t+%CXXYZEN^~6mzU$;&S5SuMcIh_T9p%sApK`=E3MZ-}zsz59NSszRnR= zaDDql5JOe)MP;-Fc>XQ^^v_SZ>s(|%Tla(Dko)RT7K!mrKnnkk2OdW#<3S1)e7q<= zUM78yQlsR+X>zcDa;*~Kz{P@HSCYfCV`}CdMp!J9H9H)Eq+7*G%cTr{;aZX)BFrMx zf(^(OOFqkIvYXH3HO=h{&BcuB*P#<;q%3$eH1}F^1&q)PWkxUZ*n=E_V`(R#Xic41 zw*u*RkC{4?#iDw)CZ9a=6^rh!jazh|!lLt0u^|2c@opry=q@S`5U#F=na0K%Jsx@5 z0jfAn;#*ZtDjHE~=u*e9CRKY0W_m_Cqhu)$#ke31SV(mTIJ4`#0U!_M&D^sYE z>!GgK1Mg39hLQFe+gW?qfw_zn_NrVOZM zVc&6U=nlVD-uA>UbRC1nV$V`7R>zA=I9^-=bud&KEBMPZ^QP|@GCjeaV6vT%gE@s zk_*CgY+xiV(?)Dy1pex8leY1!T&43hEZN8WX0|rMnspViOId5In;ORBv%rpu@%1Lt zzKWY*PQ9*&!Dgl*tQubR3fbeOTz{j`i!p*U-l*t;VK> z(d_iU7xgGy)G$$7IM&+CMx1(fzE5EEC^UL}zT-HmKlJ)KUvUb5`JDM)Z2!NOg!Ta)p=KYn;Y#Na4WHPBlX84pB^o-rgHMvLhiwKwh%HFgQmzq zLR#a*v$F(qSuiK}yvdKC_N?tC@6k?(cGgw=t{4(}c`DHBrG?ZWR z9e>|UTFm;3(ib#CxpMDQf#RwURxywM%tyI$mEbKKr6KU z8FOdb9o2#o@rV1{*;XSE2`st%0*xufAd^FtTL)N;_Or}@ll*6#r{h9BRT}*6J24!@ z5#Z>Kuc94asiK0$=}yGFe5QRG+#Q!Tzfys=ITp0Kkz3ajM z9mU(QK^oD$A&qmfk976X0oEvj+YpKH2Fug3OOtC{lMU&EAPX}?hc$aRYa4JdJKJ{P zhK|=-V2n79qp!zz=vPHO61vzc1yW}`X}AlHnp;VpmFS9%?gx^H`dH?aH#D z9jwN69t!KvbD@4eYEyQT`|S*R$2Eh!L+$&JZh^CAGdsnminPGM7O=XyE&>W*dHVIF zR+3M7fC4FLv|p08;|-YkY+-%-3AG~26{UmheJh-gV%7l@*vNEpBR-0s zsS=}%Yemm3AMtS#EVzp=N;^eOF7w&U`aC3|?oEN$3U*^Y%avxhTc}Opr6;cGC?g+) zX1LC^?bsz$The^$Eod^g;+D|tBv%m0WUjJRPyllxX#q#rq(Pto-~Ft#lDo~G+gWcc z*xQ`K+c35oGoK~;eNnu;TfBY|`|y%GiDA@sv9o-T@w@XEsm?6#LvJGbgRl;1)C**; zFr?7dJ_Nu@RhBL1DriMs>)=?LPlGYKEjAKW6w)zbl$L zY$R>YrF*XFJ;^neI(*fb9~V-$Ld}ss>={xzTH{2pfQ_to73lBxpRLeGVekj~T`|;N zq5r@&y*sDx4*F&p5t3zp%tniyKd3;!AoP-@0fDpI-=q^Yhr4kO@D+2eeJ&^{f;T{X zQmy9En)P5C-u7nZy@h%76IcqH zs{mOEOz+A3-{X~BP(hcx^GZKvmuS*0Q!2T(GW`v>Oq%tpxtb?XI}ljU+F?dY8u&Gk z7{j5fC`#EcHbp+$;{|AP=X&|DQhC0}IvDn4@=Wj!N?u?Ba*8|DXM(GTb?r*(VRd7K zi;o^L^+h(!O>-}e+VlCeQRdSIY~niL?9c&c zMF-yJ(t{4T=GN-~WcdLWi|gPoS@JI>fQytFyK8sKkq>cPmA|DxECdN$37G&Lq~--Q zrl1w2@Tr|t;K_@n8cA{9v}vAC5s}OFk5N4TMy%}wZqKAxuBARi)Y>xWDPHETu$W)5 zzlNy*>AYs3k`vyCX0ACv!vN_Vwj$`8z?H7jU-T#6wH+k20l-Vr1nff&QBECE2tpm< zejK(zRZc4}HTNahk^CZSv)#Y&sWu}ZQQghYhlz9aDKSrXm1d`uxgH8D9sTS*=M2o{ zzJeG2tutN)SW7^q2eL|G{a%W3lSi;5K!Z2{pDl3u>=UKN+}vzU-y7t7EB%DesI`)= z_B)9H`HHk|`?z4hvAU*)mJENk#5v0o zs{=N^1#CIBGO%|Qtnz^h{IoaCSht6w-4Ka+#u`CR>tCUy|18ouLv4tHlKzB)q(|pg zWM9w8H`2QhNT}stJu|idn!{!R-wSfd7TtBsbyq;)OYOmcnd@iuePPMG7KnC z(j+x>Fkkk0K#2%S3I!o}cyTD_OCr);^rM<05~R+U{q1 zq)4kLn0t3Vn0vmnG%KaV^-%w^G0&Dcr~5qD)nmNVTLz}#YX)HVUm`iY{Y)%ftQ+%G z;@m+8GPBC||E(*V9iI?1i)nvAXLdSDrNHS>7Vvv@R~?rdX#m9n%jsKdPzfzjfZ8q6 zIw^`TwkmD#-G|x|Lx`F+>ED?Nlk{oPw^Pi8dn;Y{h33RoLV+!;C5PEqoKe(?TtklcRM``tt~2+JgAX8v4oc?LVLF5E9UA9>)48* zQkq`^%=Tx1Y@Z^&WLHY;!6EE~JM9jsZCQd|`Xq^(d+iTKl$C2w`;Afe9_-1Sr|A#J z-ri@*+f(YAJR~cre4+Cp#Px2C_%i;xI0)&@U??`{ZCKmiz*}>Q`(YP#0j4;chc%?( z2KI-&DNL*Env9a{JR`luqlA_*<=|y$@e^xE3G5)d6OyW4u-PTjst~rgJ!~#{NihJg zX$42mW{q}7T&vP1`_EJN8RWxMv-GL4x06jddrH7i&WOsz&WCXx*f$UVD)ze=a0Kt) zNxiZkII72$Pk^+#xq%K_B)=`zV7rf&AI2&6)<5VpiVXV}!Q6fFGID4!@Heq+DwoxQ zlILaM&mN9Mh!hdFko&%fQkx-j2P!z!-ADjG}dE+On^1$h5}vWhU4ZnobWalK4?%5SXN zbC4fX%>;Ps?PPN{=QSdGWcecJR6jUrSjBJoD!viS-U6!w)(lrzRZ;x+$&eX+Bmlnd z{2kZxy9bZZ@C0~@KlxVJkt)E4O@iQT8l{NU*aT z#kLoN-c$9T9N;%bugOD)fby%_t-p;iYdqc`egZYHkBku<@&nUgBC z!d=`|H(03kv7($rQuC|ioqc|`huX9LqtqS!d$V_E=u@Mg?xvycw(nN{^9HRro|7Nx&&xH8Hn6jM?(m`eX zseG4w0dXB#$bS}A zPO`7nA%@QW4l%^M*j;K=#88~{6kUi*He%~0ti`KyO>Xn|pT;n3i6I}+@(%2MN z*2Gf`n5SY+{5`@Ch9n{wo9WHm3%6Y_^r1In(8g^Kk6>WmR+5tzb#IMnrzNA(h|oz9 z&p`0r!NRE(b#XXsU0674g-8f@*xYwghZ`Bx(lryOaR)DQTj5mkv zdI)S?=h}B!3HR%e2YQr)+kDF%uCw%p;VYnuu<`1D|NR~aa=QqYXae`XQWTOPcwYJm zv)RUaKPMONd%3V)9heW&oD|pV-7A-#yQX)fcl%M>CC+jxTLr!P$Ov))nhU4k z0&4&M`@MP>tSskhvW`0Q^7Wg+q6aK~y)3-6}6T|{P*6)m=4jZUl zdirhGj6T#hiQ0eYEMJmCx%)LialeA<-7l$^6wcc{KQrvmbp+{#e`21k>hVyipY9dm zV`TscfNWD=$(B#mne};1vTXo*!zHU#BrBg`h5yq0&+`naACR3H0sF{NCp+l=N`88YU3IC%_IN z&%=K)&s)>`a9?S6H20O>%DtfYN^iyBhju%zCS4UZN8E>SVt$}F633YUnZEV~=LS_* z5jj_&u+iLeI^s}S-f}M;#yuRt|K+M)tO}M86t-IfR~Gq0cvbb4n((UXD>XaRS8A$w zrKV~)@jt2ysMJ)QN9{UAle;)r@wB~l%o)7B_QlfLCjudZSMsqMDmCZrCTSV>82z^~ z{wnvj_KfdnI6I7cJN`@c`y$DG8?`OIM2!(qX@q9p4CO;#lGgKb0FQ0V>m?TBnEymILSUZlnYWT~ zsK?;fFFsei_b_S)@BJA28awefdt;@>GLByO=s>DDi?mWCu~2@4_})-)d+eUwnXiJn+a702;Uz_ZTnCb#^WV1aj-ZjG#*o|wcEavtk`Ixu z(u89*?{|}B&8?~HBTx(%&|sA6U}u{}4P*Y;0$&T%7Q6XF=gaJEK1{9D*o$q7k#-pB z#tJn&oWlMD9(LVPK{2%vs)*qiZfqF>wVBc(e(88`;+#4)aO&aMt5Hg9!9G;zB+uu# z*Z~|DdjK!idkIdPfYVcwM5iEUzz)VLjey2bTqKvag(5kt11-Gib{4!FjcEm^;(Z@+ z&%^#x)vOuwg6b+8sy(O_@CZgXavcm9ENA8P1y!=2bC(#NlJc?gcn)O}KdL-eo)Jy^B9+rE@ ztVB4X74-!&H^d4Bc&Ui>AvtmNRW%4TQW0v=rAPJ4@3!2zz5K2i7ch$fOeWw!c8-k$ zPPp4<$MV|9AGx^yBQ@%+;!QG!_R@AH=Oh|R!$_U}r9W@Hwaw(ecARhE6 zu;)kxyn@F6ALeO&sl?sfnWupTe5BurK-)j0%f`8X2@%dX>hO{COu31etA=&?+ciTt z`z?lkR(*))rX<$=v+aOxb^nvzK7FC=LJ++@hTJ~g0UNc)AFNIKhc;(M5V165zC-k%(0xn!nTX8*=rN%wj-|T@BU$IHQWIIAG zXds~C-D`qPPcYJ6^yUaCPq!#SO;v=t`G0iPvuFLTf>_%^SJ_AMT;8}N*wMHn7?dEt z#+@C_JAz*|?+8|!cRa!2(>d=lOzkt)z;Y_Z0RcnoXMXm$?)9#Cti9krT;0jLH*Dkx22C?G_hCVQ&okm1?TxhD(4Gz+qwYBvzRe6E zFxBkI%ieR{b#FxGaN8p13!}wl45%Zkm`htUG|}8YYh3$7z8lLZp&WHSZ=>;t^Eq$c zMgvI>g?MBM*;rRBAhG#L7Oz-ZT@qSK-xgcABmM$`gBM~vc_b7|1)=h2^*~yLa9oFN zk$E<4YVa(z&k$rvF3=y0ySX#(d~$*7p4hDM74Pvk`+01)SVCT^!XFEN&iVD5%r+mg z4s86_Oyu48E*QUGSKt=UHi=RS8;dxfl{RwFlr(z_QNC3o-BRKd-(??zHcqonDh)e4 zwS>Mdt|-wwSz$ko2FA7F=qJ~nhKO7Q2 zFy`ZL?lxxZDRNDY$r@F@#94D=1)I$fE2~~nlBmmHm;ZCNqe}DhDAGu&& z`$Lf%=pAOy9evR3&3VwG^wQPLvh*E5vY%8oy(FXzqO$VWpr@Pdr&)j?w|^!kk>`|R zX-%lyUEQCi!ztL@W%H2q%i8@xbJW3uhp@&=^!pQTZZn?SZFJp}ls%~&MbEQyU<#ag!gHMZG#tYM*>=K1DSd5BmlZKg!|8G6G!KQC?Vhid9k z_O}qQFj6}sQkmki_ZvBTGfG1EO4@kH!m?TFPBO&hKekvpA1V*UQhq3E`ZemXH8Q7E zyFYl2+HXidzLu#8H+SS+*n_o9$evKX+*#A35m?(Nmdw!QQ;c9z_(%^=K?hVRfwhwp zR6$W9Dj225v{8P{k+}aW%Ecv8F%m|zDKOiby${?ZR4gnFE2VF+hT#?bo#M0y+E72l zDt09uXKTE|)^M!nj*I&FNglVzS2Au!_HggRO&N zX^gG_Y~^vb=rOMJf2xo9BHrBVD`3gL|}H7Qps)~>5@W5rgosL=@K*Ydy6PUa`xPNt)Y+Gn*Q zV}-w!VD=VEl5~^@uQhwT%kF4T_>EV0@r4sQTYoU-QcwxTE(J|1L`!pRz4VF~LT;X!F zM)qyBfdUJoH9XjWqxM?0Hra2Ux;Kv6cjw_CdAY-yb+8n{SIaOQwJcrUi1^%(G!?N^ z86eiSb(KF`|M)HgC+(z{59|3 zgXgHSebkP0Wq6JXn!|K>aPCF5e+$f29lT`Hgjk?-I1QzE{BhzCMNSu4{H%GazFVMo zq3;mH_}zM~@;ZVTdD0R%ZQGbHd?bzbtnVm?kJOm?FVXLfpbpzfTXKn-xTdql)Hayh zmpESo^2~(@n!>kiF@2%@#T)fdHxsHM8`B0$QMu8&A7f`AG|jxWax+u$k`yn)2l(Rx ze_MlV#1^w(MYf1sXpxG}zH6#I7fG|23v-Ed#4?UBXL3QGwY(cy)|@-=G4@#t%FWi@ z=(n^2W@M4b0{&qhl`oa(fjjf^W&Vm0*%85m?DV^?mwHj#IO_PJGZ6olu>~M?hZd2K z&QyColIHYg&ar5M09Qobik;w+C!f6mhh!3mVr_CqNzL^$Qge{qZMj;0)v~)x^8%*( z5m7PRA1J;(_Y``*X0{hPJO!=8Z2vEt&HML!Le1$D{zlh?-RG`~A9q!v6u26i&YI&p zkoO5mq7y0&vBtx6D51jJ&?nqk`ONyb{IOMYS`j9H{`7>)=`b&wb8&hv;|{(1mVcej z0g7Y~u|=Z)0z|Z#4lmm8fj{MiH0$Dh*9&+dO@Q;r1JZ$8S=&l#!TYHU7V%Q8#s&z4 z=W?0?>Co$6M0C*gn>U>|61tSyO+Q(00N!j=(}q=xa1EM}?Ni>-^mmF9S&w1mFUsQE)Hg4=$;Pa1>js zH2)p4cpAD;+1Chq&BKi8$0C5b(njraBEK;bDVo~Ns03r4dsrxTMsG(*t~U!|ZJFmh zeaaAOyO-SWrBiEYGdzc$)NY=0?R!Yz{aK(MXt~!I9vVeKaW6_6AnUEH?_+wCFLDdk zr!(_@PeGaAN^LG*RNl{958xhnt%has(AzRA9Yg5N6W#dw^V?((wt}aX2AA{Uz7tvB z?aWIlLr{Er7v=$P+FQwN&~2wS*DtEdn3`e^ulrg71&eX&aKx@JyP5y{9!I7$uG+pXJ+88B&;iBxp187r}0Ghw-BB)rT zl*EV5xtUpPipwrB@kW@WD}BElIUmz?Sldf?bgE3&4WL2CXT12%ww}IqGIUk51VedeU;tp!+=5GvDR%z>gXSOpI3LB zvuxJETTfNX1F2JOu7EJWqgOMGDdR`Te$f%CXb7};@IVEQkoxF^e3oVK_*?*w&z(Yi zt}A+3hVjsxDmR9LbL#zl#oM=GLWjkA$5+|CD#b&??v2D2f~wX#zJru4)RYGnVoAmQ z{IkfadkioCvEt>w1EJA1=!-8_H(lBaodb){9APhkc|utb3xd~&ZFvRC!jlR5DPgY^ zHci=<0&jB^phQ=7Tj|Zb3)EMThmk*6@0W*dX2TK9op$cBb1Cdp^wG0E+|-;)!AIHD zZpzMgkQl%P!ph`D>|Fp)K(N0-?m<23)I!*QS~sSn7OFz=kh%fu0y$4CoVAJ3pNV*W z0b%VlYU_HGy;Ir#$!MNx>YC+F1`5zp6@A6qHHTqEP_TUyL)?@)kJ6p!i}OrG&7rrN zX+7B6yyox-viPmGL#R3IW(j?&l=B#PO6h7V868cTt+iibTePBC*01?khy(257jG9_ zbfajdh-V?!(;m19+B!<$-96d6Jmc_a#Peg8s#HYj4tFjMe1iPD0vH5m?PYw4V|lu! z^*cVEp$gHnJq#Aph?k0ke7p}~p|n*7ALTL11u2{Mm4YSw88Yx|*gx!nNU_oylWb*$ z(j%aep)%$MT;CZM40prPf9W}IzcdXD4!gl$oL!IgCMVzm=NpC~C$kT)W#zT#FH&t* z{=C)88vax%%=kyvD1DgbDSeopNGm<@0KZgvVbJx@7?=Anb7FdG_L6K=6qck}SC?cJ z9xwgTI=)adr+||i0dhktL`}y=tj*D$FX>GOIZbaYy0#vVqPz@Qr$>5Q2RxtU%#7@W zsF|^X#?e%^FODYouyINm%A3aT|F*h)ozv{o0SPO+wblGFOY-_y96fvc;lum4pEFsv-p=b#Xtb0qSGYdQob`|8xEy3H;ZOIohtrvjCA=5T} zA%J#cAX94?pLY%0$g_w8*f2SOKg{CSis`ysjK>JTO36Q2rJs?#6M6)+=jIYrkh$v{GC{edh>LSJ=dZO9&y9Fsp&40sUf~{Sz^mO;Gjx zgoy*a^aF2xLTzfDaJI2VL3X|1pFhfZt$MY(;7p3u-d8AHKz&fBgf)L_Adg=obx=Xa zS;R}jTfsI&aoaBGih%HQJE<$n7jA|0RrmX-Q^Y|1kjo#xEYRKx?yL45A;?3RkL;)f z=Phm|){H(f$h#B-kmuA41C8NX8F11{ZI*QxhEacxnc!ULoDVTB) z6vi52Q1}0cudSvu+@UkpV7&auCxv)(8g&t-I#)2esJRv{`%@FipMzEVqor{pM+f5) z-fZJ2JVAu!X#^E3B`?i*9@H0Bny-8cUZevG4}XtFmwqJ%`7@4XwCQq@>!da-ZuQ6U5(!zs@oHZhA~^H(*bZ`c zku{Ine*Cy`J1hsaamj=UQA?QGjm9~#z@Fp%{qK#ZKnl2jqP)Dv2^Qd%MkB-kZ?+p5 z;&yjHc(Ps4U;2`2cuthO$Vzj8R?rd}E1`x=@c)Xni1pRS-293(EK2D50WjBt^`{aq z9o?HxxkALH$)_^gbS-|Lx}X*;i_rV8aW{GxR(tij6!1`<#sS|^6P;>?p?HOKSMb1g zpGS26Bb}4p75n5arFY7;Py2V0lZCoT0{)>6T8i60N}rZUMS^)#^uD-^8P4n~uhWvH zQ*8ZG-g=|SY#h`p;=+_@7HO?WA=3kZ{{=JEKOF3eQL|+)E<|>Fl{R>7ay~d z5__KzwzCWU7FOHrx~eZ$=z!1YyL3PfN&1-Iuf3i$&RMbsnu%$bMkC#>qagV3HIL%9lWSW{I>ggpKY( zkzw*EP`;|nTvMSf?jMSoqxPP&&?KFI%^7IT1u!%tb$`xA6U`Se5PMH{LV3+Tnl1k~ zTJ5Wo4tUG^*kXG-rEyP;k#^-viNZ)7#L_{I6FMgK*ALQ>vyijNMDu{#--x}33UFy0 zi;>51`vE^GQ@$*#qyv&!Wbb#OnPKwx*J=4<_Hl`{RqY~wC(w_|j6SmzyqeMVa1iiR zxNlXVz0<$9I$}i!(9)Ex!1Cd1&b_ECpCUe^B0jcTKsn9F9Hip<3i!g!q~ZJk8BSew zFZuC7{P;MwBCuHZ1224?-G#=4$#bsLq6d!_|uAq^CbMoMDP8TNMDAb+{9;sBZG@G&zKY|>` zA@{2kH2HD4v?E_i0G0s8+=em#ERimRDBAUpKus@cANKF2D8?dT9lJ#xbgaG4!Mxn6 z6lzZ$t7gQw#pk4co*_ z>1OGPAhpN*aLzx{-V5nje}OwLynDet>o2@>$`w#le+5i+mc3aYd7!|?DJ6pJue!s$ z2xq66Un77wcQ3gL+%2o7)INiPQD@b`zyLO5VQvvTMcGZ&j}39$E&rMg9Y7UE!%J>7 z#L$nzdEXpXnpRb^VxL z?0jJcIp5RfhQz1`e%Li~u)dEjqVS`qFc|Xd4F+5tX({;|FK-)oBszblGX#HCZU>;u z4cNy|qSaWV&EE1xw#=?JAdNXD?_OqkE+xbE^tL9Uu*R~iWbIYbTl-zroS6g_Nf6N; zwe!UpxD4v4cF7a+w_TwHg67i%q}y{{GJ@x36=XeHI>v zntr-RU(L~>k}ZLK&AO=j#fTW1PD)K+xzQ{hnHhxnk)C~RmEKpH$iiyLRwSNSMqNs1 zHg_!^f|=fq^?azU3i08R9RlOwWrSiHDmIMwOs46~)frc5f#WLepFfdbrONt7ny2%6 z>Ou|z5(TR!N^xr*O7~#Y+*3(^a*XPsN-;1)KiW+WR8N>PgAn`S+>Er48|Nmd?Eh`X zta#0g87`0ulSSAeh=iag0zZ8QD&`AXE83+SWQX~(B1naiR$>3M7>5Wxvq~S}@X1nU zzoE3K=vjXptsOHJSyYDjl9#|mP#NqC>sTY-3>Je%Nl%5d z!K3C2IkDAq`0J|bP*i>GJ8Y6;%J>7y$%D@)xLorR6gGpxIRhKd^buUyxRJC(zy_K4 z$`-)}fdD&mw?^-C$e34ki1g%EIW0QMcN%k3&W1$X-R<3}MJy%aPm7$FFIbBlmgwdp zB@{H~7jpY6)a`mzNmD7#zF6$fhNuF*VsG;6{?=F23fFzN4_FV!b$@KH8P|Q}rAhVI zeb?t&>NZ8}I{1-1|GNE3n2P*20x5TRzVvs2a{ZQ@ubicb&|+J$rp#X0O&410jm+sU zb~>ubCj)<|(_j>*JXOtLLAZze>v4hn?+uJA#GWD?+H1na8?`Tp)4T$kW4dh5Azn$(tbZVnJwWR z^f31krb;NM|CMFs#;fOPNZ57E{=tfWr@vySc-`JSjJ>@<*C`V3CQp5pf547=s+!B3 z#6IcssKq@k;#o*5jrywNu>Sg_;;&zx*V4QFQ6CX7m%ZIPUVkJpGd0C=x$cQbpOStk zIqz@dmZ*aXSu^>I&Qg{P+r*#kw!e|2OG7dA*VenXI|#f!klaKd@EWcXeP?jT-sF9I15MNcM%?pfH$4&_Mo22(UHm)S2_JJ@kz7KZ> z564#~XXfn6cikO*DYj}s#qNulyYqGr&P=G9?_ArRm2#Yo18g}GxM~}z=s)Bs-Zk{9 z%jE&zzs(U8#&fxTw%)MSSde257>Y36f%xiD?e)Mgb=-t7(9_sJu{2$K-4LecG@YjF z(_$<3W##NLyY7y<6kj#3V$a1a&>WNzUp?Phb4|`=Kfzi2(b0jI{w5nhPM!rI$EYLd z^7JlKdEIbjo|=~+nG&YM6ibyU#yd#X@kypDlkCf!rYW6EGjn#EU3W#N$5qV-!Ayl< z0w?%VHZij(?KUAZ+aa}_^O4KJ1=JJ&e;`_kyN<= z_y~v_``cRzY%UTyX)_{1R|EQ?0YbSL~sl!a`@w^5b%u>?@*r?!a*>5b*1c z>baw%Hc%U}G$0tYk6uC?e+#WL*G~>I{fj^Pl=DQi|FUMvT4o2v)vu*vC9@52>VXM- zB^AMDWbe*@C0I<;xO-4$eANPYLb92ec&OT+hpJD?67P4`N31mX@^v%&Orz6%hhwDELo>WV?dya-AUTeaT!ldNPuRTCxQ6&)aIj=HuMI6v5hWMx=KkOMD zrH?d!^dLvM>iws&7F`kn4pwmZNdC6Vt{aD>M3|=L9ZE57%HP`mNMzykV_9uF!((;2 ztA(E@vU&VuXvIs|M3k^C)xFSBSMyCXxpG|Ml2mJI2@OfnY3l6Fr5$45BeP+tr-vk| zM|{vfew;qx=`*}m~ z^&*`&)CMEY4`Y$kDB8+5k*@41^8C5Oivn%#rFzvd$r++q%+q5j+wJYl8EiHJg0u&;B zZjkp`=@T_VTBIJJqn1FEhq!xR-Bz;w3b_?OE(OAjl^((w>7iN~+J8-gqMjm+K!uGr zY9r&n9Q57b?_4!?52RCKe_z$`FZ&FO)+gnEbMK_KvY)TI-x4PDiH8H9nX*4)Q?BdZ ziF=YR&b)YF&&9tpH^=Tz%$%8)*``m%Vsb9gQXzSZvZ@O&PrFtuc|VpX)*a&+;pC2; z+ULr)l5wTqTqRv`C~1QB+%C}+h0EiGj5K-ke=)D(ute>vp4i0_;$LcG;0!v?HLLDNWij3Arn%=*kr>zY2Rr^k1Z*)$= zHZDALv=G~P)8LdL`O{3PsisW@+xi{FHg;xko{Zg`kKMf4v0L&MXGjcN}Qng)g>HXUU*Ks zKV-Ig$TZ)+({X|2?@l|vC4+B>QN{(>5N9`D+?;fHq-lZkv3SrgH5k+@d-mn@(cf=1 z&09-T4!CyF$%5=IR!Kk8MEO>%^lPB}Gn-*|>Y-Dz8u&}^7)w~mA!|x0C2KO{26ArYJ(%K26=k@K4qQ-^bjM1!L;gMR}@ z*rFjg-}cjFc>9pZ5K$Vy{Nw>VJ{+r)YUqSqqmq7-s%u{gNv0RM)CY`>uncHmOhe!* zjdN8~pgo05#o_f_#VhB=iIB1C0W&-~QwjNdz*KhqxskKyz}Za~HzzolO2oP0&kwa? zLl8LYvnEjCEEuvnKvUf=GA3$B9`r&Qq{?-Y2jP0GkZx0jK_wk?l7F>IzoOq2hs?5$ zumSpJ7!uy>_a!%M3Z||%Rap~mt9lI8d!$czcwI|PV7&HtqO&N@_V%ld~D$)IU26UKUHwki@Nmy~{$a zFxRld>v*5r8`Zl1pe%Mqe#@n*BrwwD&gW^3| zV{YWz_GCz(2nD+$GLy;|IOj4Kk*5Tq-#^ou0jHOe)86kHi+snL={&tkDFf3@?4(sV~|FvD2fKu9ut(>gwv8lr+IAx zj~ehkbit!&XoT4gh&@v{hDI`Z-g!RuZ5y}yupY4XupZr6lYBuL8$ZY1lougG;W?WD zNQm%ff$Wy_h;AW6!I|8}2&su$b2Xf`w5su=)KWqvF)X~q9FA(-z1%U8Ke>fxm3D>c zu=3@Yg=4`F#Z~ZyDYUO}Or;X!{>ubj3E(%IxwDP|`?Ir93DA+;D`v;*DVl!4#JZ|k z=vUo__eK?fdMJ&gVdQ-2$?dKed4H%!yb8d04O*RuSMM{WGz{l|N9jwkciQBdtJ<>Q zKy~c0kf_o6m^1H{9g~`vKc{eCYR1OgZShA(z#uq0 z9J!?9*+;9`Kwdz7t#a)T$Rw?{(rtCky4yU%{j9W#XSh#}qRDKbBg6f78qIoV9?Sr$ za>-An!!8c9o-TP%w#BMh8ZP}!bz%a=j8lF!B;SQ>WN6aL|lbPgp(xM^D_z z<(H2uU&l@L_2B0-43_g-FY(iGm}#CV`QXKkm$nW|8*PTk|8qFI$bRmt(=0ttZt9!s z?)`k@&#!q#<~a8LY8K8DsEaH-EnjNQ!g&t-z)1%G@p{d&aKrIQ*2_Eze)jp`kEFkZ z#ytSO7Jpnsrhd9uoYHExv8k7W5yi z9`||Ruwi=5xund`%MUA`3|-RA7wH;9FD56S*$7);c=FKnIT?HRod4&-#!-96URdC~ zeJZlzd$9?tSev$*{9gw*OD|Zv?y?)ZSgO_>q)c_ex}u+rzdNURip(>bJlWV{dl7Qu z12^&9_^r6%<4ccQPn0MttiuZTNt;%41uJS$$GsOEJz5`qW?5;r67}jg4fZl(1;%7Z zFw=EYEMMV*eW{t7vbQFtjmVqle41A=Ol0q`VME%2lMqK4Y zy3$`tc^>K_DBlOG*#Mr{TYh)V`bTbIER#Q~vcGum@BY|rxlihM+aN1_W9`p3+|5SV z-+PdN->80nrw1lUl8|ml;`{s6_RHmG`G8A`kWTzTnjM!7 zM#Oj)=}TOc{H~GykGp1){z$_A+YR z*sdhm`d5h=2FZZ3BZZo|^OPuxru{FRY2=l{%;mE?&NQpf{&YBf z^+t^5scd9tcr+%AM`JE3iG$vCfgs2s`GN|uZM`f%a+1GVG$oE3`MPr1m-7o*lK6%E znt=pLypa-=3mbMHHf&J?r4n4z3vo@q(QCz{Hqxstr+Zd2CAb)axT57?@%i9MW zjVhSV5uIj>6hcdXIH)*6&E~NQ?8DWpUt4<@drSC2@n+hspxJ_?mttn$w>tGy%B#*S%PBSf4+G4eTpP@Nq7~dHDmN+4 z`_T9MabuqlB)ED>dmv<%I-=euGVMw`x9yVahQtHIjPs1Rb2p@K8Fpy2aiR0^3F2aK zv1~OP1c#^@h0_86ElhILF!@brXf+(7@rpwf1czv*-KoC(p^9TYSVQaC2}B+~+(h}f zB9C?T{zrCjT!TCwIOLHX5(jyl=dqr6a5C4p7o22nNp#3#1mrQ6b20#&{Obr^;;+mv zU5@v0slv3Cc0>j&KYh+5y) z()du6Ju~Nd3|lfte?BSi)SWiFX znne4s@DzQ5w? z(~i_x-0>DxJoxfQ)Cfn@&zj@ZS*F_kg zW#8acQYEp<@MF2}`Va&L3-SyQaDOOvzBr9kj@QTjA9Niu1aE$k1@Ax0S3beR)0>?V z^v4nl4k@9*P5n~)7fdcVoLaQ$$~L}z@PzY_+2oGmGwD~FC*O`j8jSRZr~DiH$ll1n zdr-xi`0V1!s3&H}$y*>uyndxC)2a^fZg^_EuZWT-p-C?Vye|^o^h;SWPm&tUV&%cA zpa_&HN;j!UzNwOaK`axAQ5@MGM4XIp7C4}|-?1!HDa8cPyshVD@HT&_bXkI1ls>>3P zGTF+ZAmb{?!0%{9va+&t!!gHK%EIS3P+w0O+JY(OZ@tQ=Sez6t`Yq*|lkUBk?_&MF zXpZ3Rl7Hc;>p5gj4ngMR-n`l&0%_`>7h6$mc|g5V;%(95pm|)O*}7rAJg%$Ew}B=e zaFy9|4NZiGg1YObFlgwc*Cvk_vAgiXX}Qi1sZbTE)SleSkqm_hvAgpAIF!8+=gu0@ z8*wz0l1Rv=MlYF=&5}^!_RbX=SwM5IwlbB_sS@g>v<#H#IE@#5;_eW7AZFjGs?6@q zI)P~yJCKui&why_W*#|<+_t+8g6DZ1juYj85BOcbO zu#B?HNK{&Z)lm;%bUUBiia;if7uA#a6MBGx%t5i*lv7=8 ziuLx6}_Mmr3(-FOQ> zcU@f*VNyO#FdFko$iJNrGAqkydD*^_t(Z^?P3?J*$`LKbjH*gwVxS%S`_1l^%#~@o zbM*JO9{7=#Tpv`>TY75BZi-MD>S&ak0)dmAr!F6=0!9V&nyh~>cl_cZUkqL8N^65y z!BKTi@sB&rZinJ+yVKM66e4f)($Mk+2sN^%DTy_R6GOwy?IBz^$0Tx<`V>$@v~V8Hx@rLs1IC zdjiIq9%bJ#n$6Gh@7gbNY@Ppd8P$lzd6!@X4Gj&B9_H;6eX&$>6WAN~4b((;-%4-j z**5u;bOArCG#TV+aO15s3JuL-^KNHZ(POYEpVa1?e0JZKQR~tTWu)b45RVpN^s8c7 zUOGlk3JQuIiqS8X=_Sp(SPB~!yGH<4;?4U3f9oFD=uPCB6|ii1xkxi;DmzY|IzgMy=ze7vL6OY3>ELh@~U7}%Tkj)G>_(tgDwgJ@gIZE>12xHA-~^_5G-9QA9is_wj}FAqB!AdS3ndSs2QubWD(Zt*GDHnKd_z3I3G`pJ6w*rFPiOZ|m81RtN9GUFyPyIT|$e(@9y_*;%R}oze@j zAK%&w4KjM8e2gNfaHScd(m^&qALLNdScGO4oZP#7)yug~<%`z5OEow0h8hgfiJo53 z8CJd2`d#RDIco^=N+jhIXv~`+-9X^ z;&l;2gOf=H`9q}*Bvlta&nJ~~jHOxPl=DUN62y;*m3f&s#u9wx)q--gXu4Igwya%u zAEuH0kVyIg+bsqzk_AT_#TKkiSh`QS7T)2l6RSj8Wsq;9L>F+DIA!Q@0lk%fTOlL> zTevJ+z9eYm6_jpI6!~chGW_6lV=tVPGxBZug+s{g+|ae_jZjfj*C=S5YS3g4-{JZI zyboElCxgeSeIfxF4ev0%9DN`5B2_o+d}QV9@`D%bxk8|hH&DENM>}3uD7^z4#2~}d z{D55$c$S>8yZ{q_!WVjjm8N0p^*t0j>KfLX&)>g({;$|^aHq#|_mgwc6bc!0mQ z6ErhKn?u_X({^Y;OC0?mhogVIKsp?#(0mUji=4+eHj>4uXcLX(8-ZFHF#X;k5 z@>}}E&BCJN=(-*(NXxH@jM$r09a?*}SQ&?@ID{eG>mSn1;E zuA_F+Inj18>)O?e@c{wD;`@aU%d+XI>RoE(Q^}e$0rlst*xQx91TU^i*~)**8X6%; zR?*R7FjW4fm_8=t)s#xf3RXjUA!xl>*f{5EjkTJSQk6E9YNapG$L~R@-7lE^iQiil zTB|Bn$;;@aSamTQRLf*urQfYQDTn$8+L*)1p z{(DQr;tLnAU%N0YG-UX&@UY<*OBA-7`<5}>D}F(o`HCQVgM>Eps%N{8Ew47h;8DN&WmBOIlICq*cn2`d~?0ReCE+T1~C=z}#SmEW(9u)QYSE zJ>#14*vzT*F5L;Hd7H;UI*{89a_?he!E7nWO%9PiFHx~)XzmYEfd+@1tQL@VV^5qQ zBA7i~V#*WP@-tcoKyOm9wn}Yj+8;HFIUHz*B+q$_jAT zKjjlHwLH95Fj~N*zI>&p{timz%A{Jpnp8{HveHMHR27y6%XmyaH(3{ulACKw;XB_t zBPIq|_BuEE#{pK3{9qM=;S@(Io*%5rWO0g7oSjc&^KGwN#mh8x^;Yp+?6*$!R&gg- z#l2p$ij&x|*R0}UlvHmO*Gf0pvUvhUn(r6#aV0eS4`y@#PMwNRmx{G zbS@1>;8xRP({C^X9o;3d1^>qs3~?B1CEOGg?gwyF&_;q{3d*kN2%Rl`+8Z4u-bnY{z?CXB|Fb zFdh`sN5ennogtME$3l*;jG!I)S2$^ZQ| z<494lQ(T{qLn4ZO;O7^W2z|~_+&p@_TeYIk-t2AG3UcDsLKQ!Q=B@aECBt5-cdLEi zR!1pz6D4p*nrfwHU}!E@k~%7O6TmsZDW=dfWW3IC`0Qo334A;z~yDPLDt z#fouL;d3rL>H&CX;>C@$V|(7 zVf^W)ZUg;;LmP}dnH*2QLi5swHJXx1ufof$RgjMNH zHd-xx?!=bCu$jya8#;l{Zosfn%#APdsc-(Dg{@vQI5fx3qb22iks&#X`l{Jd-jede zQoDb!@`+xtK49uA21vEzUh#g-0NKpXtyd;Ueb4Lv-bNcwjo5{$9;;apAMp*vE@{qG zj})^+^X&Hjcgw`t*P>j6fy|jTuLx8u6ALxxmdUfnuURIr8UDtuH~;c~S`C*SRzvB< zba0y#94>H^p;jYkHm{^c1|~_BB&jvMJOTmsN=v8cunOJ4qe?{?PPiOZFGJ*MCDa%n zIhRVGsFm=~Y%`6$+87j$71Ky-Q^<9^{bM0ZiTK3#_H&bb?M*~>myJ|Y@Mqr7*_+Zh zf!?m6CN%J8HySB_X8jLf=xMO&ej!+?0PVrbeIiy~0|wWv<=5V354?zzf^#&0ANg$zOoMWFI4ALxGRXzRX8% zaTz0Du~83a_<;|k!f4VUz8HitO z^SF7zpA7>}@#-LEKCaGt@$1pcZuCCQ7Xis3w}_-}pQya!QFS~G&!W~n>FIdS**!Qt z$;xxfSmQ$pH>$NfKO^3BvyhsC*Ftb=wn#pCn(a2c3<@v+Bchp4^5q~?J)m~3(D3N`x6jeR0-5h)&_E{+voVV9-5u#Sxna%znE z=I5p-W>6~x+7sl?9dAV{m13zey}H_%6dV+l=n;K3I{>+zcfPa*k_<+DeGh@1!6<)+x2Lf+5oIhXyWQqq^MxJEHH#9e6RZ4qYl zOm9|TtW{ghqZImsz7uIO%eP5yvosZ(LON(& zrp3ZVVoV4Oj7m_nu9e89LK06u@+f3)a7p+w7sTiM6{RbDuIStpoAjQ_Wk_~n?&Iu= zTpn_IVS361u%VRREnRbMd3|TkWAo_ShaxQW=}KQrKQ>*ZSvUtxJJs|?-r7IQ-M&Jp zPk-LN)6u&VX3-q>BkQ0Z5GV3qJ}k9hhw>9m^(=IZ>&x}wzAwggxp|oyD`Mb!qjIVJNXUP+Gp<;u7vFgXE21b;S0#9Y zw{cl2BAEwI3@X_Jk9|A_W5u0Slb6I}GG1;tVnMYH3JO^?sIvJ2Oc5n2qoucQ6u!Vj zqS$zwvZ39BFEek~@i>z`aBRoM!g#=2h8eqZ}L`f9JIW}%Ex98f4ga{n`t;;dV<1KeTVjNACF#Y zCGtqY{m9S@sxV_}gtGhbW%K!HPO|W8Mq7ZPOOLyDwjOqJS+75P4tSe=((2#AjN_KnW6S@SY0-6RjzPh<;i z(oX^GJr=8e_OXYuxNWewZ?U(rxNZ32zWmEg^Ir-1ZdG&D)6? zX>Q)N0!;n|SEh3o>c`hS#L`a(0l;u_YRUWUWweCuIYeeJAMheQ~ra`1<}PP~y|3~S69lRAd@A9XJ7sm4s5 z%VOY>jWpebVn7d-yCtrYyleq?19i&D_pi1kd3iaG=ef$s_bV4h41~dT?)CM@R)?>W z%xc)1!s*=GW?KO@HovSNTv71=9VO9Z5hvn52Km1N)2Rb=R(d2qR8b@9C4x+OIp0^@ zhOFPO9Y9k#XFUtpn_L2Z>}{yIuR`+j3uRj^#tJFWs*_Bme085FGzVKwT+35BqdLyk zEak?j$xAc@U`n`gY?u;&z2+$$Qy23i>_bm8Yhl+3)Do+Td&Y$o?-Z2Qr=d!$XquVE zDAv`dSE*UaBUo3zz`7bR;U;yZPRDOvEms zJY2tq$V0%exbU!H+2B45yJUH>^h+pP*c-S0r-4`8+bRybhPC1j`wI)#O+^QmUxYbu>yli}I zdSJwaDlGJ;V@m%;U$@!`Lajf2h}K*eF|lD`!NZ1OVi!w6VUEa>ilsR8&+Mgs@M(|{ z^Wu>wXC`p_?xn@_2!w*<)6E+z?#+$>;wJLN&rp2i?jt(7lNeRFDp$%s>Px z!3$1_Rq?obKb9!>}xmHbz!^p_HndTD-W;^eIKd+`k=9tG@Phh>Qw;!+=$gcPH_38{4={VZ@><;NvhIY-O!Lec zie-Jgm}k96KhQ1l$K-YUQ?zN{rhaumPgB`EmF&y(u(umtSR3qZWPGa2r$?R&fVEv& zc>ZRJ8@*y3vsJsCC22lM_{Wm z5obJT4>jE=_?>sb`Awm{!upv)9kHiS8Y;qEgTr0^Z)f`rHhgvXneKN4B!Aj$-!CvN z`ZLKMA)J}=3S(APOTo~Wj>@cz1*$0<&=O#z*4dqTlZ-}P#!`_M{RumieoZC z{IF@0cFW4m-)z)V5{nf(Tct?`)`%@9Z{4XWk-I}0Y`!=6wdIE2En96$K61vHCCO9R zErG|vzVSkL*Jbr>=yRVaZRqp!e?=E1ydv2+&XvRCut9hsS^{V<#^O~l@AIKE`Y2y!@w}9(SGi?_U^VztJi(Eef8d)cRQu9_8&e|wGN zrS%Q#=lasOk2%LH+}YAs9Dm(lTWb=Uq4m7T^wcg~m+geVTZGGRQ=0U4IOmv+r786+ zZ(g|>ET@Czq*p9AS6FUR&+?RrS0V??{tlK)R~vVyopz?>U8twdCQYq3wtqEITk}s1 z<~CQkpfbek=m?Dx5x$dx5bO(T2=%+&4^w z!&YvEx55oO|LFL7JDo=WHSEJ3x|2|caK0COxHZRJH#dCmx^d5GY|Rf?3pBu2jCFJV zdNZ{%|5$IX_vDPhTsIX+U3rY}HFJG`fkDNF(^SsU)@|DD3P%X*fvI*X&E*QY?*PSx zYG5j`-g$5pdF)TcK33z0PE3j3rLe_YE+fwYY~j1ta(AADVy!Pn-BrGFEiAN$&@+ zreFuZ1$K7w6GI7gy4+XTac)^`+$Yu& z5VwB4g)i$=k^3`p0PBF0OjFCx)lhz}dN2*nRS$le%q=nUgDj7UqW^3a_~kyqA|;K8 zS_tC^1ARGIxF;Z&|l>yLJcXx?YCw*rZ(n zOvFWq0Zu4vD_a0juUvsPCb<l# z6U8NXi+!TT?;oFv4FIPAlBu|!$9G{r^a@rBB%0($k)&ah6c3>TN4x5nm74d!{ELxX zj6a*e$72hU_t?v5AF z^A?Yv5WN^3aV9!3kKW__0`80@59)jOl&zxIN!Hgb?Fla)XS<^9Z+LOf#*|M}%q9R? zK&HRAHdpC01P4kU05v0;D#i7Cf7q9*OoUP( zfE#5>JwMZ_Zp=$O7t&TbDU_t2yRp}e+}J6He>0H#H;TLQqnUb}ekf|i{f(NdcZzTD zpmM#-p~*k5cpa6O@N|7C&evyXT)*(4*;RV{h}5q{WW776e}a**Q@iWC9bawJzhH|* zHdk>*TCw(O{Q8L*!*)f%9dW~Nm@n=+mEy((xurBIDD{PM9GLw62=E8!o+1SXW@wcHKAnSW{Lv4d`S2O0gE-}2z`|LwPYZ=z1- z?;V~CXRe07o_AS6Z5^-YU?~Bw!U1<)~w}>E;zp=J{vl$CDS?taoo*v)_zkFoouHZaAD0|VP1W4cgiWCe=?NX2=v^%&Wua#2Zf0~rMsZX%eE}Ti@s*Q zyUYa5CU-dvcy|qJ6^6CK+Fi%J;7(@;FV}V8@&OOZdVz;&V*6t0<4||zuEy_j4T@@O z-vY|>CYdhnI1X237eiCod7B#^_yYxe3$+Xpw{L4vWlHh6blcdN+LY218%;rQVkRI5 zo<27}&^?Rj)Tv_x>&QBGFhAAP5jlVdrYY!mYF{5EnnQHQAKC*2)mJ_lOqpacOnmTE%P%e3i`89{BqaL?;`9JUJ;|OmgbYt?sfu2)%b0N>PB0Xqr6YpS7zq~L$ z)sho?%gly?)>{$GspE@i3i(ps889tDClWBTiRJi;XggOa7X)?HNVKlu+dBy)}_zmVbt$y{SaV) z5a6(@Gp+y*`-9H8B=?&W@q&yrdShD-Kc@R52$|*YcThv1k+D z)eS$&y7(Q;!9P;K=O^M7HD~nVeK|nr$=Ul#-@o>`Qa*I6zO#4%nlI$=8lv!Waw-0j z_ZDwgKA=!@ESVPE5beJ}01K1ZtdnXfNT6!^w7(4tj(<%q$9RlP@c?l@Y1a_E))r*n5)aoy4XRLqsxCoZ+=cxud3 zKyuVBl1E9tVCn#W@T`~>7wb2Rb>Yn9@Fn~};pFEh7w>_SUXO<=oUs1_y`}%f@wvA$ zM_t^T{b5dt5#ou@;RR0v%Sm0b()xK}TG?;q!%_1Dw9h#=MVg}0OiO4)#%@3I*)=Pn!LM&VArQ4mz%0`X+|F3S^dhm&c~I7m221v`jmqI z2LQdh?yA(?DzKl$s@;N*qZNF!TqL{La%n;?|NQ~H0UAYE2k_so^%1BU@5X*xdP=tq z2rq_1`c7gl3ld_Yy=U+P$2%pD3x17gQ&Z^A&ob|8?U#ifPZKEYD}4YMoW{GgS2wUn zNxaoq0#L%FRkU8|)BXnU(;o01H{#m??!3PDAaAev-o7ikt*qS*VDqt^keR9G5OtK0 zGpYFxDE=Z=?-sl<2h>uI$Sp8cfQE8{h4F@F2uCX-kS2VwTo-U4Cz}lt;$j14;q;1!2&$AzBU$QrI*$Di3GseC9vp9Z~`GFb* z!|67a=1^=-V`V~o=Qm{|1lU`(9s)83T|e9f+>lNi*}GRhsB&hzq))_*iv83D`)77y zy#E~573#V#i%ab@u~bd{etLZVuJ#dgzQD#}g_{rW+UwB>>i@MqnAPFPp*IR>Q~`Zg z(8^Xu&8_5I_Ec%uUPu1YS+U%daqFfD6#58dzdrNqQpYXP&4m&l*2u zaQp;+--P1@oTaZsjt>;@t#h^djH8o#Rc2{UuJL;2muAvIOvT?=_E;Ym zlNyk2p-6sa(jeJdFDb? zZMgIJhmKuMq4`Am6aD>&P_Iw=fUc5;T^ zv;-gqgv-jl~E?fiF|6iWdnOf9r zb|4H^q|U>;1uI%hN2p#7N{We3QWTuWyqx?!Y*;MvSokMGg(X*cFRRbed z4_D6VHz{fT4)nPHIy3RBi0>j+x=MbMB+AWMBYF{9TUZR0ZX}Q6aMeD>3L{ec_$IPk zu@#qJy;AZNkkxn>>mxCmC9rwo&@ZFD1)|ec_1!;mb1Jm=15Hq{W`U7C{BmP&f2I#r zuN)MyW~8Et%_;8t-Jr{^Fs1MWRrbiVhjyXRUOFV*5!v_d^m&N9w}d`@$-XR+&MGgC zdrWv3rXie#OV(iu6E90p@r4%l)5VwUN{Kx%gdKCIoguYvBJFy%)L+ayeeBBRGZUj@ zMo${hf6UQbJw0aci753_xLxUdopYO4t$l3BXKHXeq>FcMG`J0J;5PDKZasBu9?KSK zl!5(iZ`xkzb8DkzJ*EGEF=?5c z{sK``TToBGSbg{R+?;aly+ETPt*D;V{gw74#9R?Q$H)h)XPvkz_}gXMGi^v@Q{O6qB3HWA)U5%j>vpLj4+sAgWsdmVN+B zzm`ZvA?yctS`i{|Q&_4HGtV3;x^iZ6LOi56aCBN0q=*e!FTxVOgxM9ZiO?@M4ohfI zuX-gyXYj~HxQg8pxft6ApqZI%AGN3UwmAuIpq>yghqc%9Wm}_|al^WHCFh}z#!^Oae4$)>+cSgdnBFU~kN@Rir20bNU%k@De|3N54DzG7>-N%cHw?{Wxr=xMk+tb^ zO*G7|1p5R*+1xgBbr#Le=0f?YY?C4sFypDi8n}qYtRvM`*^{GU;wJfE4RX0O-fLI` z3)bNGD|u3>0KtE*_k-XycQ?bRiWQ|$Y~N62``$e-*|2?WDrv1$Q(Fz9PxGj+iJmGX zf3&+#I(EQ^HZl*^bCZ=UtkI1gxSK_GY zXZjHJcfNeyzeke)TAKeO4c+5vVoZdEDTh9lLODcd=*>V@%t3dha^io72k|df$sq!r z%a@vPj-Z2i(w{=D)~bR&j1=?04NBd?P;@jH!U+JL^4!4FhhpGozTfzL>s$rXkaLxD zQ~S8DNzum0E*@87k^Z6g;H$BQ<0z3AxcZ((9dt#*%cgx4sLozsaSj+&r_?RN?Fg80wIf8`|Ii>~1#;6XcsxOK^A;@|qO=?;6Fj z55Surmsh1CuUxEA3}?qvQ4X*Z!5x_SK(ZL+#+wXuVUH*40{3NPSoYmO>%+vvpgA06 zew7o8V@|`mb>}?~<0yujT|&?JW*2#a6oP7_^G2Vc3hbvgrD<0B!FsqvbB?O$3d$M3 zOgZ}Pv9`yLuKy*~jm=~~sHvp{1FO@s$gW*GMzT(>Y-zK z7A?86wl{D%C9!s%%sudU)U|1P_AMJX#C|CsM}0SQh3Q@%%~rhC9TxiDvVjNOUNl0) z4F}n;;x{QrzB}GlLyb-xS@%+g+)|@+S63y^{(Gb68T114`RMvrY@H%WpqZcWX zZ4ybu4;Ab_d@=`dxPN_D)<}<$V-Jlhny+W?u<><+9Du}+O|;bLh{gTMS=i1QKs0VV z$5*R6gKh$Mr8x0xg%bxG%n5vG>?_*iV3L|NSoDMii7O5@&v4Z5o zr}EI2g1MO3a5jv+70H@{*XYAz3+L%sTW}H}C>`Q+E*nd;DJsVizSzW>`3o^SO|3h9 zS|jqVi#%wjG=*2;0(dO_1p%e4JOQ?T_%X%Jn{!py(jD)_>E#Gg!OfnNl%TlTUH$iE zB62wiTzwL+<3Cln?a+}7?E@v2qWId~^-;RjiH9c_Epc`SORab~#b&ybN0akj<7YFE zr~D`U|B9#ZQuIjr(e5I22Bvyps(;yUPYXv7^JU${^YFMV8H%le>9Pt%QD?%XOtnST_iSO;(}>_O{**!y~5 zhV#K5&_cdkE0yJfT)H-J^rM(to$^3ejntclkWFqqQ$LFIW&=|h+NZ2VCL4)AEfP9$ zrV5Otys)zhM*y{AEkI(Z+;LybAu`dg%T@I$YOY6Q4a zMD;N4(0DLaugScLeV*BL7mVdOLO&ao?WDwh&ez9&6v$zKJJdrC1Ki;kC+MR(sZ%FX zbGueUlIC^H1QbbVBTl$Gw|MR}ubVHlXFFf@Tix&i#(h2=HeWW=`v~KAs_chIqm71CY8YrO5lMez(!fEUlbD|A zJdPF?-8@P@H%zv!)9u0b#Hlsc_tAo2cppG?k3z+x!@3dVk%$>0>a6$R*J>(*Ig$~w0|To z2SzO|muGO`$^hQ0HmI(zAT{pHHn3BYM5ow>Cu)~O1t=?c3=N4i<>%E$mIo?tK0_>n z$~E~3GHRa86|{)A(TsU1=K-gz0#K=Uq(^iI@K-8&SB#Vz1K6_ycDS1VXtTN#0zEXp z8jcbw0xUEXkz_vBe~z$Sq90`o7t3AG`O(`W$o-?8=%^g}OW zmERJ1Tp7<)Jj`r6$e*rkGnMYNtGH|$`KnpaSKWs8(sp7+!qdCmFLBVzN;P7td6x^W z=F>Bc^HqBb=s(e%pT-hvm3 zBx@3p{xTZJv~{Mga@~zz%K!L=BUcV(OINV~j$Bz-x^|t-jWxp|DQ!mqA#IUgs-*3R z6Uz%(JQ`0YSf!gvsKEQc_Ux1SrfeDt^YD$5<<>LS+q`mEbEX23=o4ZbMfJ7X!wm9H zHTNkROM}FUjOj^qqMGg2|z^-k3KM)tiso;f`6&@;Ao&l_>n+HEeoC|YTd z%Cg?}OX=@lXSP|2!)M7V76?lg?ap~`dDs)9S%tkAPgNzCE@$qc;jH6@{TI(&qQ2?i zr}!(&cK9}s4!7+e9f$YsE}|XsIIFbHAcv~u#`IjQzBGUA_@VQ>eUg$-oJ!w=wVH{w zsy=Hi_dd(l%6pW*p?VZg<#={{JX_UQhk;11u3BG1Il|@Awcp#^G><-5BKH$Zq`xR$ zevqKnJbF*sFhKsBjkF8Fx;P{UneJrnGNoscLGltTJZAZq)L2ZQ_&BR{71g|I&Bg)< zrv;X8?x;~o^RRr$XU}Hr#qurV%v`Lh^1j4ev3x^)d}@X%%eRp)U)8!AW%(eRp`d|oM`a)n?fC@c=Zzhk zG#BLeo;sD04Dt&&`3n^l-WL?|!~OhfhAZUvVr_g?mC(`hKflRrvk+_Z-s|ea>34C^ zzX9?8HfUU}wEUyaa%6~;{rGZwd${iK(n#PhGhpLItn{EO9a4!GU}#jwQf*d2hZ1%q@7&rAwu|3Hd&y3x>Mk7l#JV zXKs3Yk3QiI92$@6)sq^J!bv%dnw-6Nmo+)7#9>17atq?J@c=v}r&alt(vr%nH&KAV zi=g(}hl)jKCdb8(o-}aasH0igXO9%QvCU58WXr$*AixZFqnRP1dk^anYUV~Cju)4) z&TQ;z_EuY@&*P*!XI%3`KA>ky)O@rob^f}7pK||jKHE!V!MJ?bm|}ZjD9ST7bL`oc z=7(7aj2ED-S*`9~wUv}zEibkpF3KTH`qER#(Q|mQlpl(n#P&iZuAG`TX584h{RfQQ zd-C+D8!M|wuwqgv$qiCnk?GKmTG+#DKWzR(lHn7j_&akhtOD|o`EW5NL`)oRON(Tc6 zEOQhFY&<+l@7Yg#Am?TaXW^+hlsu;tOKU^rp5TCPfrEt;CyreR4t5vINdpKE!+MY2j14K18)^y z?~@0Mr8xN$<)=6XD^^Nd`^lTxD0|CblvYwZ<4I~9pS913%d2k|=e2CE^t(VZU%)ZN z()mz%C>MNv4-PTJJ#@`dCj^jZkqEe_p;waDS@?<6I4M_qUQY9(qq~vKUPUw z0eK@Amq^7p7mav@euEk(WbVy7lSw@?z~Vv6Y_KT3h11$|bg{HQR1W8|Be1w&{P?j8 zz~b%`Cr<7Li_O+*q-^Uhl#y zGEU;)ea9$o7IWt;0FPy7=$Cbg4Xf~E>a@s3ny;fj_lE$nvbF}-0D61 z;67`9j*Y?TvZ>&@nLf*J%yFNZS)Y|s8(1-q?Bm6%oNH?@T5Wfx#emFHw{>km9F!1{@04XoHL}~ z0VPcxO*l!AJ2DAx|8JF16YE_E$%pWM@PZZ>hj&T;gtYAJ%(QYhwgHCIP2+?MGkEAH=A#zgK`@+WlDDT zl*eqml1ZJ9lXNQlgq9`CtXbAuC8V*!(Y0^mAey08m8VV~j0>?Q1CM!$Q@p(KM2g2f z%zld#X>S@IJ@znCGo43Nm##OXF!4p~plHS7l&vp=fux{T4`)kOvmkCDU9VZY{-zs7 zk7v0eB^uZ-_U7CjtI4*ZQTc@|yoB;wX{BYK^=>h_qkx0I4Q#6oRD!?pQcp-^*2obF zGyQxM51v1#n35~Fp$2RV&rIb-4k!{e3DkyLVUhBBu?CUdsj~hd7y8fTe|&oh$JcPS zXblVH%5vGZ29|A4TFT=i-bQ-E1gmi@czCPq^Rgq>J7v@cMp~2(i}Ai#o;fu>Az`Y& zf5PF+tjxn$j6Xp7R^Gh_eU)c*kC^T~Z$^VO+2w`2)Lb42LuR0gWz&d;#mT_p3|AJ1 zKTTXIU%MWHe4DwjqiP;psG*~B8x@x4Cffp*9_C)z{>+$|0Y@%TVQPitq_ql6al!PR z1g<{hmg~@@#OY9x)bvZ4so?4dt|HlYZ+qk@DiYhL*DY?jE@tboFzv7~wx7#>ch)@4 z{wAZ@QZ|e)PB0h7^(u~bF112mRk`0osUP3({T?Xq+2>nI)l^E2_HDsQ$* zn_(FxW>w`EG|23x^|mdBv#0rNg+qVZAzB;>JQmHTD=IP|zQn11Tzqc$0WLy4M2K&J zUr5m-7yNQ5^6x5=)Vu3OvJ^#~ssXT1B|^#Cb!Be!TVF9?x(W_|J3r=!C+rw%hbVE@ zc|?i((wp(rc6oA68|Jr#=_;rx%$^*I%%vu#!dGi++iiWu`3$pq>g?O>xuQX~fYT_z z_g6Sp*)PDc$~I+{+tjZzEW~>{n@Ghy*Ex#kde}+}t$Pvi0i=Nv@^RPkkk4xoVz&TYecUJ6 zNmI8%3H(qaYV>;O2S39aIYK|wgrPQQA*pB~`RGiw=OSqiQ?Zsj5VXijhnR{~iq+ES zdKmo}Va_+vawQxTVtryIFYB&K&Bh8xKuC9U(x5>ellZ**A`R}=Q9keENQ7{E4^aX_Zx10nz+2C=_t+{C&2j9_%`&ngBdJ!5po7vQfxP(trZfbFYD^ap6gq67 zNtVMrU|d)5Dp(S)1aPu=uwS<9?4S_(Tu^RD#?}f+gOAP-4!}D-(D^~p~HWCK^ zpBA-eE$U+hbwFEiDdk(6B`eO=NN{QN9pAG>#hdDes6yDLY9`vdAh-GM(1l(YyZ>hPjJ zYs4D2AAs%I-u?0;-AlAGb(4F@$=w+fBkX6*>e^|{%SWe?v4@vg>6lUjy4_T6 zdX^#7A;+q+SohAD(*6oan7c8iu?Xwvc^@ zUHb>#j#xb1tP2wyyR_Jpja@1wDLXVA6h3N!D zh0Q*pCfAI${}jUG{o~8*W}n25T*VrZlC1I68`+ z8Y5J-VNwtzfb*o{lj@!dWt&Z>3`*8}TZTI0Anf0*uO9CJB9XEJOaDP_7q2 z3o(-8O~})9IhQ8aC+bS^)&Y*ePKx$a!T!DA7UM)i1r3zs5&(4SABVcj@ekC@7Y!a+ zGdW(xVx*3cB^8;j;0DQaurjpveexU4_WqujHl*K7Ewj(xyU>%~iX*q>dk}H%zKOk4wCtg?JeuZUx;$N2G#PV| zzxGN1F3OG=OU@UuBb+a?v5wbCS=Y0# z8%;ShLZRE=B8@3`*ELL!mkZ2Prgtz~DI;)WzbLzqKeq|#j$O!~;gnt25zT+)Zld%{ zmi)_gX;-!^v3vF=xxD#Gv}CCB=6fK-RLNCmhN8D9l^kO^qeyd^h&_WyJzw&im-Z`y zyD|f}?mTm43=3gnRJ4~uL~3WM1#nb5e9|e>-p+)+%Cb#r4GH#7r?=A&=aJfUA)5we z^Vv)Rd<%lw77Ojzp&W_En$hy7+N;*~h-*M(&RQFRSEwySoi? zx@}JK4~R(Y(|1UQtvo;dmK*(t+KF|o0fL~eomiVBzLv$*Y(5*syHNPIRqg{bw!z1_ zj?^NWqGT44eHZWk;icpjB}%zsWzP6PLt@7vujpicVb+Oi<$=%j*5wz}sNrdXHEMrr z0Dqe}K2coE5_wF~(E-ty<|5sE1b_4+mc`Mr*&qL=6kRjsW>RE^Bc+IDI}(aKb@ll~ z=Rv)Th+LwfLlb6udM50@bSd)yFrB}4B7IHzty^B{Opg?zq`rL--_*O&(b?i67O#Z+ z8`6l-eQ`KX4wU6SuVoR{ZdS60KGs#Ersq`>5lwd_^x%bOJbfy{fV0slwdP_t(t()2 z97_IbO$drV?43mUkX1UQuAL&U7Rd)x_Typb+l*$5Sd!yCgijZloz7a`|PHKy6$^t^x$6*Ru8fVmnZCxOTD_gJMp zYI)fR(E;1aTD=0rZsmY;bsOviT+CPalN?9e%>mg;=Zi2{hLwUboV96PxKP{Cs;Yep zXa!ZKoT?gAtdCb@td~z@PK|dBqF)FaGAsp6KDH)dDd6(Yk zZpDf=lmY{TpM(8t9&BdEI0pYbn#!Yl*3Gf9DBvCY`wfrWzRGF#u_vm_RBbg6*3(Y} zUuY`JR^fLnl7MM9g z^BliVGg(?JP4{9`RhogD+531jcFtS-msLTN7?`xOSKAB;z}#wgpQwu^CB}=G$FLAL z{3yUKz4iEyX9>X%}D2_6f#mCY_ZS^AT80?M}L*mv^<8I5zQ>H6BY zXff7AGi?&PfWFf-8k0zlrEy-kZ3~{;%JU3u^d2mcGj_-!ucB7Ee3NRL3EDzy4YVOyC2=W8IKgjwDZT9u1BBXhR z>Z)OyS7@^uz2^BUwi_O%iixa!Pv!$aHdJcuAeVyk&t1=Vq!xpy?c#l~gM4-|xBK)C z2V|?45WQ9UqRb3vS_3;uq{XZY>f%1Y>|mxuV&AlIyuAwXxR$Z4pM?eBDF&G z+*sA1NuItV6pa2-^n4ww_T>-@Q_&_L82vfu;k+~aLR94yj>k5~cs-vEa=HhRCctMM zY*kjqLnkL&rDUuIJ1d_Se-ffV&W3nN05H{9JO9IGbNOK&r-+f#A!a`|-myw=W0e3` z?^qxjUV!E)dzEQrRrvGa4L3C}aVjhnAk-f@9>I+p3LZg{rzcjT9xAt75vsoe{Nb+% zm4gav?DUJ=Oe~OXgXw$q7d@CJfOTKCrxu-7&)z)eLCs^R_3}MAFfO++(e}lCXO3z) z(NvL7`xFigmYlLvmIDf={|fu=+KED~3w;9~IIuE!aOl>*JOJ2O;h`mX;Oe6QvUgw% zMiiS^cSE3w8+GJjlJ7=ROE!^*qvcSYgvy2qXrs8(LYYdto5%NsX#J_E$LEkVo<^-* z(^!l04v$8kG__&xW_KoU>ZnCyzJ1=J<}vF=wT8NPu$@(!+tdv)tY8zR=D##yI4k8T z9d0D4NP1_k?zk^CmC6M6jwdgB8K*xQ_56^fH1(0|p}xiaAI)->o3dWD*xS$Tlj#L- z5$MXBa;I47i`t8bl1sDlNkosSq1Lq+7&R`>r6RUk=>f$L=rY{=iM#G(Y z3?35}S}^AR{esiQ*9V{O;ihRBewc#Apdh)GpmBD;N0LYr4DtvoML1f*P`n8T!3}$~ z02%$KkyI$Pg)IQw=3~Buj;X>p{gJ2_hb$$jk6jOW77u(d6HNvivENx+>7c-Weu;FK z-)HilRszI?w1T%qh{}DIeJhu~%`btZqRM`=Q64TM^uo9z#nufFSnCw8`!BWI>ZS@y z)J*8pfwe^+JCrHyFTa|4&-Ji>X~eVn&Vf3%hwbF0XY*up%s)Em)4nJ?`#`#%3&e4Z z^|4(LX@o(ZY^AY$D$%dHzo2mMx``*;=Gc~(Uaar@a%>T(4+N}M3Tu7X>po(^8)>vj zUKUB?KTtE5zU`TIvOX0_+6QdcQt!JS_AQNg3aOW|9iry_Md$)^aMu5Jfe|qz?UNdl zl293IgcR@c=3`|)VYDDL#zR3~q(VWUdLG3C9?y1$ z^w=h*=b+@V^`PV!BZ~?EN)DmhW9R|@1RA+i>9n+hfBF$$L#MxV^n1Pq8NZx>ie8j+C88?U(Me3U`?5JqW*9sHA=M{&AK$!uqGWi@CDwnFYo zPEuFitgEX^a|SMXAbTd|&@<#0tWa99l!+J|Tue2{E37pCBc1d^J~^5BUbEJHAvkuL zh)MepGLN)-X^dH37D40r)V;9l+9^84r~btCaNpvAk7qf5GF%K?#sS9L_u_y%aPYO; zsfGC>KsY;73#jUneR&E9r`ui9@Fp$gB7JX=5f4sdI|XTP!3~h#T-wh@-<5s-`{&Ar zuew3m;!8!shdr+kcrxpdv5n@6qS%c{P{c7$;Yh_fvcJ(8eLjQ6*S;g1K(lXe-kb$( zqNSvRtZZ!C?zkqjKkTrvCN2x4xGXJ zvTWp-IZkmMJCGC4F^{5V+0UP`X4xne!`PHcH#tIyoNA@jYMyBAIzWfO1MMrQwnt(` zK)fSX6=`48$z-yNqr5&QVL_9)^}a+gRl zOjI*f6mw$282!=cnnO94ldD|!gk{87XF0Q#9MeLUHn6Xj>a3I@KT;tFr&?qySTkA_ zDsL#J&!`#usuV61EO}`r8lZsUGV74ix_AKzdv(%#B7UH})b1P1cH)OfqhrAq|#HiaxazvJq`lB&bhjOncSGp#LW<=TMI3qyWiS4U>7Z7xJvdfLM z#tiTjp}P(Q&T;}%OQl7@Yyt?xgvuj8;BC}_vT)Y)aMUgPXrUvp-_({#v+K>?H1tZ6hC-)Q~un99`b%gGg7e6iL!&Iki`W1Tp5OB}FUFhnI4 zI-pzfIBse)fV#^oifIuh@Nud14=mC+fkNq5<*Zq3jZ&yLiU`!95mrCRP=1S21vW$AM!RRdv`EKL#JzXkQ2eS|G8#6=YReS+0VLFE(jyEte zK@mhVCX7-9k#l7amM<(l){1>__Ze{Yo(3$WZ-hs#7rN5hgGu`y%GS`t&ubg&d>^~k zMcQe;Y2vgOlv2OqwH&JDF6i$R9pc%9W-p*W4f!*ienkWQw0i9cm;(9`#1$_8(2O`v z_8P4lC8|H#k7%!Q31+K!}YAn8~p*|5UIs6A&14U}HXI$lClZ zALf_&UjuBJM!GM==+8z!JX=NT!}N~p5g1?{ACEp>Z-Dtw2QAE>UCYIMT>Pvf&YwDs zmC98(Q#$6Wl#eDjOtB>1TjjTZt+81e3+@PUt`0U+V_0Ji_X4)}^Hf-4kJAV zK#c*#@$Z6eLcq01hp8q89njU=Y6Jg&u+`lEwbh)Q>3!*KrDH=&NB5KAR>p8JLl2Y(^+wRWe~lm- zZI<7QpmG1FC4^;vWeMF6|359E2d^xl=PT@y$g(u^d(P3vW4qGF!^S??a2?N7b1hM`wqxlr9!bOh|GST$u8_Q_mNWRQ5kp9r zU(2&~n!77VM18-GiJU$9$NYuveElU_Ld_2fF}E+)U!v|gzPLo;k7>+~OO(>t_ae;P z=4`B5LdMejtT{~ysl8f4C-K=$ew`}&08L-aTVK207+P&yN8%F>j4o=PLe-4TS1!7N z_{68-qU(qD()AZzZo@?vU4PMy!j`N$oO=ytcXCKZv<+)hhKp|RzZabsv~ZR5IX3EM zG~sX&JF#X@)hvY5dPBMMTv)T`|6X}7HnXOOqHg2L>k!f9)s<)FSKdHed2?}*ZpNLb zR_;8_%kz#)PwH=8tZPjBt@H>1>i^n%i8RS9e;Pp(JF1wsI}2s+#K2d4asfxxA!-9( zv1O(Eqfw{xa8%`VAb;wvrAMddJ3h`^uf{L>TnjVR=9MB`xN(kG}DN(B6Cc~?p~Ju0jY{)K8pK9hrKtusPR-tB2_o+J zchbC{QX~6U0(0&IL!k8peOmPMgVs`bTZg<$20fn3y{(l95j>E-qPg<5Xq5WBhGMJq zUC87pw)CC31~mOkQ*A$&UZ~w5aKGxh1Pwa&m}!o9J$=cEs1+jP8;IO@5SfF6k!|GO z6iuV4_Im^uCst(BAdbnMPNcmh@Y>nKWTR7KZZD` zmwnB}8B_+7u~hL{U&(J@gZySge%3=zU&+r78aPyfSgZpE7Qb4CGo?%=t&~i>|H7al zp!JDO+5%b#ccaK;0FrL*gWP<}#~|nMt3a=Zs3~1hPf)Gh+CcCD-mK^2u&q4x8DEKh%1TUN6#xfKH5#pls4ca%BJag8otM*Yb>Mcl zZ%^ttN5_He7cZDPTj@72%tX7*53n2utdAYd1~kvX%>#v-_kp*I&M%ys$*-ict3fIY z8g}tm#mKPQ6unTE25?V*GxyrFf`=dhTcZcY|DyC3Ee|PqQmVO61$H-)e9Ut12nr2U zF~cC{&)yE#pNXrvWPF}XZ@DHjRZh>Uk!O(I(XudtJjg>!Uk?_sUAsl7FhDnXa*4et zL`4ys>#_xI4;|y}a&huMKV4aJOF`(Df}|SEqAgolB5e#|Gu2USR+#Qo%!`NGGt|c{ zcZeXvC<+#$tT=U6vF-{W|91)?e+~!aN8T;k4IWnxoG%rP<#)h~(-kFmOEpv{0x7># zCBG|$f{2z?m)PG3VIQia*;G;Uh&i2%e*Q>%j{2JAj-WI0xllgKSwpxtj)^p%_m`vg zI)2<+jr6^#41+JS#FoB1Sy^%$rhk-H_T&!x=RFW!qf-@#8ju|T;5}I-5Z`6RgSx*mY@Ai#5;IBn+9~tH26FQ zhtD&_NQdivo>&$s+~J6pc6TXQdZ-j$ZN{utlt@2@uqkjAXN2iaa?zb=AUXcIV8fK8 z^QxTds+-NlZd#NC|Qr?8q%CpcW3)05!hSQ6mk0ES=MV7{&B z!i!U5VKN2Te&j1w%|-ec*_L;(W-3ng8Hg?}k=BK(#`>Sg|MiL^e1O@|z2hJmG*58-X~G07cZLU3;@ zs#-Tfe=N58P{I} zcX2n*lCMRnBXBqS;%;8d@8-Hq0wv{_nNkW`(FDt9>=z-Z450#()Qaf@_AP5IN`Wj| z4paq3iuk;Y%#QmmUu3ukYuyA#&wpHX{mIu{VmjJz*$w%Jy7T+ab{_X#2N5rU?A>GD z)C5|R!l%9jhw2O*@gA%hkE1JxD&pwy+;G)dMU8DUt~#f>rGn<{d1?~KUf`B{q1K#5 zJ7)0J4GhqsONFU!1aYkH#*9SbtQU8c~PY{E~%Ylw4Uxd9% zK=);Nwh&u2H!V|lIP%VIWfM%urGBPzaH8CN%6fIkUqb8P^;3tK8R(OIX*L>p%CJ8*;2 z1vMVdg({w6@kf;f=R%dmVsQsv$7iUlawRG9uu zY)!iHSu(jO*Hn+H5ofY-O%+9uCwXe=o1b8jv)0%aj9N1%75^f_@x`-ZdlBlJhVVNp zEnmtpw~~A-0<4+>($Gnf+U`awS30#!XKzslZ_+K=XKJIVU>@697`;Uu5nVrHt__Ny zGl;Htgnj-t>$_O5DUf=z^~#+xUv5(S9|0%?HD+vWnuXzeyy(Si%MlY1r3oT+-9WCU zGY`*nBW)yg{cty8F{R9F1M5`!?c>@?;ai|`1~ZQjosYp;kPfotRytnWScTt~2yv*R z)YhPe``;EAkzIIs!|$LoPf17g#OVT3h$6U3A@g)wsLkcm&rWxwHUp^hvSdud!n`-L z&NYate9uM;tJJuxI(sqi<$6L>UlBMp$U($!|3Rgq<|K6ool@2v;IJJ8VDx2MbFP>o zVK^otDX(`Kg;S$mye=8O47o@vMC$n$>9bDVJKd9X@zmp!9XV|{x=5ctSf|1-ZaP!4 zv9?zfC9A#wGWHdC;$-A2+WQE6oK4aI1SikKAy?x|*0?TJ0cWkrC<8bv zr#?`j-o6+KjLWG}PwU4;)U`-+1kjQaQqOw)t#EM4!NJEUWY!$n&iekrIw~COG1m5o zqCK30P7V%SWY`JIjIi6sax~Q$L2MeEPWk9wV5A!Q0BglQWL^2A2pv&zGEdnNwdTk# zf0LW2Is6Nv7yK*M#DNIvZM+Q@htjONJ_7aQiyl{&prd!BnHcCF(wfdZIMbakdbf{u z8{3T3G0%Tkr|Y#%1=cZ)d41$eZRKVhCc~SCd zN4>G;i8L8&-WLhb%0djb;HO(j3q|S-&kbR3h&a zjg{F(#1b8E4#KcC^R7IJ4mSeYU$FwHWTtSn< zJpX2$iobpc)&05~>m0^BK62LVMucMr9TdnV_dH>3x34C&ewjwCA+YVNHFUQn2cd}0 zy^4WH(oD>xr;Wmujbc+|Hi^s3eobf))!(m)>SJe;d2_E0hJBeC)_v50qg*8_2v=^j zS^=pT)~ze4haoNc;-iNSY^wxa8o6U$qB1WLvZNSO1q2z7Ct=4X)m#DL*$s>Ljpko7lTW%N{vvu6#qlK}(|+ zm@%48%8hED2oz|fH!G<~fS9w9S@Be%E^!d!$-d%o2 zH1e^3Lr3`{gCF}Xihfc#va`E>v?~tT*)sCkJN(1M%gZXASJHY>bBJ65)S4pZ!s;UJ z=S*ss;7jyY#<5�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 literal 0 HcmV?d00001 diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 1b7eff4604f5f..5faa8a7830cf6 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -66,6 +66,14 @@ font-display: swap; } +/* Avoid legacy CJK fonts in Windows */ +@font-face { + font-family: 'Noto Sans KR'; + src: url("noto-sans-kr-v13-korean-regular.woff") format("woff"); + font-display: swap; + unicode-range: U+A960-A97F, U+AC00-D7AF, U+D7B0-D7FF; +} + * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; @@ -90,7 +98,7 @@ html { /* General structure and fonts */ body { - font: 16px/1.4 "Source Serif 4", serif; + font: 16px/1.4 "Source Serif 4", "Noto Sans KR", serif; margin: 0; position: relative; padding: 10px 15px 20px 15px; From 7e2e331d658d719a76fd53a9d9cf1c4bf89a6982 Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Sat, 15 May 2021 14:31:54 +0900 Subject: [PATCH 06/70] rustdoc: add the license of Noto Sans KR --- ...oto-sans-kr-v13-korean-regular-LICENSE.txt | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/librustdoc/html/static/noto-sans-kr-v13-korean-regular-LICENSE.txt diff --git a/src/librustdoc/html/static/noto-sans-kr-v13-korean-regular-LICENSE.txt b/src/librustdoc/html/static/noto-sans-kr-v13-korean-regular-LICENSE.txt new file mode 100644 index 0000000000000..922d5fdc18dc9 --- /dev/null +++ b/src/librustdoc/html/static/noto-sans-kr-v13-korean-regular-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2014, 2015 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. From b5e09dc7a3ab4a5e81f850a529ad9adba16b3925 Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Sat, 15 May 2021 14:54:49 +0900 Subject: [PATCH 07/70] rustdoc: update static files --- src/librustdoc/html/render/write_shared.rs | 2 ++ src/librustdoc/html/static_files.rs | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index d0518cb6862fe..97514917c9fdf 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -33,6 +33,8 @@ crate static FILES_UNVERSIONED: Lazy> = Lazy::new(|| { "SourceCodePro-Semibold.ttf.woff" => static_files::source_code_pro::SEMIBOLD, "SourceCodePro-It.ttf.woff" => static_files::source_code_pro::ITALIC, "SourceCodePro-LICENSE.txt" => static_files::source_code_pro::LICENSE, + "noto-sans-kr-v13-korean-regular.woff" => static_files::noto_sans_kr::REGULAR, + "noto-sans-kr-v13-korean-regular-LICENSE.txt" => static_files::noto_sans_kr::LICENSE, "LICENSE-MIT.txt" => static_files::LICENSE_MIT, "LICENSE-APACHE.txt" => static_files::LICENSE_APACHE, "COPYRIGHT.txt" => static_files::COPYRIGHT, diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 1abb1f7294a18..c44976f4790d2 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -126,6 +126,14 @@ crate mod source_code_pro { crate static LICENSE: &[u8] = include_bytes!("static/SourceCodePro-LICENSE.txt"); } +crate mod noto_sans_kr { + /// The file `noto-sans-kr-v13-korean-regular.woff`, the Regular variant of the Noto Sans KR font. + crate static REGULAR: &[u8] = include_bytes!("static/noto-sans-kr-v13-korean-regular.woff"); + + /// The file `noto-sans-kr-v13-korean-regular-LICENSE.txt`, the license text of the Noto Sans KR font. + crate static LICENSE: &[u8] = include_bytes!("static/noto-sans-kr-v13-korean-regular-LICENSE.txt"); +} + /// Files related to the sidebar in rustdoc sources. crate mod sidebar { /// File script to handle sidebar. From fe44fde3ef7743e5af17d3a605fca062536c4b41 Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Sat, 15 May 2021 15:46:44 +0900 Subject: [PATCH 08/70] chore: format code --- src/librustdoc/html/static_files.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index c44976f4790d2..ca7e5ef815080 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -127,11 +127,14 @@ crate mod source_code_pro { } crate mod noto_sans_kr { - /// The file `noto-sans-kr-v13-korean-regular.woff`, the Regular variant of the Noto Sans KR font. + /// The file `noto-sans-kr-v13-korean-regular.woff`, the Regular variant of the Noto Sans KR + /// font. crate static REGULAR: &[u8] = include_bytes!("static/noto-sans-kr-v13-korean-regular.woff"); - /// The file `noto-sans-kr-v13-korean-regular-LICENSE.txt`, the license text of the Noto Sans KR font. - crate static LICENSE: &[u8] = include_bytes!("static/noto-sans-kr-v13-korean-regular-LICENSE.txt"); + /// The file `noto-sans-kr-v13-korean-regular-LICENSE.txt`, the license text of the Noto Sans KR + /// font. + crate static LICENSE: &[u8] = + include_bytes!("static/noto-sans-kr-v13-korean-regular-LICENSE.txt"); } /// Files related to the sidebar in rustdoc sources. From 6b601d492df12238fa5513f389d744803e85326e Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Sat, 15 May 2021 20:04:38 +0900 Subject: [PATCH 09/70] chore: update comment in rustdoc.css --- src/librustdoc/html/static/rustdoc.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 5faa8a7830cf6..b6e347d35d5d1 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -66,7 +66,7 @@ font-display: swap; } -/* Avoid legacy CJK fonts in Windows */ +/* Avoid using legacy CJK serif fonts in Windows like Batang */ @font-face { font-family: 'Noto Sans KR'; src: url("noto-sans-kr-v13-korean-regular.woff") format("woff"); From 8412d306e679d807430821886a12a987c71d924f Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Tue, 18 May 2021 21:31:36 +0900 Subject: [PATCH 10/70] test: update unversioned-files.txt --- .../print-unversioned-files/unversioned-files.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt b/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt index 4b20cd5d7453e..e7e7bbfcc9ef1 100644 --- a/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt +++ b/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt @@ -14,3 +14,5 @@ SourceSerif4-Bold.ttf.woff SourceSerif4-It.ttf.woff SourceSerif4-LICENSE.md SourceSerif4-Regular.ttf.woff +noto-sans-kr-v13-korean-regular.woff +noto-sans-kr-v13-korean-regular-LICENSE.txt From 8a2d66337e49d5b8e60911cb34c9e15f5123488f Mon Sep 17 00:00:00 2001 From: Shinwoo Park Date: Wed, 19 May 2021 12:43:06 +0900 Subject: [PATCH 11/70] test: fix the order in unversioned-files.txt --- .../print-unversioned-files/unversioned-files.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt b/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt index e7e7bbfcc9ef1..348cd1fdf37b3 100644 --- a/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt +++ b/src/test/run-make-fulldeps/print-unversioned-files/unversioned-files.txt @@ -14,5 +14,5 @@ SourceSerif4-Bold.ttf.woff SourceSerif4-It.ttf.woff SourceSerif4-LICENSE.md SourceSerif4-Regular.ttf.woff -noto-sans-kr-v13-korean-regular.woff noto-sans-kr-v13-korean-regular-LICENSE.txt +noto-sans-kr-v13-korean-regular.woff From f749d88ae7574aa18aa527ad4d6345e98ea00a82 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Wed, 19 May 2021 18:51:42 +0200 Subject: [PATCH 12/70] Disallow shadowing const parameters --- compiler/rustc_resolve/src/diagnostics.rs | 23 ++++++++------ compiler/rustc_resolve/src/late.rs | 30 +++++++++++++++---- compiler/rustc_resolve/src/lib.rs | 9 +++++- src/test/ui/resolve/issue-85348.rs | 12 ++++++++ src/test/ui/resolve/issue-85348.stderr | 25 ++++++++++++++++ src/test/ui/resolve/shadow-const-param.rs | 20 +++++++++++++ src/test/ui/resolve/shadow-const-param.stderr | 20 +++++++++++++ 7 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 src/test/ui/resolve/issue-85348.rs create mode 100644 src/test/ui/resolve/issue-85348.stderr create mode 100644 src/test/ui/resolve/shadow-const-param.rs create mode 100644 src/test/ui/resolve/shadow-const-param.stderr diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 6ea46f5c5289e..a1eafd65d643d 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -425,24 +425,29 @@ impl<'a> Resolver<'a> { } err } - ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => { - let res = binding.res(); - let shadows_what = res.descr(); + ResolutionError::BindingShadowsSomethingUnacceptable { + shadowing_binding_descr, + name, + participle, + article, + shadowed_binding_descr, + shadowed_binding_span, + } => { let mut err = struct_span_err!( self.session, span, E0530, "{}s cannot shadow {}s", - what_binding, - shadows_what + shadowing_binding_descr, + shadowed_binding_descr, ); err.span_label( span, - format!("cannot be named the same as {} {}", res.article(), shadows_what), + format!("cannot be named the same as {} {}", article, shadowed_binding_descr), ); - let participle = if binding.is_import() { "imported" } else { "defined" }; - let msg = format!("the {} `{}` is {} here", shadows_what, name, participle); - err.span_label(binding.span, msg); + let msg = + format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle); + err.span_label(shadowed_binding_span, msg); err } ResolutionError::ForwardDeclaredTyParam => { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ffa825b7d46a3..662d39f6ef39c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1763,13 +1763,33 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // to something unusable as a pattern (e.g., constructor function), // but we still conservatively report an error, see // issues/33118#issuecomment-233962221 for one reason why. + let binding = binding.expect("no binding for a ctor or static"); self.report_error( ident.span, - ResolutionError::BindingShadowsSomethingUnacceptable( - pat_src.descr(), - ident.name, - binding.expect("no binding for a ctor or static"), - ), + ResolutionError::BindingShadowsSomethingUnacceptable { + shadowing_binding_descr: pat_src.descr(), + name: ident.name, + participle: if binding.is_import() { "imported" } else { "defined" }, + article: binding.res().article(), + shadowed_binding_descr: binding.res().descr(), + shadowed_binding_span: binding.span, + }, + ); + None + } + Res::Def(DefKind::ConstParam, def_id) => { + // Same as for DefKind::Const above, but here, `binding` is `None`, so we + // have to construct the error differently + self.report_error( + ident.span, + ResolutionError::BindingShadowsSomethingUnacceptable { + shadowing_binding_descr: pat_src.descr(), + name: ident.name, + participle: "defined", + article: res.article(), + shadowed_binding_descr: res.descr(), + shadowed_binding_span: self.r.opt_span(def_id).expect("const parameter defined outside of local crate"), + } ); None } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 300d2c01cb5d0..05c698925041b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -234,7 +234,14 @@ enum ResolutionError<'a> { /* current */ &'static str, ), /// Error E0530: `X` bindings cannot shadow `Y`s. - BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>), + BindingShadowsSomethingUnacceptable { + shadowing_binding_descr: &'static str, + name: Symbol, + participle: &'static str, + article: &'static str, + shadowed_binding_descr: &'static str, + shadowed_binding_span: Span, + }, /// Error E0128: generic parameters with a default cannot use forward-declared identifiers. ForwardDeclaredTyParam, // FIXME(const_generics_defaults) /// ERROR E0770: the type of const parameters must not depend on other generic parameters. diff --git a/src/test/ui/resolve/issue-85348.rs b/src/test/ui/resolve/issue-85348.rs new file mode 100644 index 0000000000000..3a33c19340841 --- /dev/null +++ b/src/test/ui/resolve/issue-85348.rs @@ -0,0 +1,12 @@ +// Checks whether shadowing a const parameter leads to an ICE (#85348). + +impl ArrayWindowsExample { +//~^ ERROR: cannot find type `ArrayWindowsExample` in this scope [E0412] + fn next() { + let mut N; + //~^ ERROR: let bindings cannot shadow const parameters [E0530] + //~| ERROR: type annotations needed [E0282] + } +} + +fn main() {} diff --git a/src/test/ui/resolve/issue-85348.stderr b/src/test/ui/resolve/issue-85348.stderr new file mode 100644 index 0000000000000..f475c26f32b8f --- /dev/null +++ b/src/test/ui/resolve/issue-85348.stderr @@ -0,0 +1,25 @@ +error[E0530]: let bindings cannot shadow const parameters + --> $DIR/issue-85348.rs:6:17 + | +LL | impl ArrayWindowsExample { + | - the const parameter `N` is defined here +... +LL | let mut N; + | ^ cannot be named the same as a const parameter + +error[E0412]: cannot find type `ArrayWindowsExample` in this scope + --> $DIR/issue-85348.rs:3:22 + | +LL | impl ArrayWindowsExample { + | ^^^^^^^^^^^^^^^^^^^ not found in this scope + +error[E0282]: type annotations needed + --> $DIR/issue-85348.rs:6:13 + | +LL | let mut N; + | ^^^^^ consider giving `N` a type + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0412, E0530. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/resolve/shadow-const-param.rs b/src/test/ui/resolve/shadow-const-param.rs new file mode 100644 index 0000000000000..c435c16dc6788 --- /dev/null +++ b/src/test/ui/resolve/shadow-const-param.rs @@ -0,0 +1,20 @@ +// Checks that const parameters cannot be shadowed with fresh bindings +// even in syntactically unambiguous contexts. See +// https://github.com/rust-lang/rust/issues/33118#issuecomment-233962221 + +fn foo(i: i32) -> bool { + match i { + N @ _ => true, + //~^ ERROR: match bindings cannot shadow const parameters [E0530] + } +} + +fn bar(i: i32) -> bool { + let N @ _ = 0; + //~^ ERROR: let bindings cannot shadow const parameters [E0530] + match i { + N @ _ => true, + } +} + +fn main() {} diff --git a/src/test/ui/resolve/shadow-const-param.stderr b/src/test/ui/resolve/shadow-const-param.stderr new file mode 100644 index 0000000000000..fbd0d81100082 --- /dev/null +++ b/src/test/ui/resolve/shadow-const-param.stderr @@ -0,0 +1,20 @@ +error[E0530]: match bindings cannot shadow const parameters + --> $DIR/shadow-const-param.rs:7:9 + | +LL | fn foo(i: i32) -> bool { + | - the const parameter `N` is defined here +LL | match i { +LL | N @ _ => true, + | ^ cannot be named the same as a const parameter + +error[E0530]: let bindings cannot shadow const parameters + --> $DIR/shadow-const-param.rs:13:9 + | +LL | fn bar(i: i32) -> bool { + | - the const parameter `N` is defined here +LL | let N @ _ = 0; + | ^ cannot be named the same as a const parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0530`. From e5873660fc872f92e904bac385645750eb4f84c4 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Thu, 20 May 2021 17:15:39 -0500 Subject: [PATCH 13/70] doc: clarify Mutex::try_lock, etc. errors Clarify error returns from Mutex::try_lock, RwLock::try_read, RwLock::try_write to make it more obvious that both poisoning and the lock being already locked are possible errors. --- library/std/src/sync/mutex.rs | 10 ++++++++-- library/std/src/sync/rwlock.rs | 27 ++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index 773ab18b2ce65..5ebb87792f2a2 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -294,8 +294,14 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return an error if the mutex would otherwise be - /// acquired. + /// this call will return the error [`Poisoned`] if the mutex would + /// otherwise be acquired. + /// + /// If the mutex could not be acquired because it is already locked, then + /// this call will return [`WouldBlock`]. + /// + /// [`Poisoned`]: TryLockError::Poisoned + /// [`WouldBlock`]: TryLockError::WouldBlock /// /// # Examples /// diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index b01bcec1361d7..161d2789c27ef 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -199,11 +199,17 @@ impl RwLock { /// /// # Errors /// - /// This function will return an error if the RwLock is poisoned. An RwLock - /// is poisoned whenever a writer panics while holding an exclusive lock. An - /// error will only be returned if the lock would have otherwise been + /// This function will return the error [`Poisoned`] if the RwLock is poisoned. + /// An RwLock is poisoned whenever a writer panics while holding an exclusive + /// lock. `Poisoned` will only be returned if the lock would have otherwise been /// acquired. /// + /// This function will return the error [`WouldBlock`] if the RwLock could not + /// be acquired because it was already locked exclusively. + /// + /// [`Poisoned`]: TryLockError::Poisoned + /// [`WouldBlock`]: TryLockError::WouldBlock + /// /// # Examples /// /// ``` @@ -281,10 +287,17 @@ impl RwLock { /// /// # Errors /// - /// This function will return an error if the RwLock is poisoned. An RwLock - /// is poisoned whenever a writer panics while holding an exclusive lock. An - /// error will only be returned if the lock would have otherwise been - /// acquired. + /// This function will return the error [`Poisoned`] if the RwLock is + /// poisoned. An RwLock is poisoned whenever a writer panics while holding + /// an exclusive lock. `Poisoned` will only be returned if the lock would have + /// otherwise been acquired. + /// + /// This function will return the error [`WouldBlock`] if the RwLock could not + /// be acquired because it was already locked exclusively. + /// + /// [`Poisoned`]: TryLockError::Poisoned + /// [`WouldBlock`]: TryLockError::WouldBlock + /// /// /// # Examples /// From c441675edf501c63c892a381fd4842042c3cd663 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 20 May 2021 19:40:48 -0700 Subject: [PATCH 14/70] Add Weak may_dangle tests --- library/alloc/tests/arc.rs | 15 +++++++++++++++ library/alloc/tests/rc.rs | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/library/alloc/tests/arc.rs b/library/alloc/tests/arc.rs index c02ba267056d6..ce40b5c9b0a0d 100644 --- a/library/alloc/tests/arc.rs +++ b/library/alloc/tests/arc.rs @@ -195,3 +195,18 @@ fn shared_from_iter_trustedlen_no_fuse() { assert_trusted_len(&iter); assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::>()); } + +#[test] +fn weak_may_dangle() { + fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> { + val.clone() + } + + // Without #[may_dangle] we get: + let mut val = Weak::new(); + hmm(&mut val); + // ~~~~~~~~ borrowed value does not live long enough + // + // `val` dropped here while still borrowed + // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak` +} diff --git a/library/alloc/tests/rc.rs b/library/alloc/tests/rc.rs index 501b4f0f816be..efb39a609665b 100644 --- a/library/alloc/tests/rc.rs +++ b/library/alloc/tests/rc.rs @@ -191,3 +191,18 @@ fn shared_from_iter_trustedlen_no_fuse() { assert_trusted_len(&iter); assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::>()); } + +#[test] +fn weak_may_dangle() { + fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> { + val.clone() + } + + // Without #[may_dangle] we get: + let mut val = Weak::new(); + hmm(&mut val); + // ~~~~~~~~ borrowed value does not live long enough + // + // `val` dropped here while still borrowed + // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::rc::Weak` +} From 23a4050f7dbc8675df6305b9968a3d5648518ff4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 20 May 2021 19:43:41 -0700 Subject: [PATCH 15/70] Weak's type parameter may dangle on drop --- library/alloc/src/rc.rs | 2 +- library/alloc/src/sync.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 800952f7a5ece..f19a13c8defef 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2303,7 +2303,7 @@ impl Weak { } #[stable(feature = "rc_weak", since = "1.4.0")] -impl Drop for Weak { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak { /// Drops the `Weak` pointer. /// /// # Examples diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 17927f5f5fdc4..02a739309cde0 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2015,7 +2015,7 @@ impl Default for Weak { } #[stable(feature = "arc_weak", since = "1.4.0")] -impl Drop for Weak { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak { /// Drops the `Weak` pointer. /// /// # Examples From 6efa14b3add08188c5322db8694a8cbbea7851e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Fri, 21 May 2021 14:01:38 +0200 Subject: [PATCH 16/70] remove generic argument insead of displaying "_" --- .../rustc_typeck/src/check/method/suggest.rs | 16 +------------ src/test/ui/auto-ref-slice-plus-ref.stderr | 4 ++-- src/test/ui/class-cast-to-trait.stderr | 2 +- .../issue-18343.stderr | 2 +- .../issue-2392.stderr | 12 +++++----- .../no-method-suggested-traits.stderr | 24 +++++++++---------- src/test/ui/issues/issue-41880.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 10 ++++---- ...ethod-not-found-generic-arg-elision.stderr | 10 ++++---- src/test/ui/object-pointer-types.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 +- 11 files changed, 36 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 54a1078383fcb..f46d4205a6bd5 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -13,7 +13,6 @@ use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::fast_reject::simplify_type; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; @@ -411,20 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .sum(); if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { if let Some((path_string, _)) = ty_str.split_once('<') { - ty_str_reported = format!("{}<", path_string); - for (index, arg) in generics.iter().enumerate() { - let arg_replace = match arg.unpack() { - GenericArgKind::Lifetime(_) => "'_", - GenericArgKind::Type(_) - | GenericArgKind::Const(_) => "_", - }; - ty_str_reported = - format!("{}{}", ty_str_reported, arg_replace); - if index < generics.len() - 1 { - ty_str_reported = format!("{}, ", ty_str_reported); - } - } - ty_str_reported = format!("{}>", ty_str_reported); + ty_str_reported = path_string.to_string(); } } } diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index be1b79e936d24..7203d3ed30e93 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it LL | trait MyIter { | ^^^^^^^^^^^^ -error[E0599]: no method named `test` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `test` found for struct `Vec` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index c01af6d7e2561..a1a3ead581265 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for struct `Box<_, _>` in the current scope +error[E0599]: no method named `eat` found for struct `Box` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr index 2bf32975a6f45..fe6b12968c110 100644 --- a/src/test/ui/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-18343.rs:7:7 | LL | struct Obj where F: FnMut() -> u32 { diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr index f17a56eba2f7a..0480958e99c05 100644 --- a/src/test/ui/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:36:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -12,7 +12,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (o_closure.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:38:15 | LL | struct Obj where F: FnOnce() -> u32 { @@ -23,7 +23,7 @@ LL | o_closure.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:42:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -65,7 +65,7 @@ help: to call the function stored in `boxed_closure`, surround the field access LL | (boxed_closure.boxed_closure)(); | ^ ^ -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:53:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p LL | (w.wrap.closure)(); | ^ ^ -error[E0599]: no method named `not_closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `not_closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:55:12 | LL | struct Obj where F: FnOnce() -> u32 { @@ -90,7 +90,7 @@ LL | w.wrap.not_closure(); | | | field, not a method -error[E0599]: no method named `closure` found for struct `Obj<_>` in the current scope +error[E0599]: no method named `closure` found for struct `Obj` in the current scope --> $DIR/issue-2392.rs:58:24 | LL | struct Obj where F: FnOnce() -> u32 { diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 5c0f945140a01..5507406b0f502 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -98,7 +98,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `Reexported` -error[E0599]: no method named `method` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method2` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -202,7 +202,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -225,7 +225,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for struct `Rc<_>` in the current scope +error[E0599]: no method named `method3` found for struct `Rc` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr index f9d11c47687b9..017dd831f712a 100644 --- a/src/test/ui/issues/issue-41880.stderr +++ b/src/test/ui/issues/issue-41880.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `iter` found for struct `Iterate<_, _>` in the current scope +error[E0599]: no method named `iter` found for struct `Iterate` in the current scope --> $DIR/issue-41880.rs:27:24 | LL | pub struct Iterate { diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 85ccb0bd0de2a..23f01fb861fdb 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -69,22 +69,22 @@ fn main() { let d = point_i32.distance(); //~^ ERROR no method named `distance` found for struct `Point let d = point_i32.other(); - //~^ ERROR no method named `other` found for struct `Point<_> + //~^ ERROR no method named `other` found for struct `Point let v = vec![1_i32, 2, 3]; v.iter().map(|x| x * x).extend(std::iter::once(100)); - //~^ ERROR no method named `extend` found for struct `Map<_, _> + //~^ ERROR no method named `extend` found for struct `Map let wrapper = Wrapper(true); wrapper.method(); //~^ ERROR no method named `method` found for struct `Wrapper wrapper.other(); - //~^ ERROR no method named `other` found for struct `Wrapper<_> + //~^ ERROR no method named `other` found for struct `Wrapper let boolean = true; let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; wrapper.method(); //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> wrapper.other(); - //~^ ERROR no method named `other` found for struct `Wrapper2<'_, _, _> + //~^ ERROR no method named `other` found for struct `Wrapper2 let a = vec![1, 2, 3]; a.not_found(); - //~^ ERROR no method named `not_found` found for struct `Vec<_, _> + //~^ ERROR no method named `not_found` found for struct `Vec } diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 80e111390c6ac..65dbabbc1430a 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -9,7 +9,7 @@ LL | let d = point_i32.distance(); | = note: The method was found for Point. -error[E0599]: no method named `other` found for struct `Point<_>` in the current scope +error[E0599]: no method named `other` found for struct `Point` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:71:23 | LL | struct Point { @@ -18,7 +18,7 @@ LL | struct Point { LL | let d = point_i32.other(); | ^^^^^ method not found in `Point` -error[E0599]: no method named `extend` found for struct `Map<_, _>` in the current scope +error[E0599]: no method named `extend` found for struct `Map` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:74:29 | LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); @@ -35,7 +35,7 @@ LL | wrapper.method(); | = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. -error[E0599]: no method named `other` found for struct `Wrapper<_>` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:79:13 | LL | struct Wrapper(T); @@ -55,7 +55,7 @@ LL | wrapper.method(); | = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. -error[E0599]: no method named `other` found for struct `Wrapper2<'_, _, _>` in the current scope +error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:85:13 | LL | struct Wrapper2<'a, T, const C: usize> { @@ -64,7 +64,7 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.other(); | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` -error[E0599]: no method named `not_found` found for struct `Vec<_, _>` in the current scope +error[E0599]: no method named `not_found` found for struct `Vec` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:88:7 | LL | a.not_found(); diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index fb3462b2cabd4..021899b3082cd 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box<_, _>` in the current scope +error[E0599]: no method named `managed` found for struct `Box` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr index 027d7a0e0e448..6b8ec47d98d81 100644 --- a/src/test/ui/resolve/issue-82865.stderr +++ b/src/test/ui/resolve/issue-82865.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: maybe a missing crate `x`? LL | use x::y::z; | ^ maybe a missing crate `x`? -error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope +error[E0599]: no function or associated item named `z` found for struct `Box` in the current scope --> $DIR/issue-82865.rs:8:10 | LL | Box::z From 1f130fbff8d32da093da8eca723323792a3a8554 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 21 May 2021 14:55:09 -0400 Subject: [PATCH 17/70] Revert portion of PR #83521 that injected issue #85435 (and thus exposed underlying issue #85561). --- .../src/build/expr/as_rvalue.rs | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 92a2a7bc17a8b..1345531f3c67a 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -185,21 +185,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // match x { _ => () } // fake read of `x` // }; // ``` - for (thir_place, cause, hir_id) in fake_reads.into_iter() { - let place_builder = - unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); - - if let Ok(place_builder_resolved) = - place_builder.try_upvars_resolved(this.tcx, this.typeck_results) - { - let mir_place = - place_builder_resolved.into_place(this.tcx, this.typeck_results); - this.cfg.push_fake_read( - block, - this.source_info(this.tcx.hir().span(*hir_id)), - *cause, - mir_place, - ); + // + // FIXME(RFC2229, rust#85435): Remove feature gate once diagnostics are + // improved and unsafe checking works properly in closure bodies again. + if this.tcx.features().capture_disjoint_fields { + for (thir_place, cause, hir_id) in fake_reads.into_iter() { + let place_builder = + unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); + + if let Ok(place_builder_resolved) = + place_builder.try_upvars_resolved(this.tcx, this.typeck_results) + { + let mir_place = + place_builder_resolved.into_place(this.tcx, this.typeck_results); + this.cfg.push_fake_read( + block, + this.source_info(this.tcx.hir().span(*hir_id)), + *cause, + mir_place, + ); + } } } From 4742bbb48b25df49a8b88db29c0259ba08b54ca5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 21 May 2021 15:05:53 -0400 Subject: [PATCH 18/70] Regression test for issue 85435. --- ...fe-op-in-let-under-unsafe-under-closure.rs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs diff --git a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs new file mode 100644 index 0000000000000..9315edf882bf8 --- /dev/null +++ b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs @@ -0,0 +1,28 @@ +// check-pass + +// This is issue #85435. But the real story is reflected in issue #85561, where +// a bug in the implementation of feature(capture_disjoint_fields) () was +// exposed to non-feature-gated code by a diagnostic changing PR that removed +// the gating in one case. + +// This test is double-checking that the case of interest continues to work as +// expected in the *absence* of that feature gate. At the time of this writing, +// enabling the feature gate will cause this test to fail. We obviously cannot +// stabilize that feature until it can correctly handle this test. + +fn main() { + let val: u8 = 5; + let u8_ptr: *const u8 = &val; + let _closure = || { + unsafe { + // Fails compilation with: + // error[E0133]: dereference of raw pointer is unsafe and + // requires unsafe function or block + let tmp = *u8_ptr; + tmp + + // Just dereferencing and returning directly compiles fine: + // *u8_ptr + } + }; +} From 0d073c9174aa02c04a321c65f384958b67d43f46 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Fri, 21 May 2021 15:10:56 -0400 Subject: [PATCH 19/70] Apply suggestions from code review (removing confusing comment from my test, since the comment reflects the bad undesirable behavior that is being fixed here.) --- .../issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs index 9315edf882bf8..b0d738855d731 100644 --- a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs +++ b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs @@ -15,9 +15,6 @@ fn main() { let u8_ptr: *const u8 = &val; let _closure = || { unsafe { - // Fails compilation with: - // error[E0133]: dereference of raw pointer is unsafe and - // requires unsafe function or block let tmp = *u8_ptr; tmp From 5b802ed6c9fd23214f9201b8e05193c8a2240e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= <77335613+ABouttefeux@users.noreply.github.com> Date: Sat, 22 May 2021 08:59:04 +0200 Subject: [PATCH 20/70] Apply suggestions from code review Co-authored-by: Esteban Kuber --- .../rustc_typeck/src/check/method/suggest.rs | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index f46d4205a6bd5..a36e0553c7add 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -384,7 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { span = item_name.span; - // issue #81576, elision of generic argument when no methode can be found in any implementation + // Don't show generic arguments when the method can't be found in any implementation (#81576). let mut ty_str_reported = ty_str.clone(); if let ty::Adt(_, ref generics) = actual.kind() { if generics.len() > 0 { @@ -493,22 +493,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.associated_item(*def_id, item_name, Namespace::ValueNS) { // Check for both mode is the same so we avoid suggesting - // incorect associated item. - match (mode, assoc.fn_has_self_parameter) { - (Mode::MethodCall, true) => { - if let SelfSource::MethodCall(_) = source { - // We check that the suggest type is actually - // different from the received one - // So we avoid suggestion method with Box - // for instance - self.tcx.at(span).type_of(*def_id) != actual - && self.tcx.at(span).type_of(*def_id) - != rcvr_ty - } else { - false - } + // incorrect associated item. + match (mode, assoc.fn_has_self_parameter, source) { + (Mode::MethodCall, true, SelfSource::MethodCall(_)) => { + // We check that the suggest type is actually + // different from the received one + // So we avoid suggestion method with Box + // for instance + self.tcx.at(span).type_of(*def_id) != actual + && self.tcx.at(span).type_of(*def_id) + != rcvr_ty } - (Mode::Path, false) => true, + (Mode::Path, false, _) => true, _ => false, } } else { @@ -521,7 +517,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { inherent_impls_candidate.dedup(); // number of type to shows at most. const LIMIT: usize = 3; - let mut note = format!("The {item_kind} was found for"); + let mut note = format!("the {item_kind} was found for"); if inherent_impls_candidate.len() > 1 { for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2) { From 120691c590c4309fda31994931b9a561b4249c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Sat, 22 May 2021 12:03:37 +0200 Subject: [PATCH 21/70] change from review and show full type if it can be deref --- .../rustc_typeck/src/check/method/suggest.rs | 89 ++++++++----------- src/test/ui/auto-ref-slice-plus-ref.stderr | 4 +- src/test/ui/class-cast-to-trait.stderr | 2 +- .../no-method-suggested-traits.stderr | 24 ++--- src/test/ui/issues/issue-30123.stderr | 2 +- .../method-not-found-generic-arg-elision.rs | 20 ++++- ...ethod-not-found-generic-arg-elision.stderr | 46 +++++++--- src/test/ui/object-pointer-types.stderr | 2 +- src/test/ui/resolve/issue-82865.stderr | 2 +- 9 files changed, 105 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index a36e0553c7add..109cd3e4bc86a 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -388,27 +388,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut ty_str_reported = ty_str.clone(); if let ty::Adt(_, ref generics) = actual.kind() { if generics.len() > 0 { - let candidate_numbers: usize = self - .autoderef(span, actual) - .map(|(ty, _)| { - if let ty::Adt(ref adt_deref, _) = ty.kind() { - self.tcx - .inherent_impls(adt_deref.did) - .iter() - .filter_map(|def_id| { - self.associated_item( - *def_id, - item_name, - Namespace::ValueNS, - ) - }) - .count() - } else { - 0 - } - }) - .sum(); - if candidate_numbers == 0 && unsatisfied_predicates.is_empty() { + let mut autoderef = self.autoderef(span, actual); + let candidate_found = autoderef.any(|(ty, _)| { + if let ty::Adt(ref adt_deref, _) = ty.kind() { + self.tcx + .inherent_impls(adt_deref.did) + .iter() + .filter_map(|def_id| { + self.associated_item( + *def_id, + item_name, + Namespace::ValueNS, + ) + }) + .count() + >= 1 + } else { + false + } + }); + let has_deref = autoderef.step_count() > 0; + if !candidate_found + && !has_deref + && unsatisfied_predicates.is_empty() + { if let Some((path_string, _)) = ty_str.split_once('<') { ty_str_reported = path_string.to_string(); } @@ -501,8 +504,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // So we avoid suggestion method with Box // for instance self.tcx.at(span).type_of(*def_id) != actual - && self.tcx.at(span).type_of(*def_id) - != rcvr_ty + && self.tcx.at(span).type_of(*def_id) != rcvr_ty } (Mode::Path, false, _) => true, _ => false, @@ -515,38 +517,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if inherent_impls_candidate.len() > 0 { inherent_impls_candidate.sort(); inherent_impls_candidate.dedup(); + let type_candidates = inherent_impls_candidate + .iter() + .map(|impl_item| self.tcx.at(span).type_of(*impl_item)) + .collect::>(); // number of type to shows at most. - const LIMIT: usize = 3; - let mut note = format!("the {item_kind} was found for"); - if inherent_impls_candidate.len() > 1 { - for impl_item in inherent_impls_candidate.iter().take(LIMIT - 2) - { - let impl_ty = self.tcx.at(span).type_of(*impl_item); - note = format!("{} {},", note, impl_ty); - } - let impl_ty = self.tcx.at(span).type_of( - inherent_impls_candidate - [inherent_impls_candidate.len() - 1], - ); - if inherent_impls_candidate.len() > LIMIT { - note = format!("{} {},", note, impl_ty); - } else { - note = format!("{} {} and", note, impl_ty); - } + let limit = if type_candidates.len() == 4 { 4 } else { 3 }; + for ty in type_candidates.iter().take(limit) { + err.note(&format!("the {item_kind} was found for {}", ty)); } - let impl_ty = self - .tcx - .at(span) - .type_of(*inherent_impls_candidate.last().unwrap()); - note = format!("{} {}", note, impl_ty); - if inherent_impls_candidate.len() > LIMIT { - note = format!( - "{} and {} more", - note, - inherent_impls_candidate.len() - LIMIT - ); + if type_candidates.len() > limit { + err.note(&format!( + "the {item_kind} was found for {} more types", + type_candidates.len() - limit + )); } - err.note(&format!("{}.", note)); } } } else { diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index 7203d3ed30e93..eb8447ff0f3e7 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `test_mut` found for struct `Vec` in the current scope +error[E0599]: no method named `test_mut` found for struct `Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:7:7 | LL | a.test_mut(); @@ -11,7 +11,7 @@ note: `MyIter` defines an item `test_mut`, perhaps you need to implement it LL | trait MyIter { | ^^^^^^^^^^^^ -error[E0599]: no method named `test` found for struct `Vec` in the current scope +error[E0599]: no method named `test` found for struct `Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr index a1a3ead581265..56d10d88d8b25 100644 --- a/src/test/ui/class-cast-to-trait.stderr +++ b/src/test/ui/class-cast-to-trait.stderr @@ -1,4 +1,4 @@ -error[E0599]: no method named `eat` found for struct `Box` in the current scope +error[E0599]: no method named `eat` found for struct `Box` in the current scope --> $DIR/class-cast-to-trait.rs:53:8 | LL | nyan.eat(); diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index 5507406b0f502..64ddcb81c0a9b 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -16,7 +16,7 @@ LL | use no_method_suggested_traits::qux::PrivPub; LL | use no_method_suggested_traits::Reexported; | -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&u32>>` in the current scope --> $DIR/no-method-suggested-traits.rs:26:44 | LL | std::rc::Rc::new(&mut Box::new(&1u32)).method(); @@ -46,7 +46,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use foo::Bar; | -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&char>>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); @@ -70,7 +70,7 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use no_method_suggested_traits::foo::PubPub; | -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&i32>>` in the current scope --> $DIR/no-method-suggested-traits.rs:37:44 | LL | std::rc::Rc::new(&mut Box::new(&1i32)).method(); @@ -98,7 +98,7 @@ LL | Foo.method(); candidate #3: `no_method_suggested_traits::qux::PrivPub` candidate #4: `Reexported` -error[E0599]: no method named `method` found for struct `Rc` in the current scope +error[E0599]: no method named `method` found for struct `Rc<&mut Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:42:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); @@ -124,7 +124,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&u64>>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); @@ -150,7 +150,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); @@ -176,7 +176,7 @@ note: `foo::Bar` defines an item `method2`, perhaps you need to implement it LL | pub trait Bar { | ^^^^^^^^^^^^^ -error[E0599]: no method named `method2` found for struct `Rc` in the current scope +error[E0599]: no method named `method2` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); @@ -202,7 +202,7 @@ LL | Foo.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:61:43 | LL | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); @@ -225,7 +225,7 @@ LL | Bar::X.method3(); = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `PubPub` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:65:46 | LL | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); @@ -241,7 +241,7 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc LL | 1_usize.method3(); | ^^^^^^^ method not found in `usize` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&usize>>` in the current scope --> $DIR/no-method-suggested-traits.rs:70:47 | LL | std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); @@ -253,7 +253,7 @@ error[E0599]: no method named `method3` found for struct `no_method_suggested_tr LL | no_method_suggested_traits::Foo.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:72:71 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); @@ -265,7 +265,7 @@ error[E0599]: no method named `method3` found for enum `no_method_suggested_trai LL | no_method_suggested_traits::Bar::X.method3(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` -error[E0599]: no method named `method3` found for struct `Rc` in the current scope +error[E0599]: no method named `method3` found for struct `Rc<&mut Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:75:74 | LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 27b128372c0fe..76a6b447ac100 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -4,7 +4,7 @@ error[E0599]: no function or associated item named `new_undirected` found for st LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` | - = note: The function or associated item was found for issue_30123_aux::Graph. + = note: the function or associated item was found for issue_30123_aux::Graph error: aborting due to previous error diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 23f01fb861fdb..3df928b5d804d 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -1,6 +1,7 @@ // Test for issue 81576 // Remove generic arguments if no method is found for all possible generic argument +use std::marker::PhantomData; struct Wrapper2<'a, T, const C: usize> { x: &'a T, @@ -19,8 +20,6 @@ impl<'a, const C: usize> Wrapper2<'a, i32, C> { } struct Wrapper(T); - - impl Wrapper { fn method(&self) {} } @@ -62,6 +61,20 @@ impl Other { fn other(&self) {} } +struct Struct{ + _phatom: PhantomData +} + +impl Default for Struct { + fn default() -> Self { + Self{ _phatom: PhantomData } + } +} + +impl Struct { + fn method(&self) {} +} + fn main() { let point_f64 = Point{ x: 1_f64, y: 1_f64}; let d = point_f64.distance(); @@ -87,4 +100,7 @@ fn main() { let a = vec![1, 2, 3]; a.not_found(); //~^ ERROR no method named `not_found` found for struct `Vec + let s = Struct::::default(); + s.method(); + //~^ ERROR the method `method` exists for struct `Struct`, but its trait bounds were not satisfied } diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 65dbabbc1430a..4a9cfb4fc804e 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `distance` found for struct `Point` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:69:23 + --> $DIR/method-not-found-generic-arg-elision.rs:82:23 | LL | struct Point { | --------------- method `distance` not found for this @@ -7,10 +7,10 @@ LL | struct Point { LL | let d = point_i32.distance(); | ^^^^^^^^ method not found in `Point` | - = note: The method was found for Point. + = note: the method was found for Point error[E0599]: no method named `other` found for struct `Point` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:71:23 + --> $DIR/method-not-found-generic-arg-elision.rs:84:23 | LL | struct Point { | --------------- method `other` not found for this @@ -19,13 +19,13 @@ LL | let d = point_i32.other(); | ^^^^^ method not found in `Point` error[E0599]: no method named `extend` found for struct `Map` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:74:29 + --> $DIR/method-not-found-generic-arg-elision.rs:87:29 | LL | v.iter().map(|x| x * x).extend(std::iter::once(100)); - | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:74:18: 74:27]>` + | ^^^^^^ method not found in `Map, [closure@$DIR/method-not-found-generic-arg-elision.rs:87:18: 87:27]>` error[E0599]: no method named `method` found for struct `Wrapper` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:77:13 + --> $DIR/method-not-found-generic-arg-elision.rs:90:13 | LL | struct Wrapper(T); | --------------------- method `method` not found for this @@ -33,10 +33,13 @@ LL | struct Wrapper(T); LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | - = note: The method was found for Wrapper, Wrapper, Wrapper and 3 more. + = note: the method was found for Wrapper + = note: the method was found for Wrapper + = note: the method was found for Wrapper + = note: the method was found for 3 more types error[E0599]: no method named `other` found for struct `Wrapper` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:79:13 + --> $DIR/method-not-found-generic-arg-elision.rs:92:13 | LL | struct Wrapper(T); | --------------------- method `other` not found for this @@ -45,7 +48,7 @@ LL | wrapper.other(); | ^^^^^ method not found in `Wrapper` error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:83:13 + --> $DIR/method-not-found-generic-arg-elision.rs:96:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `method` not found for this @@ -53,10 +56,12 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` | - = note: The method was found for Wrapper2<'a, i8, C>, Wrapper2<'a, i32, C> and Wrapper2<'a, i32, C>. + = note: the method was found for Wrapper2<'a, i8, C> + = note: the method was found for Wrapper2<'a, i16, C> + = note: the method was found for Wrapper2<'a, i32, C> error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:85:13 + --> $DIR/method-not-found-generic-arg-elision.rs:98:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `other` not found for this @@ -64,12 +69,25 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.other(); | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` -error[E0599]: no method named `not_found` found for struct `Vec` in the current scope - --> $DIR/method-not-found-generic-arg-elision.rs:88:7 +error[E0599]: no method named `not_found` found for struct `Vec<{integer}>` in the current scope + --> $DIR/method-not-found-generic-arg-elision.rs:101:7 | LL | a.not_found(); | ^^^^^^^^^ method not found in `Vec<{integer}>` -error: aborting due to 8 previous errors +error[E0599]: the method `method` exists for struct `Struct`, but its trait bounds were not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:104:7 + | +LL | struct Struct{ + | ---------------- method `method` not found for this +... +LL | s.method(); + | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `f64: Eq` + `f64: Ord` + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index 021899b3082cd..a477425edc81b 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -16,7 +16,7 @@ LL | fn owned(self: Box); LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` -error[E0599]: no method named `managed` found for struct `Box` in the current scope +error[E0599]: no method named `managed` found for struct `Box<(dyn Foo + 'static)>` in the current scope --> $DIR/object-pointer-types.rs:23:7 | LL | x.managed(); diff --git a/src/test/ui/resolve/issue-82865.stderr b/src/test/ui/resolve/issue-82865.stderr index 6b8ec47d98d81..027d7a0e0e448 100644 --- a/src/test/ui/resolve/issue-82865.stderr +++ b/src/test/ui/resolve/issue-82865.stderr @@ -4,7 +4,7 @@ error[E0433]: failed to resolve: maybe a missing crate `x`? LL | use x::y::z; | ^ maybe a missing crate `x`? -error[E0599]: no function or associated item named `z` found for struct `Box` in the current scope +error[E0599]: no function or associated item named `z` found for struct `Box<_, _>` in the current scope --> $DIR/issue-82865.rs:8:10 | LL | Box::z From a50f1e949b4f7b3b35ee0be041cbf490d6e21314 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 22 May 2021 11:46:54 +0200 Subject: [PATCH 22/70] Get rid of PreviousDepGraph. --- .../rustc_incremental/src/persist/load.rs | 10 ++-- .../rustc_incremental/src/persist/save.rs | 4 +- compiler/rustc_middle/src/dep_graph/mod.rs | 1 - .../rustc_query_system/src/dep_graph/graph.rs | 15 +++-- .../rustc_query_system/src/dep_graph/mod.rs | 2 - .../rustc_query_system/src/dep_graph/prev.rs | 56 ------------------- .../src/dep_graph/serialized.rs | 40 +++++++++++-- 7 files changed, 49 insertions(+), 79 deletions(-) delete mode 100644 compiler/rustc_query_system/src/dep_graph/prev.rs diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index bd3b5239f7bda..303c39a39a920 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::definitions::DefPathTable; -use rustc_middle::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{SerializedDepGraph, WorkProduct, WorkProductId}; use rustc_middle::ty::query::OnDiskCache; use rustc_serialize::opaque::Decoder; use rustc_serialize::Decodable; @@ -22,8 +22,8 @@ pub enum LoadResult { Error { message: String }, } -impl LoadResult<(PreviousDepGraph, WorkProductMap)> { - pub fn open(self, sess: &Session) -> (PreviousDepGraph, WorkProductMap) { +impl LoadResult<(SerializedDepGraph, WorkProductMap)> { + pub fn open(self, sess: &Session) -> (SerializedDepGraph, WorkProductMap) { match self { LoadResult::Error { message } => { sess.warn(&message); @@ -84,7 +84,7 @@ impl MaybeAsync { } } -pub type DepGraphFuture = MaybeAsync>; +pub type DepGraphFuture = MaybeAsync>; /// Launch a thread and load the dependency graph in the background. pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { @@ -185,7 +185,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { let dep_graph = SerializedDepGraph::decode(&mut decoder) .expect("Error reading cached dep-graph"); - LoadResult::Ok { data: (PreviousDepGraph::new(dep_graph), prev_work_products) } + LoadResult::Ok { data: (dep_graph, prev_work_products) } } } })) diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 1484088837a4b..9603b102cbc5d 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::join; -use rustc_middle::dep_graph::{DepGraph, PreviousDepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{DepGraph, SerializedDepGraph, WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_serialize::Encodable as RustcEncodable; @@ -186,7 +186,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: &mut FileEncoder) -> FileEncodeR pub fn build_dep_graph( sess: &Session, - prev_graph: PreviousDepGraph, + prev_graph: SerializedDepGraph, prev_work_products: FxHashMap, ) -> Option { if sess.opts.incremental.is_none() { diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 31bea8329587d..aa61219ad789e 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -18,7 +18,6 @@ crate use dep_node::{make_compile_codegen_unit, make_compile_mono_item}; pub type DepGraph = rustc_query_system::dep_graph::DepGraph; pub type TaskDeps = rustc_query_system::dep_graph::TaskDeps; pub type DepGraphQuery = rustc_query_system::dep_graph::DepGraphQuery; -pub type PreviousDepGraph = rustc_query_system::dep_graph::PreviousDepGraph; pub type SerializedDepGraph = rustc_query_system::dep_graph::SerializedDepGraph; pub type EdgeFilter = rustc_query_system::dep_graph::debug::EdgeFilter; diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 7a0fc320663f7..38010b7786814 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -19,9 +19,8 @@ use std::marker::PhantomData; use std::mem; use std::sync::atomic::Ordering::Relaxed; -use super::prev::PreviousDepGraph; use super::query::DepGraphQuery; -use super::serialized::{GraphEncoder, SerializedDepNodeIndex}; +use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex}; use super::{DepContext, DepKind, DepNode, HasDepContext, WorkProductId}; use crate::query::QueryContext; @@ -78,7 +77,7 @@ struct DepGraphData { /// The dep-graph from the previous compilation session. It contains all /// nodes and edges as well as all fingerprints of nodes that have them. - previous: PreviousDepGraph, + previous: SerializedDepGraph, colors: DepNodeColorMap, @@ -109,7 +108,7 @@ where impl DepGraph { pub fn new( - prev_graph: PreviousDepGraph, + prev_graph: SerializedDepGraph, prev_work_products: FxHashMap, encoder: FileEncoder, record_graph: bool, @@ -857,7 +856,7 @@ rustc_index::newtype_index! { /// For this reason, we avoid storing `DepNode`s more than once as map /// keys. The `new_node_to_index` map only contains nodes not in the previous /// graph, and we map nodes in the previous graph to indices via a two-step -/// mapping. `PreviousDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`, +/// mapping. `SerializedDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`, /// and the `prev_index_to_index` vector (which is more compact and faster than /// using a map) maps from `SerializedDepNodeIndex` to `DepNodeIndex`. /// @@ -982,7 +981,7 @@ impl CurrentDepGraph { fn intern_node( &self, profiler: &SelfProfilerRef, - prev_graph: &PreviousDepGraph, + prev_graph: &SerializedDepGraph, key: DepNode, edges: EdgesVec, fingerprint: Option, @@ -1080,7 +1079,7 @@ impl CurrentDepGraph { fn promote_node_and_deps_to_current( &self, profiler: &SelfProfilerRef, - prev_graph: &PreviousDepGraph, + prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, ) -> DepNodeIndex { self.debug_assert_not_in_new_nodes(prev_graph, prev_index); @@ -1112,7 +1111,7 @@ impl CurrentDepGraph { #[inline] fn debug_assert_not_in_new_nodes( &self, - prev_graph: &PreviousDepGraph, + prev_graph: &SerializedDepGraph, prev_index: SerializedDepNodeIndex, ) { let node = &prev_graph.index_to_node(prev_index); diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 1b6ecf3e637f3..15e2633c4f12e 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -1,13 +1,11 @@ pub mod debug; mod dep_node; mod graph; -mod prev; mod query; mod serialized; pub use dep_node::{DepNode, DepNodeParams, WorkProductId}; pub use graph::{hash_result, DepGraph, DepNodeColor, DepNodeIndex, TaskDeps, WorkProduct}; -pub use prev::PreviousDepGraph; pub use query::DepGraphQuery; pub use serialized::{SerializedDepGraph, SerializedDepNodeIndex}; diff --git a/compiler/rustc_query_system/src/dep_graph/prev.rs b/compiler/rustc_query_system/src/dep_graph/prev.rs deleted file mode 100644 index 6303bbf53b9c4..0000000000000 --- a/compiler/rustc_query_system/src/dep_graph/prev.rs +++ /dev/null @@ -1,56 +0,0 @@ -use super::serialized::{SerializedDepGraph, SerializedDepNodeIndex}; -use super::{DepKind, DepNode}; -use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxHashMap; - -#[derive(Debug)] -pub struct PreviousDepGraph { - data: SerializedDepGraph, - index: FxHashMap, SerializedDepNodeIndex>, -} - -impl Default for PreviousDepGraph { - fn default() -> Self { - PreviousDepGraph { data: Default::default(), index: Default::default() } - } -} - -impl PreviousDepGraph { - pub fn new(data: SerializedDepGraph) -> PreviousDepGraph { - let index: FxHashMap<_, _> = - data.nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect(); - PreviousDepGraph { data, index } - } - - #[inline] - pub fn edge_targets_from( - &self, - dep_node_index: SerializedDepNodeIndex, - ) -> &[SerializedDepNodeIndex] { - self.data.edge_targets_from(dep_node_index) - } - - #[inline] - pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode { - self.data.nodes[dep_node_index] - } - - #[inline] - pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { - self.index.get(dep_node).cloned() - } - - #[inline] - pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { - self.index.get(dep_node).map(|&node_index| self.data.fingerprints[node_index]) - } - - #[inline] - pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { - self.data.fingerprints[dep_node_index] - } - - pub fn node_count(&self) -> usize { - self.index.len() - } -} diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 6f3d1fb71994e..6a84a28be6656 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -37,17 +37,19 @@ rustc_index::newtype_index! { #[derive(Debug)] pub struct SerializedDepGraph { /// The set of all DepNodes in the graph - pub nodes: IndexVec>, + nodes: IndexVec>, /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to /// the DepNode at the same index in the nodes vector. - pub fingerprints: IndexVec, + fingerprints: IndexVec, /// For each DepNode, stores the list of edges originating from that /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data, /// which holds the actual DepNodeIndices of the target nodes. - pub edge_list_indices: IndexVec, + edge_list_indices: IndexVec, /// A flattened list of all edge targets in the graph. Edge sources are /// implicit in edge_list_indices. - pub edge_list_data: Vec, + edge_list_data: Vec, + /// Reciprocal map to `nodes`. + index: FxHashMap, SerializedDepNodeIndex>, } impl Default for SerializedDepGraph { @@ -57,6 +59,7 @@ impl Default for SerializedDepGraph { fingerprints: Default::default(), edge_list_indices: Default::default(), edge_list_data: Default::default(), + index: Default::default(), } } } @@ -67,6 +70,30 @@ impl SerializedDepGraph { let targets = self.edge_list_indices[source]; &self.edge_list_data[targets.0 as usize..targets.1 as usize] } + + #[inline] + pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode { + self.nodes[dep_node_index] + } + + #[inline] + pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option { + self.index.get(dep_node).cloned() + } + + #[inline] + pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { + self.index.get(dep_node).map(|&node_index| self.fingerprints[node_index]) + } + + #[inline] + pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { + self.fingerprints[dep_node_index] + } + + pub fn node_count(&self) -> usize { + self.index.len() + } } impl<'a, K: DepKind + Decodable>> Decodable> @@ -121,7 +148,10 @@ impl<'a, K: DepKind + Decodable>> Decodable = + nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect(); + + Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }) } } From 903e369c831d52726a5292f847e384622189d9a0 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Sat, 22 May 2021 17:48:26 -0400 Subject: [PATCH 23/70] Fix boostrap using host exe suffix for cargo --- src/bootstrap/tool.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 98b5bfd3b980a..64e4be6863a62 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -217,9 +217,8 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - let cargo_out = - builder.cargo_out(compiler, self.mode, target).join(exe(tool, compiler.host)); - let bin = builder.tools_dir(compiler).join(exe(tool, compiler.host)); + let cargo_out = builder.cargo_out(compiler, self.mode, target).join(exe(tool, target)); + let bin = builder.tools_dir(compiler).join(exe(tool, target)); builder.copy(&cargo_out, &bin); Some(bin) } From 9e11b61e8de1ffb6a1ea8fb1f8c42cfe30b6b3e4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 11 Jan 2021 10:13:08 -0800 Subject: [PATCH 24/70] linkchecker: Organize state into a struct, and add report. Moves all the state into a struct so it doesn't need to be passed around as much. Also adds a report showing how long it took and what it found. This includes a minor change: a failure to load a file is now an error, instead of being ignored. This should only happen if there is a permission error or some other shenanigans going on. --- src/tools/linkchecker/main.rs | 465 +++++++++++++++++++--------------- 1 file changed, 257 insertions(+), 208 deletions(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index c677d04917eaf..7df4f5a9c46d5 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -20,6 +20,7 @@ use std::env; use std::fs; use std::path::{Component, Path, PathBuf}; use std::rc::Rc; +use std::time::Instant; use once_cell::sync::Lazy; use regex::Regex; @@ -89,16 +90,41 @@ macro_rules! t { fn main() { let docs = env::args_os().nth(1).unwrap(); let docs = env::current_dir().unwrap().join(docs); - let mut errors = false; - walk(&mut HashMap::new(), &docs, &docs, &mut errors); - if errors { - panic!("found some broken links"); + let mut checker = Checker { + root: docs.clone(), + cache: HashMap::new(), + errors: 0, + start: Instant::now(), + html_files: 0, + html_redirects: 0, + links_checked: 0, + links_ignored_external: 0, + links_ignored_exception: 0, + intra_doc_exceptions: 0, + }; + checker.walk(&docs); + checker.report(); + if checker.errors != 0 { + println!("found some broken links"); + std::process::exit(1); } } +struct Checker { + root: PathBuf, + cache: Cache, + errors: u32, + start: Instant, + html_files: u32, + html_redirects: u32, + links_checked: u32, + links_ignored_external: u32, + links_ignored_exception: u32, + intra_doc_exceptions: u32, +} + #[derive(Debug)] pub enum LoadError { - IOError(std::io::Error), BrokenRedirect(PathBuf, std::io::Error), IsRedirect, } @@ -131,13 +157,13 @@ fn small_url_encode(s: &str) -> String { } impl FileEntry { - fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut bool) { + fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut u32) { if self.ids.is_empty() { with_attrs_in_source(contents, " id", |fragment, i, _| { let frag = fragment.trim_start_matches("#").to_owned(); let encoded = small_url_encode(&frag); if !self.ids.insert(frag) { - *errors = true; + *errors += 1; println!("{}:{}: id is not unique: `{}`", file.display(), i, fragment); } // Just in case, we also add the encoded id. @@ -147,239 +173,262 @@ impl FileEntry { } } -fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) { - for entry in t!(dir.read_dir()).map(|e| t!(e)) { - let path = entry.path(); - let kind = t!(entry.file_type()); - if kind.is_dir() { - walk(cache, root, &path, errors); - } else { - let pretty_path = check(cache, root, &path, errors); - if let Some(pretty_path) = pretty_path { - let entry = cache.get_mut(&pretty_path).unwrap(); - // we don't need the source anymore, - // so drop to reduce memory-usage - entry.source = Rc::new(String::new()); +impl Checker { + fn walk(&mut self, dir: &Path) { + for entry in t!(dir.read_dir()).map(|e| t!(e)) { + let path = entry.path(); + let kind = t!(entry.file_type()); + if kind.is_dir() { + self.walk(&path); + } else { + let pretty_path = self.check(&path); + if let Some(pretty_path) = pretty_path { + let entry = self.cache.get_mut(&pretty_path).unwrap(); + // we don't need the source anymore, + // so drop to reduce memory-usage + entry.source = Rc::new(String::new()); + } } } } -} -fn is_intra_doc_exception(file: &Path, link: &str) -> bool { - if let Some(entry) = INTRA_DOC_LINK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { - entry.1.is_empty() || entry.1.contains(&link) - } else { - false - } -} - -fn is_exception(file: &Path, link: &str) -> bool { - if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { - entry.1.contains(&link) - } else { - // FIXME(#63351): Concat trait in alloc/slice reexported in primitive page - // - // NOTE: This cannot be added to `LINKCHECK_EXCEPTIONS` because the resolved path - // calculated in `check` function is outside `build//doc` dir. - // So the `strip_prefix` method just returns the old absolute broken path. - if file.ends_with("std/primitive.slice.html") { - if link.ends_with("primitive.slice.html") { - return true; - } + fn check(&mut self, file: &Path) -> Option { + // Ignore non-HTML files. + if file.extension().and_then(|s| s.to_str()) != Some("html") { + return None; } - false - } -} + self.html_files += 1; -fn check(cache: &mut Cache, root: &Path, file: &Path, errors: &mut bool) -> Option { - // Ignore non-HTML files. - if file.extension().and_then(|s| s.to_str()) != Some("html") { - return None; - } - - let res = load_file(cache, root, file, SkipRedirect); - let (pretty_file, contents) = match res { - Ok(res) => res, - Err(_) => return None, - }; - { - cache.get_mut(&pretty_file).unwrap().parse_ids(&pretty_file, &contents, errors); - } - - // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' - with_attrs_in_source(&contents, " href", |url, i, base| { - // Ignore external URLs - if url.starts_with("http:") - || url.starts_with("https:") - || url.starts_with("javascript:") - || url.starts_with("ftp:") - || url.starts_with("irc:") - || url.starts_with("data:") - { - return; - } - let (url, fragment) = match url.split_once('#') { - None => (url, None), - Some((url, fragment)) => (url, Some(fragment)), + let res = self.load_file(file, SkipRedirect); + let (pretty_file, contents) = match res { + Ok(res) => res, + Err(_) => return None, }; - // NB: the `splitn` always succeeds, even if the delimiter is not present. - let url = url.splitn(2, '?').next().unwrap(); - - // Once we've plucked out the URL, parse it using our base url and - // then try to extract a file path. - let mut path = file.to_path_buf(); - if !base.is_empty() || !url.is_empty() { - path.pop(); - for part in Path::new(base).join(url).components() { - match part { - Component::Prefix(_) | Component::RootDir => { - // Avoid absolute paths as they make the docs not - // relocatable by making assumptions on where the docs - // are hosted relative to the site root. - *errors = true; - println!( - "{}:{}: absolute path - {}", - pretty_file.display(), - i + 1, - Path::new(base).join(url).display() - ); - return; - } - Component::CurDir => {} - Component::ParentDir => { - path.pop(); - } - Component::Normal(s) => { - path.push(s); - } - } - } - } - - // Alright, if we've found a file name then this file had better - // exist! If it doesn't then we register and print an error. - if path.exists() { - if path.is_dir() { - // Links to directories show as directory listings when viewing - // the docs offline so it's best to avoid them. - *errors = true; - let pretty_path = path.strip_prefix(root).unwrap_or(&path); - println!( - "{}:{}: directory link - {}", - pretty_file.display(), - i + 1, - pretty_path.display() - ); + self.cache.get_mut(&pretty_file).unwrap().parse_ids( + &pretty_file, + &contents, + &mut self.errors, + ); + + // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' + with_attrs_in_source(&contents, " href", |url, i, base| { + // Ignore external URLs + if url.starts_with("http:") + || url.starts_with("https:") + || url.starts_with("javascript:") + || url.starts_with("ftp:") + || url.starts_with("irc:") + || url.starts_with("data:") + { + self.links_ignored_external += 1; return; } - if let Some(extension) = path.extension() { - // Ignore none HTML files. - if extension != "html" { - return; + self.links_checked += 1; + let (url, fragment) = match url.split_once('#') { + None => (url, None), + Some((url, fragment)) => (url, Some(fragment)), + }; + // NB: the `splitn` always succeeds, even if the delimiter is not present. + let url = url.splitn(2, '?').next().unwrap(); + + // Once we've plucked out the URL, parse it using our base url and + // then try to extract a file path. + let mut path = file.to_path_buf(); + if !base.is_empty() || !url.is_empty() { + path.pop(); + for part in Path::new(base).join(url).components() { + match part { + Component::Prefix(_) | Component::RootDir => { + // Avoid absolute paths as they make the docs not + // relocatable by making assumptions on where the docs + // are hosted relative to the site root. + self.errors += 1; + println!( + "{}:{}: absolute path - {}", + pretty_file.display(), + i + 1, + Path::new(base).join(url).display() + ); + return; + } + Component::CurDir => {} + Component::ParentDir => { + path.pop(); + } + Component::Normal(s) => { + path.push(s); + } + } } } - let res = load_file(cache, root, &path, FromRedirect(false)); - let (pretty_path, contents) = match res { - Ok(res) => res, - Err(LoadError::IOError(err)) => { - panic!("error loading {}: {}", path.display(), err); - } - Err(LoadError::BrokenRedirect(target, _)) => { - *errors = true; + + // Alright, if we've found a file name then this file had better + // exist! If it doesn't then we register and print an error. + if path.exists() { + if path.is_dir() { + // Links to directories show as directory listings when viewing + // the docs offline so it's best to avoid them. + self.errors += 1; + let pretty_path = path.strip_prefix(&self.root).unwrap_or(&path); println!( - "{}:{}: broken redirect to {}", + "{}:{}: directory link - {}", pretty_file.display(), i + 1, - target.display() + pretty_path.display() ); return; } - Err(LoadError::IsRedirect) => unreachable!(), - }; - - if let Some(ref fragment) = fragment { - // Fragments like `#1-6` are most likely line numbers to be - // interpreted by javascript, so we're ignoring these - if fragment.splitn(2, '-').all(|f| f.chars().all(|c| c.is_numeric())) { - return; + if let Some(extension) = path.extension() { + // Ignore none HTML files. + if extension != "html" { + return; + } } + let res = self.load_file(&path, FromRedirect(false)); + let (pretty_path, contents) = match res { + Ok(res) => res, + Err(LoadError::BrokenRedirect(target, _)) => { + self.errors += 1; + println!( + "{}:{}: broken redirect to {}", + pretty_file.display(), + i + 1, + target.display() + ); + return; + } + Err(LoadError::IsRedirect) => unreachable!(), + }; - // These appear to be broken in mdbook right now? - if fragment.starts_with('-') { - return; - } + if let Some(ref fragment) = fragment { + // Fragments like `#1-6` are most likely line numbers to be + // interpreted by javascript, so we're ignoring these + if fragment.splitn(2, '-').all(|f| f.chars().all(|c| c.is_numeric())) { + return; + } - let entry = &mut cache.get_mut(&pretty_path).unwrap(); - entry.parse_ids(&pretty_path, &contents, errors); + // These appear to be broken in mdbook right now? + if fragment.starts_with('-') { + return; + } - if !entry.ids.contains(*fragment) && !is_exception(file, &format!("#{}", fragment)) - { - *errors = true; - print!("{}:{}: broken link fragment ", pretty_file.display(), i + 1); - println!("`#{}` pointing to `{}`", fragment, pretty_path.display()); - }; + let entry = self.cache.get_mut(&pretty_path).unwrap(); + entry.parse_ids(&pretty_path, &contents, &mut self.errors); + + if entry.ids.contains(*fragment) { + return; + } + + if is_exception(file, &format!("#{}", fragment)) { + self.links_ignored_exception += 1; + } else { + self.errors += 1; + print!("{}:{}: broken link fragment ", pretty_file.display(), i + 1); + println!("`#{}` pointing to `{}`", fragment, pretty_path.display()); + }; + } + } else { + let pretty_path = path.strip_prefix(&self.root).unwrap_or(&path); + if is_exception(file, pretty_path.to_str().unwrap()) { + } else { + self.errors += 1; + print!("{}:{}: broken link - ", pretty_file.display(), i + 1); + println!("{}", pretty_path.display()); + } } - } else { - let pretty_path = path.strip_prefix(root).unwrap_or(&path); - if !is_exception(file, pretty_path.to_str().unwrap()) { - *errors = true; - print!("{}:{}: broken link - ", pretty_file.display(), i + 1); - println!("{}", pretty_path.display()); + }); + + // Search for intra-doc links that rustdoc didn't warn about + // FIXME(#77199, 77200) Rustdoc should just warn about these directly. + // NOTE: only looks at one line at a time; in practice this should find most links + for (i, line) in contents.lines().enumerate() { + for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) { + if is_intra_doc_exception(file, &broken_link[1]) { + self.intra_doc_exceptions += 1; + } else { + self.errors += 1; + print!("{}:{}: broken intra-doc link - ", pretty_file.display(), i + 1); + println!("{}", &broken_link[0]); + } } } - }); - - // Search for intra-doc links that rustdoc didn't warn about - // FIXME(#77199, 77200) Rustdoc should just warn about these directly. - // NOTE: only looks at one line at a time; in practice this should find most links - for (i, line) in contents.lines().enumerate() { - for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) { - if !is_intra_doc_exception(file, &broken_link[1]) { - *errors = true; - print!("{}:{}: broken intra-doc link - ", pretty_file.display(), i + 1); - println!("{}", &broken_link[0]); + Some(pretty_file) + } + + fn load_file( + &mut self, + file: &Path, + redirect: Redirect, + ) -> Result<(PathBuf, Rc), LoadError> { + let pretty_file = PathBuf::from(file.strip_prefix(&self.root).unwrap_or(&file)); + + let (maybe_redirect, contents) = match self.cache.entry(pretty_file.clone()) { + Entry::Occupied(entry) => (None, entry.get().source.clone()), + Entry::Vacant(entry) => { + let contents = match fs::read_to_string(file) { + Ok(s) => Rc::new(s), + Err(err) => { + return Err(if let FromRedirect(true) = redirect { + LoadError::BrokenRedirect(file.to_path_buf(), err) + } else { + panic!("error loading {}: {}", file.display(), err); + }); + } + }; + + let maybe = maybe_redirect(&contents); + if maybe.is_some() { + self.html_redirects += 1; + if let SkipRedirect = redirect { + return Err(LoadError::IsRedirect); + } + } else { + entry.insert(FileEntry { source: contents.clone(), ids: HashSet::new() }); + } + (maybe, contents) } + }; + match maybe_redirect.map(|url| file.parent().unwrap().join(url)) { + Some(redirect_file) => self.load_file(&redirect_file, FromRedirect(true)), + None => Ok((pretty_file, contents)), } } - Some(pretty_file) + + fn report(&self) { + println!("checked links in: {:.1}s", self.start.elapsed().as_secs_f64()); + println!("number of HTML files scanned: {}", self.html_files); + println!("number of HTML redirects found: {}", self.html_redirects); + println!("number of links checked: {}", self.links_checked); + println!("number of links ignored due to external: {}", self.links_ignored_external); + println!("number of links ignored due to exceptions: {}", self.links_ignored_exception); + println!("number of intra doc links ignored: {}", self.intra_doc_exceptions); + println!("errors found: {}", self.errors); + } } -fn load_file( - cache: &mut Cache, - root: &Path, - file: &Path, - redirect: Redirect, -) -> Result<(PathBuf, Rc), LoadError> { - let pretty_file = PathBuf::from(file.strip_prefix(root).unwrap_or(&file)); - - let (maybe_redirect, contents) = match cache.entry(pretty_file.clone()) { - Entry::Occupied(entry) => (None, entry.get().source.clone()), - Entry::Vacant(entry) => { - let contents = match fs::read_to_string(file) { - Ok(s) => Rc::new(s), - Err(err) => { - return Err(if let FromRedirect(true) = redirect { - LoadError::BrokenRedirect(file.to_path_buf(), err) - } else { - LoadError::IOError(err) - }); - } - }; +fn is_intra_doc_exception(file: &Path, link: &str) -> bool { + if let Some(entry) = INTRA_DOC_LINK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { + entry.1.is_empty() || entry.1.contains(&link) + } else { + false + } +} - let maybe = maybe_redirect(&contents); - if maybe.is_some() { - if let SkipRedirect = redirect { - return Err(LoadError::IsRedirect); - } - } else { - entry.insert(FileEntry { source: contents.clone(), ids: HashSet::new() }); +fn is_exception(file: &Path, link: &str) -> bool { + if let Some(entry) = LINKCHECK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { + entry.1.contains(&link) + } else { + // FIXME(#63351): Concat trait in alloc/slice reexported in primitive page + // + // NOTE: This cannot be added to `LINKCHECK_EXCEPTIONS` because the resolved path + // calculated in `check` function is outside `build//doc` dir. + // So the `strip_prefix` method just returns the old absolute broken path. + if file.ends_with("std/primitive.slice.html") { + if link.ends_with("primitive.slice.html") { + return true; } - (maybe, contents) } - }; - match maybe_redirect.map(|url| file.parent().unwrap().join(url)) { - Some(redirect_file) => load_file(cache, root, &redirect_file, FromRedirect(true)), - None => Ok((pretty_file, contents)), + false } } From d7341f3c4bfd814a778461a465365e78a15e4de7 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 23 May 2021 21:43:11 +0200 Subject: [PATCH 25/70] Don't reborrow self when computing the dest pointer in <[T]>::copy_within --- library/core/src/slice/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 0923175414edd..3bcea4e6d25ed 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3096,7 +3096,11 @@ impl [T] { // SAFETY: the conditions for `ptr::copy` have all been checked above, // as have those for `ptr::add`. unsafe { - ptr::copy(self.as_ptr().add(src_start), self.as_mut_ptr().add(dest), count); + // Derive both `src_ptr` and `dest_ptr` from the same loan + let ptr = self.as_mut_ptr(); + let src_ptr = ptr.add(src_start); + let dest_ptr = ptr.add(dest); + ptr::copy(src_ptr, dest_ptr, count); } } From db8c6e038f9d667670ac2737cda9a7612f88f7be Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 24 May 2021 10:50:51 +0200 Subject: [PATCH 26/70] Remove stray .stderr files --- .../cast-ptr-to-int-const.with_feature.stderr | 19 --------- ...st-ptr-to-int-const.without_feature.stderr | 39 ------------------- 2 files changed, 58 deletions(-) delete mode 100644 src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr delete mode 100644 src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr diff --git a/src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr b/src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr deleted file mode 100644 index 8282bc3db0507..0000000000000 --- a/src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block - --> $DIR/cast-ptr-to-int-const.rs:16:9 - | -LL | &Y as *const u32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int - | - = note: casting pointers to integers in constants - -error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block - --> $DIR/cast-ptr-to-int-const.rs:23:5 - | -LL | &0 as *const i32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int - | - = note: casting pointers to integers in constants - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr b/src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr deleted file mode 100644 index c87fa1a14a4c8..0000000000000 --- a/src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/cast-ptr-to-int-const.rs:8:9 - | -LL | main as usize - | ^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/cast-ptr-to-int-const.rs:12:9 - | -LL | &Y as *const u32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/cast-ptr-to-int-const.rs:16:9 - | -LL | &Y as *const u32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error[E0658]: casting pointers to integers in constant functions is unstable - --> $DIR/cast-ptr-to-int-const.rs:23:5 - | -LL | &0 as *const i32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. From e0c97196724d82335ee0dbb07cb3f3166f91c009 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 24 May 2021 12:41:13 +0200 Subject: [PATCH 27/70] Avoid a double drop in Vec::dedup if a destructor panics --- library/alloc/src/vec/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1c33ff555d628..105c60e7bf085 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1619,6 +1619,8 @@ impl Vec { let prev_ptr = ptr.add(gap.write.wrapping_sub(1)); if same_bucket(&mut *read_ptr, &mut *prev_ptr) { + // Increase `gap.read` now since the drop may panic. + gap.read += 1; /* We have found duplicate, drop it in-place */ ptr::drop_in_place(read_ptr); } else { @@ -1631,9 +1633,8 @@ impl Vec { /* We have filled that place, so go further */ gap.write += 1; + gap.read += 1; } - - gap.read += 1; } /* Technically we could let `gap` clean up with its Drop, but From c9595faa2850b01966c64682d2bb8b32e0955625 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Mon, 24 May 2021 12:42:04 +0200 Subject: [PATCH 28/70] Make Vec::dedup panicking test actually detect double panics --- library/alloc/tests/vec.rs | 48 ++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index ad69234403b9c..36c81b4970973 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -2234,48 +2234,50 @@ fn test_vec_dedup() { #[test] fn test_vec_dedup_panicking() { #[derive(Debug)] - struct Panic { - drop_counter: &'static AtomicU32, + struct Panic<'a> { + drop_counter: &'a Cell, value: bool, index: usize, } - impl PartialEq for Panic { + impl<'a> PartialEq for Panic<'a> { fn eq(&self, other: &Self) -> bool { self.value == other.value } } - impl Drop for Panic { + impl<'a> Drop for Panic<'a> { fn drop(&mut self) { - let x = self.drop_counter.fetch_add(1, Ordering::SeqCst); - assert!(x != 4); + self.drop_counter.set(self.drop_counter.get() + 1); + if !std::thread::panicking() { + assert!(self.index != 4); + } } } - static DROP_COUNTER: AtomicU32 = AtomicU32::new(0); + let drop_counter = &Cell::new(0); let expected = [ - Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 }, - Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 }, - Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 }, - Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 }, + Panic { drop_counter, value: false, index: 0 }, + Panic { drop_counter, value: false, index: 5 }, + Panic { drop_counter, value: true, index: 6 }, + Panic { drop_counter, value: true, index: 7 }, ]; let mut vec = vec![ - Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 }, + Panic { drop_counter, value: false, index: 0 }, // these elements get deduplicated - Panic { drop_counter: &DROP_COUNTER, value: false, index: 1 }, - Panic { drop_counter: &DROP_COUNTER, value: false, index: 2 }, - Panic { drop_counter: &DROP_COUNTER, value: false, index: 3 }, - Panic { drop_counter: &DROP_COUNTER, value: false, index: 4 }, - // here it panics - Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 }, - Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 }, - Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 }, + Panic { drop_counter, value: false, index: 1 }, + Panic { drop_counter, value: false, index: 2 }, + Panic { drop_counter, value: false, index: 3 }, + Panic { drop_counter, value: false, index: 4 }, + // here it panics while dropping the item with index==4 + Panic { drop_counter, value: false, index: 5 }, + Panic { drop_counter, value: true, index: 6 }, + Panic { drop_counter, value: true, index: 7 }, ]; - let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { - vec.dedup(); - })); + let _ = catch_unwind(AssertUnwindSafe(|| vec.dedup())).unwrap_err(); + + assert_eq!(drop_counter.get(), 4); let ok = vec.iter().zip(expected.iter()).all(|(x, y)| x.index == y.index); From 0e4f8cb661f66be0d02961d25b8f30d2b13c7af9 Mon Sep 17 00:00:00 2001 From: Taylor Yu Date: Mon, 24 May 2021 09:24:35 -0500 Subject: [PATCH 29/70] minor rewording after review Use "the `WouldBlock` error" instead of "the error `WouldBlock`", etc. --- library/std/src/sync/mutex.rs | 4 ++-- library/std/src/sync/rwlock.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index 5ebb87792f2a2..e7c5479ab9bb6 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -294,11 +294,11 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return the error [`Poisoned`] if the mutex would + /// this call will return the [`Poisoned`] error if the mutex would /// otherwise be acquired. /// /// If the mutex could not be acquired because it is already locked, then - /// this call will return [`WouldBlock`]. + /// this call will return the [`WouldBlock`] error. /// /// [`Poisoned`]: TryLockError::Poisoned /// [`WouldBlock`]: TryLockError::WouldBlock diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 161d2789c27ef..9d521ab14cbf3 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -199,12 +199,12 @@ impl RwLock { /// /// # Errors /// - /// This function will return the error [`Poisoned`] if the RwLock is poisoned. + /// This function will return the [`Poisoned`] error if the RwLock is poisoned. /// An RwLock is poisoned whenever a writer panics while holding an exclusive /// lock. `Poisoned` will only be returned if the lock would have otherwise been /// acquired. /// - /// This function will return the error [`WouldBlock`] if the RwLock could not + /// This function will return the [`WouldBlock`] error if the RwLock could not /// be acquired because it was already locked exclusively. /// /// [`Poisoned`]: TryLockError::Poisoned @@ -287,12 +287,12 @@ impl RwLock { /// /// # Errors /// - /// This function will return the error [`Poisoned`] if the RwLock is + /// This function will return the [`Poisoned`] error if the RwLock is /// poisoned. An RwLock is poisoned whenever a writer panics while holding /// an exclusive lock. `Poisoned` will only be returned if the lock would have /// otherwise been acquired. /// - /// This function will return the error [`WouldBlock`] if the RwLock could not + /// This function will return the [`WouldBlock`] error if the RwLock could not /// be acquired because it was already locked exclusively. /// /// [`Poisoned`]: TryLockError::Poisoned From 1c1d4f907d1aa903a5fecae3fa75298042f5d8d9 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Mon, 24 May 2021 16:50:01 -0400 Subject: [PATCH 30/70] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test THIR unsafeck too Co-authored-by: Léo Lanteri Thauvin --- .../issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs index b0d738855d731..72f7b67477712 100644 --- a/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs +++ b/src/test/ui/unsafe/issue-85435-unsafe-op-in-let-under-unsafe-under-closure.rs @@ -1,4 +1,6 @@ // check-pass +// revisions: mir thir +// [thir]compile-flags: -Z thir-unsafeck // This is issue #85435. But the real story is reflected in issue #85561, where // a bug in the implementation of feature(capture_disjoint_fields) () was From b63f7f9965c88314e3a83a2fcd57685c48fbade4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Mon, 24 May 2021 14:29:44 -0700 Subject: [PATCH 31/70] Demote ControlFlow::{from|into}_try to pub(crate) --- library/core/src/ops/control_flow.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index dbb51540bd475..419675cf641c3 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -186,9 +186,8 @@ impl ControlFlow { #[cfg(bootstrap)] impl ControlFlow { /// Create a `ControlFlow` from any type implementing `Try`. - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn from_try(r: R) -> Self { + pub(crate) fn from_try(r: R) -> Self { match R::into_result(r) { Ok(v) => ControlFlow::Continue(v), Err(v) => ControlFlow::Break(R::from_error(v)), @@ -196,9 +195,8 @@ impl ControlFlow { } /// Convert a `ControlFlow` into any type implementing `Try`; - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn into_try(self) -> R { + pub(crate) fn into_try(self) -> R { match self { ControlFlow::Continue(v) => R::from_ok(v), ControlFlow::Break(v) => v, @@ -206,12 +204,14 @@ impl ControlFlow { } } +/// These are used only as part of implementing the iterator adapters. +/// They have mediocre names and non-obvious semantics, so aren't +/// currently on a path to potential stabilization. #[cfg(not(bootstrap))] impl ControlFlow { /// Create a `ControlFlow` from any type implementing `Try`. - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn from_try(r: R) -> Self { + pub(crate) fn from_try(r: R) -> Self { match R::branch(r) { ControlFlow::Continue(v) => ControlFlow::Continue(v), ControlFlow::Break(v) => ControlFlow::Break(R::from_residual(v)), @@ -219,9 +219,8 @@ impl ControlFlow { } /// Convert a `ControlFlow` into any type implementing `Try`; - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn into_try(self) -> R { + pub(crate) fn into_try(self) -> R { match self { ControlFlow::Continue(v) => R::from_output(v), ControlFlow::Break(v) => v, From ad308264a38531bc8d2179324bac3652a1cda640 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 24 May 2021 17:52:18 -0400 Subject: [PATCH 32/70] Revert "Move llvm submodule updates to rustbuild" --- src/bootstrap/bootstrap.py | 16 ++++++-- src/bootstrap/lib.rs | 10 ----- src/bootstrap/native.rs | 84 +------------------------------------- src/build_helper/lib.rs | 1 - 4 files changed, 13 insertions(+), 98 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index bd5b3797ea825..149a899cef7a0 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -991,20 +991,28 @@ def update_submodules(self): ).decode(default_encoding).splitlines()] filtered_submodules = [] submodules_names = [] + llvm_checked_out = os.path.exists(os.path.join(self.rust_root, "src/llvm-project/.git")) + external_llvm_provided = self.get_toml('llvm-config') or self.downloading_llvm() + llvm_needed = not self.get_toml('codegen-backends', 'rust') \ + or "llvm" in self.get_toml('codegen-backends', 'rust') for module in submodules: - # This is handled by native::Llvm in rustbuild, not here if module.endswith("llvm-project"): - continue + # Don't sync the llvm-project submodule if an external LLVM was + # provided, if we are downloading LLVM or if the LLVM backend is + # not being built. Also, if the submodule has been initialized + # already, sync it anyways so that it doesn't mess up contributor + # pull requests. + if external_llvm_provided or not llvm_needed: + if self.get_toml('lld') != 'true' and not llvm_checked_out: + continue check = self.check_submodule(module, slow_submodules) filtered_submodules.append((module, check)) submodules_names.append(module) recorded = subprocess.Popen(["git", "ls-tree", "HEAD"] + submodules_names, cwd=self.rust_root, stdout=subprocess.PIPE) recorded = recorded.communicate()[0].decode(default_encoding).strip().splitlines() - # { filename: hash } recorded_submodules = {} for data in recorded: - # [mode, kind, hash, filename] data = data.split() recorded_submodules[data[3]] = data[2] for module in filtered_submodules: diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index a351290a4206f..2960dd3df6bf4 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -472,22 +472,12 @@ impl Build { slice::from_ref(&self.build.triple) } - /// If the LLVM submodule has been initialized already, sync it unconditionally. This avoids - /// contributors checking in a submodule change by accident. - pub fn maybe_update_llvm_submodule(&self) { - if self.in_tree_llvm_info.is_git() { - native::update_llvm_submodule(self); - } - } - /// Executes the entire build, as configured by the flags and configuration. pub fn build(&mut self) { unsafe { job::setup(self); } - self.maybe_update_llvm_submodule(); - if let Subcommand::Format { check, paths } = &self.config.cmd { return format::format(self, *check, &paths); } diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 44c281efe22be..bde0a96f03013 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -21,7 +21,7 @@ use build_helper::{output, t}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::util::{self, exe}; -use crate::{Build, GitRepo}; +use crate::GitRepo; use build_helper::up_to_date; pub struct Meta { @@ -91,85 +91,6 @@ pub fn prebuilt_llvm_config( Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() }) } -// modified from `check_submodule` and `update_submodule` in bootstrap.py -pub(crate) fn update_llvm_submodule(build: &Build) { - let llvm_project = &Path::new("src").join("llvm-project"); - - fn dir_is_empty(dir: &Path) -> bool { - t!(std::fs::read_dir(dir)).next().is_none() - } - - // NOTE: The check for the empty directory is here because when running x.py - // the first time, the llvm submodule won't be checked out. Check it out - // now so we can build it. - if !build.in_tree_llvm_info.is_git() && !dir_is_empty(&build.config.src.join(llvm_project)) { - return; - } - - // check_submodule - let checked_out = if build.config.fast_submodules { - Some(output( - Command::new("git") - .args(&["rev-parse", "HEAD"]) - .current_dir(build.config.src.join(llvm_project)), - )) - } else { - None - }; - - // update_submodules - let recorded = output( - Command::new("git") - .args(&["ls-tree", "HEAD"]) - .arg(llvm_project) - .current_dir(&build.config.src), - ); - let hash = - recorded.split(' ').nth(2).unwrap_or_else(|| panic!("unexpected output `{}`", recorded)); - - // update_submodule - if let Some(llvm_hash) = checked_out { - if hash == llvm_hash { - // already checked out - return; - } - } - - println!("Updating submodule {}", llvm_project.display()); - build.run( - Command::new("git") - .args(&["submodule", "-q", "sync"]) - .arg(llvm_project) - .current_dir(&build.config.src), - ); - - // Try passing `--progress` to start, then run git again without if that fails. - let update = |progress: bool| { - let mut git = Command::new("git"); - git.args(&["submodule", "update", "--init", "--recursive"]); - if progress { - git.arg("--progress"); - } - git.arg(llvm_project).current_dir(&build.config.src); - git - }; - // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails. - if !update(true).status().map_or(false, |status| status.success()) { - build.run(&mut update(false)); - } - - build.run( - Command::new("git") - .args(&["reset", "-q", "--hard"]) - .current_dir(build.config.src.join(llvm_project)), - ); - build.run( - Command::new("git") - .args(&["clean", "-qdfx"]) - .current_dir(build.config.src.join(llvm_project)), - ); -} - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Llvm { pub target: TargetSelection, @@ -207,9 +128,6 @@ impl Step for Llvm { Err(m) => m, }; - if !builder.config.dry_run { - update_llvm_submodule(builder); - } if builder.config.llvm_link_shared && (target.contains("windows") || target.contains("apple-darwin")) { diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index b1ec072f3f8aa..80f804174ed08 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -130,7 +130,6 @@ pub fn make(host: &str) -> PathBuf { } } -#[track_caller] pub fn output(cmd: &mut Command) -> String { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, From e238ee31d4d613da9458a84ad200195518b1bd39 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Mon, 24 May 2021 23:34:12 +0100 Subject: [PATCH 33/70] Update cc Recent commits to cc have helped to address #83043 and #43468 --- Cargo.lock | 4 ++-- compiler/rustc_codegen_ssa/Cargo.toml | 4 ++-- compiler/rustc_llvm/Cargo.toml | 2 +- library/profiler_builtins/Cargo.toml | 2 +- library/unwind/Cargo.toml | 2 +- src/bootstrap/Cargo.toml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62734bfaf629f..d0607fe4cf168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,9 +441,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" dependencies = [ "jobserver", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 68f40d5f86395..3a677a2437c57 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -9,7 +9,7 @@ test = false [dependencies] bitflags = "1.2.1" -cc = "1.0.67" +cc = "1.0.68" itertools = "0.9" tracing = "0.1" libc = "0.2.50" @@ -24,7 +24,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_apfloat = { path = "../rustc_apfloat" } rustc_attr = { path = "../rustc_attr" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } -rustc_data_structures = { path = "../rustc_data_structures"} +rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 7a34788de91a7..3fca2e1ccb97b 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -13,4 +13,4 @@ libc = "0.2.73" [build-dependencies] build_helper = { path = "../../src/build_helper" } -cc = "1.0.67" +cc = "1.0.68" diff --git a/library/profiler_builtins/Cargo.toml b/library/profiler_builtins/Cargo.toml index 474058a547fd3..7b7ca8029b49d 100644 --- a/library/profiler_builtins/Cargo.toml +++ b/library/profiler_builtins/Cargo.toml @@ -14,4 +14,4 @@ core = { path = "../core" } compiler_builtins = { version = "0.1.0", features = ['rustc-dep-of-std'] } [build-dependencies] -cc = "1.0.67" +cc = "1.0.68" diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index f42ded62585e2..9dac1f356578d 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -21,7 +21,7 @@ compiler_builtins = "0.1.0" cfg-if = "0.1.8" [build-dependencies] -cc = "1.0.67" +cc = "1.0.68" [features] llvm-libunwind = [] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index a74df97a5c767..8445d811e0f39 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -40,7 +40,7 @@ cmake = "0.1.38" filetime = "0.2" num_cpus = "1.0" getopts = "0.2.19" -cc = "1.0.67" +cc = "1.0.68" libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" From e9e6e66dd81c0c6c58efc2d70c54556e43045a51 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 24 May 2021 16:24:27 -0700 Subject: [PATCH 34/70] Optimize linkchecker by caching all filesystem access. This should improve performance 2-3x depending on the system. --- src/tools/linkchecker/main.rs | 386 +++++++++++++++++++--------------- 1 file changed, 214 insertions(+), 172 deletions(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 7df4f5a9c46d5..076b3653583b7 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -14,10 +14,11 @@ //! A few exceptions are allowed as there's known bugs in rustdoc, but this //! should catch the majority of "broken link" cases. -use std::collections::hash_map::Entry; +use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::env; use std::fs; +use std::io::ErrorKind; use std::path::{Component, Path, PathBuf}; use std::rc::Rc; use std::time::Instant; @@ -25,8 +26,6 @@ use std::time::Instant; use once_cell::sync::Lazy; use regex::Regex; -use crate::Redirect::*; - // Add linkcheck exceptions here // If at all possible you should use intra-doc links to avoid linkcheck issues. These // are cases where that does not work @@ -88,11 +87,10 @@ macro_rules! t { } fn main() { - let docs = env::args_os().nth(1).unwrap(); + let docs = env::args_os().nth(1).expect("doc path should be first argument"); let docs = env::current_dir().unwrap().join(docs); - let mut checker = Checker { - root: docs.clone(), - cache: HashMap::new(), + let mut checker = Checker { root: docs.clone(), cache: HashMap::new() }; + let mut report = Report { errors: 0, start: Instant::now(), html_files: 0, @@ -102,9 +100,9 @@ fn main() { links_ignored_exception: 0, intra_doc_exceptions: 0, }; - checker.walk(&docs); - checker.report(); - if checker.errors != 0 { + checker.walk(&docs, &mut report); + report.report(); + if report.errors != 0 { println!("found some broken links"); std::process::exit(1); } @@ -113,6 +111,9 @@ fn main() { struct Checker { root: PathBuf, cache: Cache, +} + +struct Report { errors: u32, start: Instant, html_files: u32, @@ -123,23 +124,27 @@ struct Checker { intra_doc_exceptions: u32, } -#[derive(Debug)] -pub enum LoadError { - BrokenRedirect(PathBuf, std::io::Error), - IsRedirect, +/// A cache entry. +enum FileEntry { + /// An HTML file. + /// + /// This includes the contents of the HTML file, and an optional set of + /// HTML IDs. The IDs are used for checking fragments. The are computed + /// as-needed. The source is discarded (replaced with an empty string) + /// after the file has been checked, to conserve on memory. + HtmlFile { source: Rc, ids: RefCell> }, + /// This file is an HTML redirect to the given local path. + Redirect { target: PathBuf }, + /// This is not an HTML file. + OtherFile, + /// This is a directory. + Dir, + /// The file doesn't exist. + Missing, } -enum Redirect { - SkipRedirect, - FromRedirect(bool), -} - -struct FileEntry { - source: Rc, - ids: HashSet, -} - -type Cache = HashMap; +/// A cache to speed up file access. +type Cache = HashMap; fn small_url_encode(s: &str) -> String { s.replace("<", "%3C") @@ -156,62 +161,36 @@ fn small_url_encode(s: &str) -> String { .replace("\"", "%22") } -impl FileEntry { - fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut u32) { - if self.ids.is_empty() { - with_attrs_in_source(contents, " id", |fragment, i, _| { - let frag = fragment.trim_start_matches("#").to_owned(); - let encoded = small_url_encode(&frag); - if !self.ids.insert(frag) { - *errors += 1; - println!("{}:{}: id is not unique: `{}`", file.display(), i, fragment); - } - // Just in case, we also add the encoded id. - self.ids.insert(encoded); - }); - } - } -} - impl Checker { - fn walk(&mut self, dir: &Path) { + /// Primary entry point for walking the filesystem to find HTML files to check. + fn walk(&mut self, dir: &Path, report: &mut Report) { for entry in t!(dir.read_dir()).map(|e| t!(e)) { let path = entry.path(); let kind = t!(entry.file_type()); if kind.is_dir() { - self.walk(&path); + self.walk(&path, report); } else { - let pretty_path = self.check(&path); - if let Some(pretty_path) = pretty_path { - let entry = self.cache.get_mut(&pretty_path).unwrap(); - // we don't need the source anymore, - // so drop to reduce memory-usage - entry.source = Rc::new(String::new()); - } + self.check(&path, report); } } } - fn check(&mut self, file: &Path) -> Option { - // Ignore non-HTML files. - if file.extension().and_then(|s| s.to_str()) != Some("html") { - return None; - } - self.html_files += 1; - - let res = self.load_file(file, SkipRedirect); - let (pretty_file, contents) = match res { - Ok(res) => res, - Err(_) => return None, + /// Checks a single file. + fn check(&mut self, file: &Path, report: &mut Report) { + let (pretty_path, entry) = self.load_file(file, report); + let source = match entry { + FileEntry::Missing => panic!("missing file {:?} while walking", file), + FileEntry::Dir => unreachable!("never with `check` path"), + FileEntry::OtherFile => return, + FileEntry::Redirect { .. } => return, + FileEntry::HtmlFile { source, ids } => { + parse_ids(&mut ids.borrow_mut(), &pretty_path, source, report); + source.clone() + } }; - self.cache.get_mut(&pretty_file).unwrap().parse_ids( - &pretty_file, - &contents, - &mut self.errors, - ); // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' - with_attrs_in_source(&contents, " href", |url, i, base| { + with_attrs_in_source(&source, " href", |url, i, base| { // Ignore external URLs if url.starts_with("http:") || url.starts_with("https:") @@ -220,10 +199,10 @@ impl Checker { || url.starts_with("irc:") || url.starts_with("data:") { - self.links_ignored_external += 1; + report.links_ignored_external += 1; return; } - self.links_checked += 1; + report.links_checked += 1; let (url, fragment) = match url.split_once('#') { None => (url, None), Some((url, fragment)) => (url, Some(fragment)), @@ -242,10 +221,10 @@ impl Checker { // Avoid absolute paths as they make the docs not // relocatable by making assumptions on where the docs // are hosted relative to the site root. - self.errors += 1; + report.errors += 1; println!( "{}:{}: absolute path - {}", - pretty_file.display(), + pretty_path, i + 1, Path::new(base).join(url).display() ); @@ -262,138 +241,165 @@ impl Checker { } } - // Alright, if we've found a file name then this file had better - // exist! If it doesn't then we register and print an error. - if path.exists() { - if path.is_dir() { + let (target_pretty_path, target_entry) = self.load_file(&path, report); + let (target_source, target_ids) = match target_entry { + FileEntry::Missing => { + if is_exception(file, &target_pretty_path) { + report.links_ignored_exception += 1; + } else { + report.errors += 1; + println!( + "{}:{}: broken link - `{}`", + pretty_path, + i + 1, + target_pretty_path + ); + } + return; + } + FileEntry::Dir => { // Links to directories show as directory listings when viewing // the docs offline so it's best to avoid them. - self.errors += 1; - let pretty_path = path.strip_prefix(&self.root).unwrap_or(&path); + report.errors += 1; println!( - "{}:{}: directory link - {}", - pretty_file.display(), + "{}:{}: directory link to `{}` \ + (directory links should use index.html instead)", + pretty_path, i + 1, - pretty_path.display() + target_pretty_path ); return; } - if let Some(extension) = path.extension() { - // Ignore none HTML files. - if extension != "html" { - return; + FileEntry::OtherFile => return, + FileEntry::Redirect { target } => { + let t = target.clone(); + drop(target); + let (target, redir_entry) = self.load_file(&t, report); + match redir_entry { + FileEntry::Missing => { + report.errors += 1; + println!( + "{}:{}: broken redirect from `{}` to `{}`", + pretty_path, + i + 1, + target_pretty_path, + target + ); + return; + } + FileEntry::Redirect { target } => { + // Redirect to a redirect, this link checker + // currently doesn't support this, since it would + // require cycle checking, etc. + report.errors += 1; + println!( + "{}:{}: redirect from `{}` to `{}` \ + which is also a redirect (not supported)", + pretty_path, + i + 1, + target_pretty_path, + target.display() + ); + return; + } + FileEntry::Dir => { + report.errors += 1; + println!( + "{}:{}: redirect from `{}` to `{}` \ + which is a directory \ + (directory links should use index.html instead)", + pretty_path, + i + 1, + target_pretty_path, + target + ); + return; + } + FileEntry::OtherFile => return, + FileEntry::HtmlFile { source, ids } => (source, ids), } } - let res = self.load_file(&path, FromRedirect(false)); - let (pretty_path, contents) = match res { - Ok(res) => res, - Err(LoadError::BrokenRedirect(target, _)) => { - self.errors += 1; - println!( - "{}:{}: broken redirect to {}", - pretty_file.display(), - i + 1, - target.display() - ); - return; - } - Err(LoadError::IsRedirect) => unreachable!(), - }; + FileEntry::HtmlFile { source, ids } => (source, ids), + }; - if let Some(ref fragment) = fragment { - // Fragments like `#1-6` are most likely line numbers to be - // interpreted by javascript, so we're ignoring these - if fragment.splitn(2, '-').all(|f| f.chars().all(|c| c.is_numeric())) { - return; - } + // Alright, if we've found an HTML file for the target link. If + // this is a fragment link, also check that the `id` exists. + if let Some(ref fragment) = fragment { + // Fragments like `#1-6` are most likely line numbers to be + // interpreted by javascript, so we're ignoring these + if fragment.splitn(2, '-').all(|f| f.chars().all(|c| c.is_numeric())) { + return; + } - // These appear to be broken in mdbook right now? - if fragment.starts_with('-') { - return; - } + // These appear to be broken in mdbook right now? + if fragment.starts_with('-') { + return; + } - let entry = self.cache.get_mut(&pretty_path).unwrap(); - entry.parse_ids(&pretty_path, &contents, &mut self.errors); + parse_ids(&mut target_ids.borrow_mut(), &pretty_path, target_source, report); - if entry.ids.contains(*fragment) { - return; - } - - if is_exception(file, &format!("#{}", fragment)) { - self.links_ignored_exception += 1; - } else { - self.errors += 1; - print!("{}:{}: broken link fragment ", pretty_file.display(), i + 1); - println!("`#{}` pointing to `{}`", fragment, pretty_path.display()); - }; + if target_ids.borrow().contains(*fragment) { + return; } - } else { - let pretty_path = path.strip_prefix(&self.root).unwrap_or(&path); - if is_exception(file, pretty_path.to_str().unwrap()) { + + if is_exception(file, &format!("#{}", fragment)) { + report.links_ignored_exception += 1; } else { - self.errors += 1; - print!("{}:{}: broken link - ", pretty_file.display(), i + 1); - println!("{}", pretty_path.display()); - } + report.errors += 1; + print!("{}:{}: broken link fragment ", pretty_path, i + 1); + println!("`#{}` pointing to `{}`", fragment, pretty_path); + }; } }); // Search for intra-doc links that rustdoc didn't warn about // FIXME(#77199, 77200) Rustdoc should just warn about these directly. // NOTE: only looks at one line at a time; in practice this should find most links - for (i, line) in contents.lines().enumerate() { + for (i, line) in source.lines().enumerate() { for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) { if is_intra_doc_exception(file, &broken_link[1]) { - self.intra_doc_exceptions += 1; + report.intra_doc_exceptions += 1; } else { - self.errors += 1; - print!("{}:{}: broken intra-doc link - ", pretty_file.display(), i + 1); + report.errors += 1; + print!("{}:{}: broken intra-doc link - ", pretty_path, i + 1); println!("{}", &broken_link[0]); } } } - Some(pretty_file) + // we don't need the source anymore, + // so drop to reduce memory-usage + match self.cache.get_mut(&pretty_path).unwrap() { + FileEntry::HtmlFile { source, .. } => *source = Rc::new(String::new()), + _ => unreachable!("must be html file"), + } } - fn load_file( - &mut self, - file: &Path, - redirect: Redirect, - ) -> Result<(PathBuf, Rc), LoadError> { - let pretty_file = PathBuf::from(file.strip_prefix(&self.root).unwrap_or(&file)); - - let (maybe_redirect, contents) = match self.cache.entry(pretty_file.clone()) { - Entry::Occupied(entry) => (None, entry.get().source.clone()), - Entry::Vacant(entry) => { - let contents = match fs::read_to_string(file) { - Ok(s) => Rc::new(s), - Err(err) => { - return Err(if let FromRedirect(true) = redirect { - LoadError::BrokenRedirect(file.to_path_buf(), err) - } else { - panic!("error loading {}: {}", file.display(), err); - }); - } - }; - - let maybe = maybe_redirect(&contents); - if maybe.is_some() { - self.html_redirects += 1; - if let SkipRedirect = redirect { - return Err(LoadError::IsRedirect); + /// Load a file from disk, or from the cache if available. + fn load_file(&mut self, file: &Path, report: &mut Report) -> (String, &FileEntry) { + let pretty_path = + file.strip_prefix(&self.root).unwrap_or(&file).to_str().unwrap().to_string(); + + let entry = + self.cache.entry(pretty_path.clone()).or_insert_with(|| match fs::metadata(file) { + Ok(metadata) if metadata.is_dir() => FileEntry::Dir, + Ok(_) => { + if file.extension().and_then(|s| s.to_str()) != Some("html") { + FileEntry::OtherFile + } else { + report.html_files += 1; + load_html_file(file, report) } - } else { - entry.insert(FileEntry { source: contents.clone(), ids: HashSet::new() }); } - (maybe, contents) - } - }; - match maybe_redirect.map(|url| file.parent().unwrap().join(url)) { - Some(redirect_file) => self.load_file(&redirect_file, FromRedirect(true)), - None => Ok((pretty_file, contents)), - } + Err(e) if e.kind() == ErrorKind::NotFound => FileEntry::Missing, + Err(e) => { + panic!("unexpected read error for {}: {}", file.display(), e); + } + }); + (pretty_path, entry) } +} +impl Report { fn report(&self) { println!("checked links in: {:.1}s", self.start.elapsed().as_secs_f64()); println!("number of HTML files scanned: {}", self.html_files); @@ -406,6 +412,25 @@ impl Checker { } } +fn load_html_file(file: &Path, report: &mut Report) -> FileEntry { + let source = match fs::read_to_string(file) { + Ok(s) => Rc::new(s), + Err(err) => { + // This usually should not fail since `metadata` was already + // called successfully on this file. + panic!("unexpected read error for {}: {}", file.display(), err); + } + }; + match maybe_redirect(&source) { + Some(target) => { + report.html_redirects += 1; + let target = file.parent().unwrap().join(target); + FileEntry::Redirect { target } + } + None => FileEntry::HtmlFile { source: source.clone(), ids: RefCell::new(HashSet::new()) }, + } +} + fn is_intra_doc_exception(file: &Path, link: &str) -> bool { if let Some(entry) = INTRA_DOC_LINK_EXCEPTIONS.iter().find(|&(f, _)| file.ends_with(f)) { entry.1.is_empty() || entry.1.contains(&link) @@ -432,6 +457,8 @@ fn is_exception(file: &Path, link: &str) -> bool { } } +/// If the given HTML file contents is an HTML redirect, this returns the +/// destination path given in the redirect. fn maybe_redirect(source: &str) -> Option { const REDIRECT: &str = "

Redirecting to (contents: &str, attr: &str, } } } + +fn parse_ids(ids: &mut HashSet, file: &str, source: &str, report: &mut Report) { + if ids.is_empty() { + with_attrs_in_source(source, " id", |fragment, i, _| { + let frag = fragment.trim_start_matches("#").to_owned(); + let encoded = small_url_encode(&frag); + if !ids.insert(frag) { + report.errors += 1; + println!("{}:{}: id is not unique: `{}`", file, i, fragment); + } + // Just in case, we also add the encoded id. + ids.insert(encoded); + }); + } +} From b6532ebeeb31f3e1236e23bffbd36327979458dc Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 24 May 2021 16:25:23 -0700 Subject: [PATCH 35/70] Add some tests for the linkchecker. --- .../linkchecker/tests/basic_broken/foo.html | 5 ++ .../tests/broken_fragment_local/foo.html | 5 ++ .../tests/broken_fragment_remote/bar.html | 4 + .../broken_fragment_remote/inner/foo.html | 5 ++ .../linkchecker/tests/broken_redir/foo.html | 5 ++ .../tests/broken_redir/redir-bad.html | 10 +++ src/tools/linkchecker/tests/checks.rs | 77 +++++++++++++++++++ .../linkchecker/tests/directory_link/foo.html | 5 ++ .../tests/directory_link/somedir/index.html | 4 + .../linkchecker/tests/redirect_loop/foo.html | 5 ++ .../tests/redirect_loop/redir-bad.html | 10 +++ .../linkchecker/tests/valid/inner/bar.html | 7 ++ .../linkchecker/tests/valid/inner/foo.html | 14 ++++ .../tests/valid/inner/redir-bad.html | 11 +++ .../tests/valid/inner/redir-target.html | 5 ++ .../linkchecker/tests/valid/inner/redir.html | 10 +++ src/tools/linkchecker/tests/valid/outer.html | 5 ++ 17 files changed, 187 insertions(+) create mode 100644 src/tools/linkchecker/tests/basic_broken/foo.html create mode 100644 src/tools/linkchecker/tests/broken_fragment_local/foo.html create mode 100644 src/tools/linkchecker/tests/broken_fragment_remote/bar.html create mode 100644 src/tools/linkchecker/tests/broken_fragment_remote/inner/foo.html create mode 100644 src/tools/linkchecker/tests/broken_redir/foo.html create mode 100644 src/tools/linkchecker/tests/broken_redir/redir-bad.html create mode 100644 src/tools/linkchecker/tests/checks.rs create mode 100644 src/tools/linkchecker/tests/directory_link/foo.html create mode 100644 src/tools/linkchecker/tests/directory_link/somedir/index.html create mode 100644 src/tools/linkchecker/tests/redirect_loop/foo.html create mode 100644 src/tools/linkchecker/tests/redirect_loop/redir-bad.html create mode 100644 src/tools/linkchecker/tests/valid/inner/bar.html create mode 100644 src/tools/linkchecker/tests/valid/inner/foo.html create mode 100644 src/tools/linkchecker/tests/valid/inner/redir-bad.html create mode 100644 src/tools/linkchecker/tests/valid/inner/redir-target.html create mode 100644 src/tools/linkchecker/tests/valid/inner/redir.html create mode 100644 src/tools/linkchecker/tests/valid/outer.html diff --git a/src/tools/linkchecker/tests/basic_broken/foo.html b/src/tools/linkchecker/tests/basic_broken/foo.html new file mode 100644 index 0000000000000..cb27c55c9fe94 --- /dev/null +++ b/src/tools/linkchecker/tests/basic_broken/foo.html @@ -0,0 +1,5 @@ + + +test + + diff --git a/src/tools/linkchecker/tests/broken_fragment_local/foo.html b/src/tools/linkchecker/tests/broken_fragment_local/foo.html new file mode 100644 index 0000000000000..66c457ad01f47 --- /dev/null +++ b/src/tools/linkchecker/tests/broken_fragment_local/foo.html @@ -0,0 +1,5 @@ + + +test + + diff --git a/src/tools/linkchecker/tests/broken_fragment_remote/bar.html b/src/tools/linkchecker/tests/broken_fragment_remote/bar.html new file mode 100644 index 0000000000000..7879e1ce9fd77 --- /dev/null +++ b/src/tools/linkchecker/tests/broken_fragment_remote/bar.html @@ -0,0 +1,4 @@ + + + + diff --git a/src/tools/linkchecker/tests/broken_fragment_remote/inner/foo.html b/src/tools/linkchecker/tests/broken_fragment_remote/inner/foo.html new file mode 100644 index 0000000000000..7683060b3a6fa --- /dev/null +++ b/src/tools/linkchecker/tests/broken_fragment_remote/inner/foo.html @@ -0,0 +1,5 @@ + + +test + + diff --git a/src/tools/linkchecker/tests/broken_redir/foo.html b/src/tools/linkchecker/tests/broken_redir/foo.html new file mode 100644 index 0000000000000..bd3e3ad3343c6 --- /dev/null +++ b/src/tools/linkchecker/tests/broken_redir/foo.html @@ -0,0 +1,5 @@ + + + bad redir + + diff --git a/src/tools/linkchecker/tests/broken_redir/redir-bad.html b/src/tools/linkchecker/tests/broken_redir/redir-bad.html new file mode 100644 index 0000000000000..3e376629f74fe --- /dev/null +++ b/src/tools/linkchecker/tests/broken_redir/redir-bad.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to sometarget...

+ + + diff --git a/src/tools/linkchecker/tests/checks.rs b/src/tools/linkchecker/tests/checks.rs new file mode 100644 index 0000000000000..c6ec999e5cfe2 --- /dev/null +++ b/src/tools/linkchecker/tests/checks.rs @@ -0,0 +1,77 @@ +use std::path::Path; +use std::process::{Command, ExitStatus}; + +fn run(dirname: &str) -> (ExitStatus, String, String) { + let output = Command::new(env!("CARGO_BIN_EXE_linkchecker")) + .current_dir(Path::new(env!("CARGO_MANIFEST_DIR")).join("tests")) + .arg(dirname) + .output() + .unwrap(); + let stdout = String::from_utf8(output.stdout).unwrap(); + let stderr = String::from_utf8(output.stderr).unwrap(); + (output.status, stdout, stderr) +} + +fn broken_test(dirname: &str, expected: &str) { + let (status, stdout, stderr) = run(dirname); + assert!(!status.success()); + if !stdout.contains(expected) { + panic!( + "stdout did not contain expected text: {}\n\ + --- stdout:\n\ + {}\n\ + --- stderr:\n\ + {}\n", + expected, stdout, stderr + ); + } +} + +fn valid_test(dirname: &str) { + let (status, stdout, stderr) = run(dirname); + if !status.success() { + panic!( + "test did not succeed as expected\n\ + --- stdout:\n\ + {}\n\ + --- stderr:\n\ + {}\n", + stdout, stderr + ); + } +} + +#[test] +fn valid() { + valid_test("valid/inner"); +} + +#[test] +fn basic_broken() { + broken_test("basic_broken", "bar.html"); +} + +#[test] +fn broken_fragment_local() { + broken_test("broken_fragment_local", "#somefrag"); +} + +#[test] +fn broken_fragment_remote() { + broken_test("broken_fragment_remote/inner", "#somefrag"); +} + +#[test] +fn broken_redir() { + broken_test("broken_redir", "sometarget"); +} + +#[test] +fn directory_link() { + broken_test("directory_link", "somedir"); +} + +#[test] +fn redirect_loop() { + broken_test("redirect_loop", "redir-bad.html"); +} diff --git a/src/tools/linkchecker/tests/directory_link/foo.html b/src/tools/linkchecker/tests/directory_link/foo.html new file mode 100644 index 0000000000000..40a8461b86cf5 --- /dev/null +++ b/src/tools/linkchecker/tests/directory_link/foo.html @@ -0,0 +1,5 @@ + + + dir link + + diff --git a/src/tools/linkchecker/tests/directory_link/somedir/index.html b/src/tools/linkchecker/tests/directory_link/somedir/index.html new file mode 100644 index 0000000000000..7879e1ce9fd77 --- /dev/null +++ b/src/tools/linkchecker/tests/directory_link/somedir/index.html @@ -0,0 +1,4 @@ + + + + diff --git a/src/tools/linkchecker/tests/redirect_loop/foo.html b/src/tools/linkchecker/tests/redirect_loop/foo.html new file mode 100644 index 0000000000000..bee58b212b557 --- /dev/null +++ b/src/tools/linkchecker/tests/redirect_loop/foo.html @@ -0,0 +1,5 @@ + + + loop link + + diff --git a/src/tools/linkchecker/tests/redirect_loop/redir-bad.html b/src/tools/linkchecker/tests/redirect_loop/redir-bad.html new file mode 100644 index 0000000000000..fe7780e6739bf --- /dev/null +++ b/src/tools/linkchecker/tests/redirect_loop/redir-bad.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to redir-bad.html...

+ + + diff --git a/src/tools/linkchecker/tests/valid/inner/bar.html b/src/tools/linkchecker/tests/valid/inner/bar.html new file mode 100644 index 0000000000000..4b500d78b76e4 --- /dev/null +++ b/src/tools/linkchecker/tests/valid/inner/bar.html @@ -0,0 +1,7 @@ + + + +

Bar

+ + + diff --git a/src/tools/linkchecker/tests/valid/inner/foo.html b/src/tools/linkchecker/tests/valid/inner/foo.html new file mode 100644 index 0000000000000..3c6a7483bcd46 --- /dev/null +++ b/src/tools/linkchecker/tests/valid/inner/foo.html @@ -0,0 +1,14 @@ + + + test local frag + remote link + remote link with fragment + this book + this book with fragment + external links not validated + Redirect + +

Local

+ + + diff --git a/src/tools/linkchecker/tests/valid/inner/redir-bad.html b/src/tools/linkchecker/tests/valid/inner/redir-bad.html new file mode 100644 index 0000000000000..d21336e7e738b --- /dev/null +++ b/src/tools/linkchecker/tests/valid/inner/redir-bad.html @@ -0,0 +1,11 @@ + + + + + + +

Redirecting to xxx...

+ + These files are skipped, but probably shouldn't be. + + diff --git a/src/tools/linkchecker/tests/valid/inner/redir-target.html b/src/tools/linkchecker/tests/valid/inner/redir-target.html new file mode 100644 index 0000000000000..bd59884a01ecf --- /dev/null +++ b/src/tools/linkchecker/tests/valid/inner/redir-target.html @@ -0,0 +1,5 @@ + + +

Redir

+ + diff --git a/src/tools/linkchecker/tests/valid/inner/redir.html b/src/tools/linkchecker/tests/valid/inner/redir.html new file mode 100644 index 0000000000000..1808b23aed856 --- /dev/null +++ b/src/tools/linkchecker/tests/valid/inner/redir.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to redir-target.html...

+ + + diff --git a/src/tools/linkchecker/tests/valid/outer.html b/src/tools/linkchecker/tests/valid/outer.html new file mode 100644 index 0000000000000..35f799f202317 --- /dev/null +++ b/src/tools/linkchecker/tests/valid/outer.html @@ -0,0 +1,5 @@ + + + + + From 37588e9e1b67eca4edd4a1972040ba449c51e887 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 May 2021 20:06:02 +0800 Subject: [PATCH 36/70] Document shared_from_cow functions --- library/alloc/src/rc.rs | 12 ++++++++++++ library/alloc/src/sync.rs | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 800952f7a5ece..77994a3f3a14a 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1859,6 +1859,18 @@ where B: ToOwned + ?Sized, Rc: From<&'a B> + From, { + /// Create a reference-counted pointer from + /// a clone-on-write pointer by copying its content. + /// + /// # Example + /// + /// ```rust + /// # use std::rc::Rc; + /// # use std::borrow::Cow; + /// let cow: Cow = Cow::Borrowed("eggplant"); + /// let shared: Rc = Rc::from(cow); + /// assert_eq!("eggplant", &shared[..]); + /// ``` #[inline] fn from(cow: Cow<'a, B>) -> Rc { match cow { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 17927f5f5fdc4..72001ad1b5633 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2413,6 +2413,18 @@ where B: ToOwned + ?Sized, Arc: From<&'a B> + From, { + /// Create an atomically reference-counted pointer from + /// a clone-on-write pointer by copying its content. + /// + /// # Example + /// + /// ```rust + /// # use std::sync::Arc; + /// # use std::borrow::Cow; + /// let cow: Cow = Cow::Borrowed("eggplant"); + /// let shared: Arc = Arc::from(cow); + /// assert_eq!("eggplant", &shared[..]); + /// ``` #[inline] fn from(cow: Cow<'a, B>) -> Arc { match cow { From 79a5b12a89c85e0402548d8b14670268db2455d1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 25 May 2021 06:04:22 -0700 Subject: [PATCH 37/70] Fix tasklist example in rustdoc book. --- src/doc/rustdoc/src/how-to-write-documentation.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/doc/rustdoc/src/how-to-write-documentation.md b/src/doc/rustdoc/src/how-to-write-documentation.md index 688be7aedea38..f89495cca3a31 100644 --- a/src/doc/rustdoc/src/how-to-write-documentation.md +++ b/src/doc/rustdoc/src/how-to-write-documentation.md @@ -229,15 +229,13 @@ Example: ```md - [x] Complete task -- [ ] IncComplete task +- [ ] Incomplete task ``` -This will render as +This will render as: -
    -
  • -
  • -
+> - [x] Complete task +> - [ ] Incomplete task See the specification for the [task list extension] for more details. From 8d954fa589bf4608d4aa56e56b223f0134b16955 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 25 May 2021 15:48:14 +0200 Subject: [PATCH 38/70] Remove arrays/IntoIterator message from Iterator trait. --- library/core/src/iter/traits/iterator.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index e6ed34d3f052b..1eef0f9064c90 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -79,11 +79,6 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} _Self = "std::string::String", label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" ), - on( - _Self = "[]", - label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`", - note = "see for more details" - ), on( _Self = "{integral}", note = "if you want to iterate between `start` until a value `end`, use the exclusive range \ From 87cf2d472646f49245e6a50f04d50ea833796151 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Tue, 25 May 2021 15:57:27 +0200 Subject: [PATCH 39/70] Move stability attribute for methods under the `ip` feature from the module to the methods themselves --- library/std/src/net/ip.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 9b629e19be53d..a8261709cea9f 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1,11 +1,3 @@ -#![unstable( - feature = "ip", - reason = "extra functionality has not been \ - scrutinized to the level that it should \ - be to be stable", - issue = "27709" -)] - // Tests for this module #[cfg(all(test, not(target_os = "emscripten")))] mod tests; @@ -126,6 +118,7 @@ pub struct Ipv6Addr { #[allow(missing_docs)] #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)] +#[unstable(feature = "ip", issue = "27709")] pub enum Ipv6MulticastScope { InterfaceLocal, LinkLocal, @@ -199,6 +192,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ip", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_global(&self) -> bool { match self { @@ -249,6 +243,7 @@ impl IpAddr { /// ); /// ``` #[rustc_const_unstable(feature = "const_ip", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_documentation(&self) -> bool { match self { @@ -549,6 +544,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_global(&self) -> bool { // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two @@ -587,6 +583,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_shared(&self) -> bool { self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000) @@ -620,6 +617,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_ietf_protocol_assignment(&self) -> bool { self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0 @@ -644,6 +642,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_benchmarking(&self) -> bool { self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18 @@ -677,6 +676,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_reserved(&self) -> bool { self.octets()[0] & 240 == 240 && !self.is_broadcast() @@ -1234,6 +1234,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_global(&self) -> bool { match self.multicast_scope() { @@ -1260,6 +1261,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 @@ -1315,6 +1317,7 @@ impl Ipv6Addr { /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_link_local_strict(&self) -> bool { matches!(self.segments(), [0xfe80, 0, 0, 0, ..]) @@ -1369,6 +1372,7 @@ impl Ipv6Addr { /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 @@ -1409,6 +1413,7 @@ impl Ipv6Addr { /// /// [RFC 3879]: https://tools.ietf.org/html/rfc3879 #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_site_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfec0 @@ -1432,6 +1437,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_documentation(&self) -> bool { (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) @@ -1468,6 +1474,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_global(&self) -> bool { !self.is_multicast() @@ -1494,6 +1501,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn multicast_scope(&self) -> Option { if self.is_multicast() { @@ -1555,6 +1563,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn to_ipv4_mapped(&self) -> Option { match self.octets() { From 3ed90e2424fb24f56bba3815dc8033323051b50c Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 25 May 2021 16:44:20 +0200 Subject: [PATCH 40/70] fix matches! and assert_matches! on edition 2021 --- library/core/src/lib.rs | 1 + library/core/src/macros/mod.rs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 337182c0c9f23..a023edaca9e94 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -168,6 +168,7 @@ #![feature(no_coverage)] // rust-lang/rust#84605 #![feature(int_error_matching)] #![deny(unsafe_op_in_unsafe_fn)] +#![deny(or_patterns_back_compat)] // allow using `core::` in intra-doc links #[allow(unused_extern_crates)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index feadf5b4c7c9a..7eb65483b99e7 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -138,7 +138,7 @@ macro_rules! assert_ne { #[unstable(feature = "assert_matches", issue = "82775")] #[allow_internal_unstable(core_panic)] macro_rules! assert_matches { - ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => ({ + ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({ match $left { $( $pattern )|+ $( if $guard )? => {} ref left_val => { @@ -150,7 +150,7 @@ macro_rules! assert_matches { } } }); - ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )?, $($arg:tt)+) => ({ + ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({ match $left { $( $pattern )|+ $( if $guard )? => {} ref left_val => { @@ -315,7 +315,7 @@ macro_rules! debug_assert_matches { #[macro_export] #[stable(feature = "matches_macro", since = "1.42.0")] macro_rules! matches { - ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => { + ($expression:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => { match $expression { $( $pattern )|+ $( if $guard )? => true, _ => false From 0baf89810f36ae5f8efc96041b99d569186d53f9 Mon Sep 17 00:00:00 2001 From: Hoe Hao Cheng Date: Tue, 25 May 2021 22:48:08 +0800 Subject: [PATCH 41/70] Remove num_as_ne_bytes feature --- library/core/src/num/f32.rs | 29 ---------------------------- library/core/src/num/f64.rs | 29 ---------------------------- library/core/src/num/int_macros.rs | 30 ----------------------------- library/core/src/num/uint_macros.rs | 30 ----------------------------- 4 files changed, 118 deletions(-) diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 0d6d919d9984d..77132cddca272 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -854,35 +854,6 @@ impl f32 { self.to_bits().to_ne_bytes() } - /// Return the memory representation of this floating point number as a byte array in - /// native byte order. - /// - /// [`to_ne_bytes`] should be preferred over this whenever possible. - /// - /// [`to_ne_bytes`]: f32::to_ne_bytes - /// - /// # Examples - /// - /// ``` - /// #![feature(num_as_ne_bytes)] - /// let num = 12.5f32; - /// let bytes = num.as_ne_bytes(); - /// assert_eq!( - /// bytes, - /// if cfg!(target_endian = "big") { - /// &[0x41, 0x48, 0x00, 0x00] - /// } else { - /// &[0x00, 0x00, 0x48, 0x41] - /// } - /// ); - /// ``` - #[unstable(feature = "num_as_ne_bytes", issue = "76976")] - #[inline] - pub fn as_ne_bytes(&self) -> &[u8; 4] { - // SAFETY: `f32` is a plain old datatype so we can always transmute to it - unsafe { &*(self as *const Self as *const _) } - } - /// Create a floating point value from its representation as a byte array in big endian. /// /// # Examples diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 42214e7b50de0..4c3f1fd16a0db 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -868,35 +868,6 @@ impl f64 { self.to_bits().to_ne_bytes() } - /// Return the memory representation of this floating point number as a byte array in - /// native byte order. - /// - /// [`to_ne_bytes`] should be preferred over this whenever possible. - /// - /// [`to_ne_bytes`]: f64::to_ne_bytes - /// - /// # Examples - /// - /// ``` - /// #![feature(num_as_ne_bytes)] - /// let num = 12.5f64; - /// let bytes = num.as_ne_bytes(); - /// assert_eq!( - /// bytes, - /// if cfg!(target_endian = "big") { - /// &[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] - /// } else { - /// &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40] - /// } - /// ); - /// ``` - #[unstable(feature = "num_as_ne_bytes", issue = "76976")] - #[inline] - pub fn as_ne_bytes(&self) -> &[u8; 8] { - // SAFETY: `f64` is a plain old datatype so we can always transmute to it - unsafe { &*(self as *const Self as *const _) } - } - /// Create a floating point value from its representation as a byte array in big endian. /// /// # Examples diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 47b2b30563c3a..4af86ed98f26f 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1842,36 +1842,6 @@ macro_rules! int_impl { unsafe { mem::transmute(self) } } - /// Return the memory representation of this integer as a byte array in - /// native byte order. - /// - /// [`to_ne_bytes`] should be preferred over this whenever possible. - /// - /// [`to_ne_bytes`]: Self::to_ne_bytes - /// - /// # Examples - /// - /// ``` - /// #![feature(num_as_ne_bytes)] - #[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")] - /// let bytes = num.as_ne_bytes(); - /// assert_eq!( - /// bytes, - /// if cfg!(target_endian = "big") { - #[doc = concat!(" &", $be_bytes)] - /// } else { - #[doc = concat!(" &", $le_bytes)] - /// } - /// ); - /// ``` - #[unstable(feature = "num_as_ne_bytes", issue = "76976")] - #[inline] - pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::()] { - // SAFETY: integers are plain old datatypes so we can always transmute them to - // arrays of bytes - unsafe { &*(self as *const Self as *const _) } - } - /// Create an integer value from its representation as a byte array in /// big endian. /// diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f9fd28b6a8c24..a525e02d5e184 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1672,36 +1672,6 @@ macro_rules! uint_impl { unsafe { mem::transmute(self) } } - /// Return the memory representation of this integer as a byte array in - /// native byte order. - /// - /// [`to_ne_bytes`] should be preferred over this whenever possible. - /// - /// [`to_ne_bytes`]: Self::to_ne_bytes - /// - /// # Examples - /// - /// ``` - /// #![feature(num_as_ne_bytes)] - #[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")] - /// let bytes = num.as_ne_bytes(); - /// assert_eq!( - /// bytes, - /// if cfg!(target_endian = "big") { - #[doc = concat!(" &", $be_bytes)] - /// } else { - #[doc = concat!(" &", $le_bytes)] - /// } - /// ); - /// ``` - #[unstable(feature = "num_as_ne_bytes", issue = "76976")] - #[inline] - pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::()] { - // SAFETY: integers are plain old datatypes so we can always transmute them to - // arrays of bytes - unsafe { &*(self as *const Self as *const _) } - } - /// Create a native endian integer value from its representation /// as a byte array in big endian. /// From 5d8e6ea7b9e668578917940d2ab1ba1a51b291b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=C3=A9nore=20Bouttefeux?= Date: Tue, 25 May 2021 16:55:30 +0200 Subject: [PATCH 42/70] show list of candidates --- .../rustc_typeck/src/check/method/suggest.rs | 34 ++++++++++++------- src/test/ui/issues/issue-30123.stderr | 3 +- ...ethod-not-found-generic-arg-elision.stderr | 20 ++++++----- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 109cd3e4bc86a..569e871922732 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -517,21 +517,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if inherent_impls_candidate.len() > 0 { inherent_impls_candidate.sort(); inherent_impls_candidate.dedup(); + + // number of type to shows at most. + let limit = if inherent_impls_candidate.len() == 5 { 5 } else { 4 }; let type_candidates = inherent_impls_candidate .iter() - .map(|impl_item| self.tcx.at(span).type_of(*impl_item)) - .collect::>(); - // number of type to shows at most. - let limit = if type_candidates.len() == 4 { 4 } else { 3 }; - for ty in type_candidates.iter().take(limit) { - err.note(&format!("the {item_kind} was found for {}", ty)); - } - if type_candidates.len() > limit { - err.note(&format!( - "the {item_kind} was found for {} more types", - type_candidates.len() - limit - )); - } + .take(limit) + .map(|impl_item| { + format!("- `{}`", self.tcx.at(span).type_of(*impl_item)) + }) + .collect::>() + .join("\n"); + let additional_types = if inherent_impls_candidate.len() > limit { + format!( + "\nand {} more types", + inherent_impls_candidate.len() - limit + ) + } else { + "".to_string() + }; + err.note(&format!( + "the {item_kind} was found for\n{}{}", + type_candidates, additional_types + )); } } } else { diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 76a6b447ac100..e9d934332f171 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -4,7 +4,8 @@ error[E0599]: no function or associated item named `new_undirected` found for st LL | let ug = Graph::::new_undirected(); | ^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` | - = note: the function or associated item was found for issue_30123_aux::Graph + = note: the function or associated item was found for + - `issue_30123_aux::Graph` error: aborting due to previous error diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 4a9cfb4fc804e..1671e5e5e64c8 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -7,7 +7,8 @@ LL | struct Point { LL | let d = point_i32.distance(); | ^^^^^^^^ method not found in `Point` | - = note: the method was found for Point + = note: the method was found for + - `Point` error[E0599]: no method named `other` found for struct `Point` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:84:23 @@ -33,10 +34,12 @@ LL | struct Wrapper(T); LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper` | - = note: the method was found for Wrapper - = note: the method was found for Wrapper - = note: the method was found for Wrapper - = note: the method was found for 3 more types + = note: the method was found for + - `Wrapper` + - `Wrapper` + - `Wrapper` + - `Wrapper` + and 2 more types error[E0599]: no method named `other` found for struct `Wrapper` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:92:13 @@ -56,9 +59,10 @@ LL | struct Wrapper2<'a, T, const C: usize> { LL | wrapper.method(); | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` | - = note: the method was found for Wrapper2<'a, i8, C> - = note: the method was found for Wrapper2<'a, i16, C> - = note: the method was found for Wrapper2<'a, i32, C> + = note: the method was found for + - `Wrapper2<'a, i8, C>` + - `Wrapper2<'a, i16, C>` + - `Wrapper2<'a, i32, C>` error[E0599]: no method named `other` found for struct `Wrapper2` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:98:13 From 824c7435fa849d101a522e3744aff85074752734 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Tue, 25 May 2021 17:34:44 +0200 Subject: [PATCH 43/70] add regression test --- src/test/ui/matches2021.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/test/ui/matches2021.rs diff --git a/src/test/ui/matches2021.rs b/src/test/ui/matches2021.rs new file mode 100644 index 0000000000000..1090b1578ba51 --- /dev/null +++ b/src/test/ui/matches2021.rs @@ -0,0 +1,12 @@ +// run-pass +// edition:2021 +// compile-flags: -Zunstable-options + +// regression test for https://github.com/rust-lang/rust/pull/85678 + +#![feature(assert_matches)] + +fn main() { + assert!(matches!((), ())); + assert_matches!((), ()); +} From d14dd9f763c9d0126cb40fd816eb25b4a1b1e8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 16 May 2021 12:34:42 +0200 Subject: [PATCH 44/70] emit diagnostic after post-monomorphization errors Emit a diagnostic when the monomorphized item collector encounters errors during a step of the recursive item collection. These post-monomorphization errors otherwise only show the erroneous expression without a trace, making them very obscure and hard to pinpoint whenever they happen in dependencies. --- compiler/rustc_middle/src/mir/mono.rs | 9 ++++ .../rustc_mir/src/monomorphize/collector.rs | 46 ++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index edf2e53976541..0109580a0bba9 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -186,6 +186,15 @@ impl<'tcx> MonoItem<'tcx> { pub fn codegen_dep_node(&self, tcx: TyCtxt<'tcx>) -> DepNode { crate::dep_graph::make_compile_mono_item(tcx, self) } + + /// Returns the item's `CrateNum` + pub fn krate(&self) -> CrateNum { + match self { + MonoItem::Fn(ref instance) => instance.def_id().krate, + MonoItem::Static(def_id) => def_id.krate, + MonoItem::GlobalAsm(..) => LOCAL_CRATE, + } + } } impl<'a, 'tcx> HashStable> for MonoItem<'tcx> { diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index ef79f36b3b5aa..afe4457bf433d 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -184,7 +184,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; use rustc_errors::{ErrorReported, FatalError}; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; +use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::GrowableBitSet; @@ -342,7 +342,8 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec( tcx: TyCtxt<'tcx>, starting_point: Spanned>, @@ -359,6 +360,31 @@ fn collect_items_rec<'tcx>( let mut neighbors = Vec::new(); let recursion_depth_reset; + // + // Post-monomorphization errors MVP + // + // We can encounter errors while monomorphizing an item, but we don't have a good way of + // showing a complete stack of spans ultimately leading to collecting the erroneous one yet. + // (It's also currently unclear exactly which diagnostics and information would be interesting + // to report in such cases) + // + // This leads to suboptimal error reporting: a post-monomorphization error (PME) will be + // shown with just a spanned piece of code causing the error, without information on where + // it was called from. This is especially obscure if the erroneous mono item is in a + // dependency. See for example issue #85155, where, before minimization, a PME happened two + // crates downstream from libcore's stdarch, without a way to know which dependency was the + // cause. + // + // If such an error occurs in the current crate, its span will be enough to locate the + // source. If the cause is in another crate, the goal here is to quickly locate which mono + // item in the current crate is ultimately responsible for causing the error. + // + // To give at least _some_ context to the user: while collecting mono items, we check the + // error count. If it has changed, a PME occurred, and we trigger some diagnostics about the + // current step of mono items collection. + // + let error_count = tcx.sess.diagnostic().err_count(); + match starting_point.node { MonoItem::Static(def_id) => { let instance = Instance::mono(tcx, def_id); @@ -411,6 +437,22 @@ fn collect_items_rec<'tcx>( } } + // Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the + // mono item graph where the PME diagnostics are currently the most problematic (e.g. ones + // involving a dependency, and the lack of context is confusing) in this MVP, we focus on + // diagnostics on edges crossing a crate boundary: the collected mono items which are not + // defined in the local crate. + if tcx.sess.diagnostic().err_count() > error_count && starting_point.node.krate() != LOCAL_CRATE + { + tcx.sess.span_note_without_error( + starting_point.span, + &format!( + "the above error was encountered while instantiating `{}`", + starting_point.node + ), + ); + } + record_accesses(tcx, starting_point.node, neighbors.iter().map(|i| &i.node), inlining_map); for neighbour in neighbors { From 6f6145617d303c090166956d7f7f2c19811e6765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 24 May 2021 16:16:56 +0200 Subject: [PATCH 45/70] add test for issue 85155 and similar This test reproduces post-monomorphization errors one can encounter when using incorrect immediate arguments to some of the stdarch intrinsics using const generics. --- .../auxiliary/post_monomorphization_error.rs | 20 ++++++++++++++++++ src/test/ui/consts/const-eval/issue-85155.rs | 21 +++++++++++++++++++ .../ui/consts/const-eval/issue-85155.stderr | 15 +++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs create mode 100644 src/test/ui/consts/const-eval/issue-85155.rs create mode 100644 src/test/ui/consts/const-eval/issue-85155.stderr diff --git a/src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs b/src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs new file mode 100644 index 0000000000000..bdeaa0cd36062 --- /dev/null +++ b/src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs @@ -0,0 +1,20 @@ +// Auxiliary crate used for testing post-monomorphization errors cross-crate. +// It duplicates the setup used in `stdarch` to validate its intrinsics' const arguments. + +struct ValidateConstImm; +impl ValidateConstImm { + pub(crate) const VALID: () = { + let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); + }; +} + +macro_rules! static_assert_imm1 { + ($imm:ident) => { + let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID; + }; +} + +// This function triggers an error whenever the const argument does not fit in 1-bit. +pub fn stdarch_intrinsic() { + static_assert_imm1!(IMM1); +} diff --git a/src/test/ui/consts/const-eval/issue-85155.rs b/src/test/ui/consts/const-eval/issue-85155.rs new file mode 100644 index 0000000000000..c3216d53d0554 --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-85155.rs @@ -0,0 +1,21 @@ +// This is a test with a setup similar to issue 85155, which triggers a const eval error: a const +// argument value is outside the range expected by the `stdarch` intrinsic. +// +// It's not the exact code mentioned in that issue because it depends both on `stdarch` intrinsics +// only available on x64, and internal implementation details of `stdarch`. But mostly because these +// are not important to trigger the diagnostics issue: it's specifically about the lack of context +// in the diagnostics of post-monomorphization errors (PMEs) for consts, happening in a dependency. +// Therefore, its setup is reproduced with an aux crate, which will similarly trigger a PME +// depending on the const argument value, like the `stdarch` intrinsics would. +// +// aux-build: post_monomorphization_error.rs +// build-fail: this is a post-monomorphization error, it passes check runs and requires building +// to actually fail. + +extern crate post_monomorphization_error; + +fn main() { + // This function triggers a PME whenever the const argument does not fit in 1-bit. + post_monomorphization_error::stdarch_intrinsic::<2>(); + //~^ NOTE the above error was encountered while instantiating +} diff --git a/src/test/ui/consts/const-eval/issue-85155.stderr b/src/test/ui/consts/const-eval/issue-85155.stderr new file mode 100644 index 0000000000000..0a1edfb8a3356 --- /dev/null +++ b/src/test/ui/consts/const-eval/issue-85155.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/auxiliary/post_monomorphization_error.rs:7:17 + | +LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero + +note: the above error was encountered while instantiating `fn stdarch_intrinsic::<2_i32>` + --> $DIR/issue-85155.rs:19:5 + | +LL | post_monomorphization_error::stdarch_intrinsic::<2>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. From b0835410bbd8c80af3a1376d112291030d08f9c6 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 24 May 2021 12:43:51 +0200 Subject: [PATCH 46/70] Handle `unsafe_op_in_unsafe_fn` properly in THIR unsafeck --- .../rustc_mir_build/src/check_unsafety.rs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 7e64c5f189edd..bb3ec9ad2b4ec 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -72,16 +72,20 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {} SafetyContext::UnsafeFn => { // unsafe_op_in_unsafe_fn is disallowed - struct_span_err!( - self.tcx.sess, + self.tcx.struct_span_lint_hir( + UNSAFE_OP_IN_UNSAFE_FN, + self.hir_context, span, - E0133, - "{} is unsafe and requires unsafe block", - description, + |lint| { + lint.build(&format!( + "{} is unsafe and requires unsafe block (error E0133)", + description, + )) + .span_label(span, description) + .note(note) + .emit(); + }, ) - .span_label(span, description) - .note(note) - .emit(); } SafetyContext::Safe => { let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" }; From f7916b4c9e6d2b12f59539a3e237329199ab069d Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 24 May 2021 12:54:26 +0200 Subject: [PATCH 47/70] Fix `unused_unsafe` in THIR unsafeck --- .../rustc_mir_build/src/check_unsafety.rs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index bb3ec9ad2b4ec..971b6dd9e1c89 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -42,7 +42,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { self.warn_unused_unsafe( hir_id, block_span, - Some(self.tcx.sess.source_map().guess_head_span(enclosing_span)), + Some((self.tcx.sess.source_map().guess_head_span(enclosing_span), "block")), ); f(self); } else { @@ -52,7 +52,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { f(self); if let SafetyContext::UnsafeBlock { used: false, span, hir_id } = self.safety_context { - self.warn_unused_unsafe(hir_id, span, self.body_unsafety.unsafe_fn_sig_span()); + self.warn_unused_unsafe( + hir_id, + span, + if self.unsafe_op_in_unsafe_fn_allowed() { + self.body_unsafety.unsafe_fn_sig_span().map(|span| (span, "fn")) + } else { + None + }, + ); } self.safety_context = prev_context; return; @@ -108,18 +116,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { &self, hir_id: hir::HirId, block_span: Span, - enclosing_span: Option, + enclosing_unsafe: Option<(Span, &'static str)>, ) { let block_span = self.tcx.sess.source_map().guess_head_span(block_span); self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, |lint| { let msg = "unnecessary `unsafe` block"; let mut db = lint.build(msg); db.span_label(block_span, msg); - if let Some(enclosing_span) = enclosing_span { - db.span_label( - enclosing_span, - format!("because it's nested under this `unsafe` block"), - ); + if let Some((span, kind)) = enclosing_unsafe { + db.span_label(span, format!("because it's nested under this `unsafe` {}", kind)); } db.emit(); }); From f9e08cd75f4bc49f3c2e1e0c2e5b654e11c727c5 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Mon, 24 May 2021 12:55:01 +0200 Subject: [PATCH 48/70] Run THIR unsafeck on `unsafe_op_in_unsafe_fn` test --- ...fc-2585-unsafe_op_in_unsafe_fn.mir.stderr} | 32 ++--- .../unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs | 3 + ...fc-2585-unsafe_op_in_unsafe_fn.thir.stderr | 122 ++++++++++++++++++ 3 files changed, 141 insertions(+), 16 deletions(-) rename src/test/ui/unsafe/{rfc-2585-unsafe_op_in_unsafe_fn.stderr => rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr} (82%) create mode 100644 src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr similarity index 82% rename from src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr rename to src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr index ad93267ca014e..9a522fac65fad 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr @@ -1,18 +1,18 @@ error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5 | LL | unsf(); | ^^^^^^ call to unsafe function | note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:1:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 | LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -20,7 +20,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -28,25 +28,25 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9 | LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 | LL | unsf(); | ^^^^^^ call to unsafe function | note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:8 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8 | LL | #[deny(warnings)] | ^^^^^^^^ @@ -54,7 +54,7 @@ LL | #[deny(warnings)] = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -62,7 +62,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -70,13 +70,13 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:30:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:44:14 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14 | LL | unsafe { unsafe { unsf() } } | ------ ^^^^^^ unnecessary `unsafe` block @@ -84,7 +84,7 @@ LL | unsafe { unsafe { unsf() } } | because it's nested under this `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:55:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5 | LL | unsafe fn allow_level() { | ----------------------- because it's nested under this `unsafe` fn @@ -93,7 +93,7 @@ LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:67:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9 | LL | unsafe fn nested_allow_level() { | ------------------------------ because it's nested under this `unsafe` fn @@ -102,7 +102,7 @@ LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block error[E0133]: call to unsafe function is unsafe and requires unsafe block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -110,7 +110,7 @@ LL | unsf(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:77:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9 | LL | unsf(); | ^^^^^^ call to unsafe function diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs index c8400a6fc4d0d..7ca714b85c216 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -1,3 +1,6 @@ +// revisions: mir thir +// [thir]compile-flags: -Zthir-unsafeck + #![deny(unsafe_op_in_unsafe_fn)] #![deny(unused_unsafe)] diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr new file mode 100644 index 0000000000000..ad87690bb52f0 --- /dev/null +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr @@ -0,0 +1,122 @@ +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 + | +LL | #![deny(unsafe_op_in_unsafe_fn)] + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 + | +LL | VOID = (); + | ^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9 + | +LL | #![deny(unused_unsafe)] + | ^^^^^^^^^^^^^ + +error: call to unsafe function is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | +note: the lint level is defined here + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8 + | +LL | #[deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 + | +LL | *PTR; + | ^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: use of mutable static is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + | +LL | VOID = (); + | ^^^^ use of mutable static + | + = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + | +LL | unsafe {} + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14 + | +LL | unsafe { unsafe { unsf() } } + | ------ ^^^^^^ unnecessary `unsafe` block + | | + | because it's nested under this `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5 + | +LL | unsafe fn allow_level() { + | ----------------------- because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error: unnecessary `unsafe` block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9 + | +LL | unsafe fn nested_allow_level() { + | ------------------------------ because it's nested under this `unsafe` fn +... +LL | unsafe { unsf() } + | ^^^^^^ unnecessary `unsafe` block + +error[E0133]: call to unsafe function is unsafe and requires unsafe block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9 + | +LL | unsf(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0133`. From caf6faf95107ab52d1f58b90d6bec764b428fdaa Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 25 May 2021 20:20:05 +0200 Subject: [PATCH 49/70] Remove Iterator #[rustc_on_unimplemented]s that no longer apply. --- library/core/src/iter/traits/iterator.rs | 34 ------------------------ 1 file changed, 34 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index e6ed34d3f052b..a696c88f66366 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -25,40 +25,6 @@ fn _assert_is_object_safe(_: &dyn Iterator) {} /// [impl]: crate::iter#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( - on( - _Self = "[std::ops::Range; 1]", - label = "if you meant to iterate between two values, remove the square brackets", - note = "`[start..end]` is an array of one `Range`; you might have meant to have a `Range` \ - without the brackets: `start..end`" - ), - on( - _Self = "[std::ops::RangeFrom; 1]", - label = "if you meant to iterate from a value onwards, remove the square brackets", - note = "`[start..]` is an array of one `RangeFrom`; you might have meant to have a \ - `RangeFrom` without the brackets: `start..`, keeping in mind that iterating over an \ - unbounded iterator will run forever unless you `break` or `return` from within the \ - loop" - ), - on( - _Self = "[std::ops::RangeTo; 1]", - label = "if you meant to iterate until a value, remove the square brackets and add a \ - starting value", - note = "`[..end]` is an array of one `RangeTo`; you might have meant to have a bounded \ - `Range` without the brackets: `0..end`" - ), - on( - _Self = "[std::ops::RangeInclusive; 1]", - label = "if you meant to iterate between two values, remove the square brackets", - note = "`[start..=end]` is an array of one `RangeInclusive`; you might have meant to have a \ - `RangeInclusive` without the brackets: `start..=end`" - ), - on( - _Self = "[std::ops::RangeToInclusive; 1]", - label = "if you meant to iterate until a value (including it), remove the square brackets \ - and add a starting value", - note = "`[..=end]` is an array of one `RangeToInclusive`; you might have meant to have a \ - bounded `RangeInclusive` without the brackets: `0..=end`" - ), on( _Self = "std::ops::RangeTo", label = "if you meant to iterate until a value, add a starting value", From 072b85c370a0e1025a99efecdb28e454fbca7bed Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 25 May 2021 15:03:01 -0700 Subject: [PATCH 50/70] Update books --- src/doc/edition-guide | 2 +- src/doc/embedded-book | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 1da3c411f17ad..302a115e8f718 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 1da3c411f17adb1ba5de1683bb6acee83362b54a +Subproject commit 302a115e8f71876dfc884aebb0ca5ccb02b8a962 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 569c3391f5c0c..7349d173fa28a 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 569c3391f5c0cc43433bc77831d17f8ff4d76602 +Subproject commit 7349d173fa28a0bb834cf0264a05286620ef0923 diff --git a/src/doc/reference b/src/doc/reference index 5aa457bf1b54b..9c68af3ce6ccc 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 5aa457bf1b54bd2cd5d4cf49797f29299bdf89a7 +Subproject commit 9c68af3ce6ccca2395e1868addef26a0542e9ddd diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 5f8c6da200ada..805e016c5792a 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 5f8c6da200ada77760a2fe1096938ef58151c9a6 +Subproject commit 805e016c5792ad2adabb66e348233067d5ea9f10 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 1e6c7fbda4c45..50de7f0682adc 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 1e6c7fbda4c45e85adf63ff3f82fa9c870b1447f +Subproject commit 50de7f0682adc5d95ce858fe6318d19b4b951553 From 8a7dc0d3aafc7709152e01efd7d77e51ed1ad775 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 25 May 2021 16:08:54 -0700 Subject: [PATCH 51/70] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 070e459c2d8b7..e931e4796b61d 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 070e459c2d8b79c5b2ac5218064e7603329c92ae +Subproject commit e931e4796b61de593aa1097649445e535c9c7ee0 From d1b69cf89b962210629149f191a7cd6647d8d5d1 Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Wed, 26 May 2021 02:37:39 -0500 Subject: [PATCH 52/70] Fix typo in core::array::IntoIter comment --- library/core/src/array/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index c36542f631488..aedbeab661058 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -139,7 +139,7 @@ impl Iterator for IntoIter { // SAFETY: Callers are only allowed to pass an index that is in bounds // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even // multiple repeated reads of the same index would be safe and the - // values aree !Drop, thus won't suffer from double drops. + // values are !Drop, thus won't suffer from double drops. unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() } } } From 128d385e5659f44c0d2a09414adc12cee41119b8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 29 Apr 2021 10:31:44 -0400 Subject: [PATCH 53/70] stabilize member constraints --- compiler/rustc_feature/src/accepted.rs | 2 + compiler/rustc_feature/src/active.rs | 3 - .../rustc_trait_selection/src/opaque_types.rs | 66 ------------------- .../language-features/member-constraints.md | 29 -------- .../multiple-lifetimes/ret-impl-trait-fg.rs | 7 +- .../ret-impl-trait-no-fg.rs | 20 ------ .../ret-impl-trait-no-fg.stderr | 43 ------------ .../multiple-lifetimes/ret-impl-trait-one.rs | 2 - .../ret-impl-trait-one.stderr | 2 +- .../feature-gate-member-constraints.rs | 10 --- .../feature-gate-member-constraints.stderr | 18 ----- .../error-handling.full_tait.stderr | 4 +- .../error-handling.min_tait.stderr | 2 +- .../multiple-lifetimes/error-handling.rs | 1 - .../multiple-lifetimes/inverse-bounds.rs | 2 - .../ordinary-bounds-pick-original-elided.rs | 8 +-- ...nds-pick-original-type-alias-impl-trait.rs | 7 +- .../ordinary-bounds-pick-original.rs | 8 +-- .../ordinary-bounds-pick-other.rs | 2 - .../ordinary-bounds-unrelated.rs | 2 - .../ordinary-bounds-unrelated.stderr | 4 +- .../ordinary-bounds-unsuited.rs | 4 +- .../ordinary-bounds-unsuited.stderr | 4 +- .../impl-trait/needs_least_region_or_bound.rs | 2 - .../issue-74761.full_tait.stderr | 6 +- .../issue-74761.min_tait.stderr | 4 +- .../ui/type-alias-impl-trait/issue-74761.rs | 1 - 27 files changed, 28 insertions(+), 235 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/member-constraints.md delete mode 100644 src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs delete mode 100644 src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr delete mode 100644 src/test/ui/feature-gates/feature-gate-member-constraints.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-member-constraints.stderr diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 945406aed4bb0..95504723e7b24 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -285,6 +285,8 @@ declare_features! ( (accepted, extended_key_value_attributes, "1.54.0", Some(78835), None), /// Allows unsizing coercions in `const fn`. (accepted, const_fn_unsize, "1.54.0", Some(64992), None), + /// Allows `impl Trait` with multiple unrelated lifetimes. + (accepted, member_constraints, "1.54.0", Some(61997), None), // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index ac1974eb4c690..a84737e80a09f 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -472,9 +472,6 @@ declare_features! ( /// Allows explicit discriminants on non-unit enum variants. (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), - /// Allows `impl Trait` with multiple unrelated lifetimes. - (active, member_constraints, "1.37.0", Some(61997), None), - /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 7e67bc118ec1e..163df26e9ffaf 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -140,15 +140,6 @@ pub trait InferCtxtExt<'tcx> { first_own_region_index: usize, ); - /*private*/ - fn member_constraint_feature_gate( - &self, - opaque_defn: &OpaqueTypeDecl<'tcx>, - opaque_type_def_id: DefId, - conflict1: ty::Region<'tcx>, - conflict2: ty::Region<'tcx>, - ) -> bool; - fn infer_opaque_definition_from_instantiation( &self, def_id: DefId, @@ -490,9 +481,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // ['a, 'b, 'c]`, where `'a..'c` are the // regions that appear in the impl trait. - // For now, enforce a feature gate outside of async functions. - self.member_constraint_feature_gate(opaque_defn, def_id, lr, subst_region); - return self.generate_member_constraint( concrete_ty, opaque_defn, @@ -559,60 +547,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }); } - /// Member constraints are presently feature-gated except for - /// async-await. We expect to lift this once we've had a bit more - /// time. - fn member_constraint_feature_gate( - &self, - opaque_defn: &OpaqueTypeDecl<'tcx>, - opaque_type_def_id: DefId, - conflict1: ty::Region<'tcx>, - conflict2: ty::Region<'tcx>, - ) -> bool { - // If we have `#![feature(member_constraints)]`, no problems. - if self.tcx.features().member_constraints { - return false; - } - - let span = self.tcx.def_span(opaque_type_def_id); - - // Without a feature-gate, we only generate member-constraints for async-await. - let context_name = match opaque_defn.origin { - // No feature-gate required for `async fn`. - hir::OpaqueTyOrigin::AsyncFn => return false, - - // Otherwise, generate the label we'll use in the error message. - hir::OpaqueTyOrigin::Binding - | hir::OpaqueTyOrigin::FnReturn - | hir::OpaqueTyOrigin::TyAlias - | hir::OpaqueTyOrigin::Misc => "impl Trait", - }; - let msg = format!("ambiguous lifetime bound in `{}`", context_name); - let mut err = self.tcx.sess.struct_span_err(span, &msg); - - let conflict1_name = conflict1.to_string(); - let conflict2_name = conflict2.to_string(); - let label_owned; - let label = match (&*conflict1_name, &*conflict2_name) { - ("'_", "'_") => "the elided lifetimes here do not outlive one another", - _ => { - label_owned = format!( - "neither `{}` nor `{}` outlives the other", - conflict1_name, conflict2_name, - ); - &label_owned - } - }; - err.span_label(span, label); - - if self.tcx.sess.is_nightly_build() { - err.help("add #![feature(member_constraints)] to the crate attributes to enable"); - } - - err.emit(); - true - } - /// Given the fully resolved, instantiated type for an opaque /// type, i.e., the value of an inference variable like C1 or C2 /// (*), computes the "definition type" for an opaque type diff --git a/src/doc/unstable-book/src/language-features/member-constraints.md b/src/doc/unstable-book/src/language-features/member-constraints.md deleted file mode 100644 index 3ba4a3e6b1f02..0000000000000 --- a/src/doc/unstable-book/src/language-features/member-constraints.md +++ /dev/null @@ -1,29 +0,0 @@ -# `member_constraints` - -The tracking issue for this feature is: [#61997] - -[#61997]: https://github.com/rust-lang/rust/issues/61997 - ------------------------- - -The `member_constraints` feature gate lets you use `impl Trait` syntax with -multiple unrelated lifetime parameters. - -A simple example is: - -```rust -#![feature(member_constraints)] - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T {} - -fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - (x, y) -} - -fn main() { } -``` - -Without the `member_constraints` feature gate, the above example is an -error because both `'a` and `'b` appear in the impl Trait bounds, but -neither outlives the other. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs index b901b61aa1898..f1002947fb978 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs @@ -1,10 +1,9 @@ // edition:2018 // run-pass -// Test that a feature gate is needed to use `impl Trait` as the -// return type of an async. - -#![feature(member_constraints)] +// Test member constraints that appear in the `impl Trait` +// return type of an async function. +// (This used to require a feature gate.) trait Trait<'a, 'b> { } impl Trait<'_, '_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs deleted file mode 100644 index 05960c0c7f636..0000000000000 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs +++ /dev/null @@ -1,20 +0,0 @@ -// edition:2018 - -// Test that a feature gate is needed to use `impl Trait` as the -// return type of an async. - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } - -async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - //~^ ERROR ambiguous lifetime bound - //~| ERROR ambiguous lifetime bound - //~| ERROR ambiguous lifetime bound - //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds - //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds - (a, b) -} - -fn main() { - let _ = async_ret_impl_trait(&22, &44); -} diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr deleted file mode 100644 index f65bbeaa31a73..0000000000000 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:9:64 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:9:64 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:9:64 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ret-impl-trait-no-fg.rs:9:1 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: hidden type `(&u8, &u8)` captures lifetime '_#5r - -error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ret-impl-trait-no-fg.rs:9:1 - | -LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: hidden type `(&u8, &u8)` captures lifetime '_#6r - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs index babc90a5e96ad..7e084217c2607 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs @@ -3,8 +3,6 @@ // Test that a feature gate is needed to use `impl Trait` as the // return type of an async. -#![feature(member_constraints)] - trait Trait<'a> { } impl Trait<'_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index 5041b39a9e9d1..8e28605721cb5 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ret-impl-trait-one.rs:12:65 + --> $DIR/ret-impl-trait-one.rs:10:65 | LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { | ------ ^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.rs b/src/test/ui/feature-gates/feature-gate-member-constraints.rs deleted file mode 100644 index f6a92b0d0bfb5..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-member-constraints.rs +++ /dev/null @@ -1,10 +0,0 @@ -trait Trait<'a, 'b> {} -impl Trait<'_, '_> for T {} - -fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - //~^ ERROR ambiguous lifetime bound - //~| ERROR ambiguous lifetime bound - (x, y) -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-member-constraints.stderr b/src/test/ui/feature-gates/feature-gate-member-constraints.stderr deleted file mode 100644 index c2ec7ae16a3a6..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-member-constraints.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/feature-gate-member-constraints.rs:4:43 - | -LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: ambiguous lifetime bound in `impl Trait` - --> $DIR/feature-gate-member-constraints.rs:4:43 - | -LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another - | - = help: add #![feature(member_constraints)] to the crate attributes to enable - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr index d7a9e5463b358..ff99d037d198f 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/error-handling.rs:6:32 + --> $DIR/error-handling.rs:5:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error: lifetime may not live long enough - --> $DIR/error-handling.rs:26:16 + --> $DIR/error-handling.rs:25:16 | LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr index e2d745cdec804..4b23ba81604a9 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.min_tait.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/error-handling.rs:26:16 + --> $DIR/error-handling.rs:25:16 | LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs index b5adabb7abd22..1ead78e02ed45 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling.rs @@ -1,6 +1,5 @@ // compile-flags:-Zborrowck=mir -#![feature(member_constraints)] // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] #![cfg_attr(full_tait, feature(type_alias_impl_trait))] diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs index 3911769b0c63d..41b6a9eb0551f 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs @@ -3,8 +3,6 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs index 553dea7aa6ed3..d0277336b25fd 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs @@ -3,10 +3,8 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} // Test case where we have elision in the impl trait and we have to // pick the right region. @@ -26,4 +24,4 @@ fn upper_bounds3<'b>(a: &u8) -> impl Trait<'_, 'b> { (a, a) } -fn main() { } +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs index 9d345502aab4d..b9857b7aa2f1d 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs @@ -3,10 +3,9 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] #![feature(min_type_alias_impl_trait)] -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} // Here we wind up selecting `'a` and `'b` in the hidden type because // those are the types that appear in the original values. @@ -28,4 +27,4 @@ fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> { (a, b) } -fn main() { } +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs index c0930ec5944e0..be455f5335083 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs @@ -3,10 +3,8 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - -trait Trait<'a, 'b> { } -impl Trait<'_, '_> for T { } +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} // Here we wind up selecting `'a` and `'b` in the hidden type because // those are the types that appear in the original values. @@ -26,4 +24,4 @@ fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { (a, b) } -fn main() { } +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs index ed36bda7db719..7235d89019f0e 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs @@ -3,8 +3,6 @@ // revisions: migrate mir //[mir]compile-flags: -Z borrowck=mir -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs index db1641b0140b9..3a97624647efd 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index b42ff1486f0a8..a6bc8fec2838e 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -1,11 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:18:74 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ | note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body - --> $DIR/ordinary-bounds-unrelated.rs:18:74 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs index 7f9c92f15a2f9..d4c60a4e89209 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(member_constraints)] - trait Trait<'a, 'b> {} impl Trait<'_, '_> for T {} @@ -18,7 +16,7 @@ struct Ordinary<'a>(&'a u8); // consider the loans for both `'a` and `'b` alive. fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds +//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds { // We return a value: // diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index 254643c406cae..a219e74741541 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -1,11 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:20:62 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ | note: hidden type `Ordinary<'_>` captures lifetime smaller than the function body - --> $DIR/ordinary-bounds-unsuited.rs:20:62 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.rs b/src/test/ui/impl-trait/needs_least_region_or_bound.rs index 3c8682bb62aa5..c4bcfe5b28133 100644 --- a/src/test/ui/impl-trait/needs_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/needs_least_region_or_bound.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(member_constraints)] - trait MultiRegionTrait<'a, 'b> {} impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr index 0880136d71b01..05b63a00dfb15 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-74761.full_tait.stderr @@ -1,5 +1,5 @@ warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-74761.rs:4:32 + --> $DIR/issue-74761.rs:3:32 | LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,13 +8,13 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: see issue #63063 for more information error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:6 + --> $DIR/issue-74761.rs:10:6 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:10 + --> $DIR/issue-74761.rs:10:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr index 20ebdd9cb504c..ad111e23b15b5 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-74761.min_tait.stderr @@ -1,11 +1,11 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:6 + --> $DIR/issue-74761.rs:10:6 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates - --> $DIR/issue-74761.rs:11:10 + --> $DIR/issue-74761.rs:10:10 | LL | impl<'a, 'b> A for () { | ^^ unconstrained lifetime parameter diff --git a/src/test/ui/type-alias-impl-trait/issue-74761.rs b/src/test/ui/type-alias-impl-trait/issue-74761.rs index 66bb079b25a81..bbc67ecc97aab 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74761.rs +++ b/src/test/ui/type-alias-impl-trait/issue-74761.rs @@ -1,4 +1,3 @@ -#![feature(member_constraints)] // revisions: min_tait full_tait #![feature(min_type_alias_impl_trait)] #![cfg_attr(full_tait, feature(type_alias_impl_trait))] From 45099e6cf6d44bb9cefdda42823794fab2df2703 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 26 May 2021 13:12:54 +0300 Subject: [PATCH 54/70] Add inline attr to private CString::into_inner --- library/std/src/ffi/c_str.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 2a4ef553be399..be7e099b73a24 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -672,6 +672,7 @@ impl CString { } /// Bypass "move out of struct which implements [`Drop`] trait" restriction. + #[inline] fn into_inner(self) -> Box<[u8]> { // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)` // so we use `ManuallyDrop` to ensure `self` is not dropped. From 52a33655be8f2afc1ac666d24b5850badb23b3e7 Mon Sep 17 00:00:00 2001 From: 12101111 Date: Mon, 24 May 2021 17:53:09 +0800 Subject: [PATCH 55/70] cleanup and fix compiling of libunwind fix conditional compiling of llvm-libunwind feaure for musl target. update document of llvm-libunwind feature. --- config.toml.example | 8 +++ library/unwind/Cargo.toml | 7 ++ library/unwind/build.rs | 146 +++++++++++++++++++------------------- library/unwind/src/lib.rs | 21 ++++-- 4 files changed, 106 insertions(+), 76 deletions(-) diff --git a/config.toml.example b/config.toml.example index 16952a5ced83e..df2fb448b7d4d 100644 --- a/config.toml.example +++ b/config.toml.example @@ -563,6 +563,14 @@ changelog-seen = 2 # Use LLVM libunwind as the implementation for Rust's unwinder. # Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false). +# This option only applies for Linux and Fuchsia targets. +# On Linux target, if crt-static is not enabled, 'no' means dynamic link to +# `libgcc_s.so`, 'in-tree' means static link to the in-tree build of llvm libunwind +# and 'system' means dynamic link to `libunwind.so`. If crt-static is enabled, +# the behavior is depend on the libc. On musl target, 'no' and 'in-tree' both +# means static link to the in-tree build of llvm libunwind, and 'system' means +# static link to `libunwind.a` provided by system. Due to the limitation of glibc, +# it must link to `libgcc_eh.a` to get a working output, and this option have no effect. #llvm-libunwind = 'no' # Enable Windows Control Flow Guard checks in the standard library. diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index f42ded62585e2..9273ad0c3a46f 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -24,5 +24,12 @@ cfg-if = "0.1.8" cc = "1.0.67" [features] + +# Only applies for Linux and Fuchsia targets +# Static link to the in-tree build of llvm libunwind llvm-libunwind = [] + +# Only applies for Linux and Fuchsia targets +# If crt-static is enabled, static link to `libunwind.a` provided by system +# If crt-static is disabled, dynamic link to `libunwind.so` provided by system system-llvm-libunwind = [] diff --git a/library/unwind/build.rs b/library/unwind/build.rs index d8bf152e4d638..96df3fc5ac4c8 100644 --- a/library/unwind/build.rs +++ b/library/unwind/build.rs @@ -4,7 +4,8 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); let target = env::var("TARGET").expect("TARGET was not set"); - if cfg!(feature = "system-llvm-libunwind") { + if cfg!(target_os = "linux") && cfg!(feature = "system-llvm-libunwind") { + // linking for Linux is handled in lib.rs return; } @@ -57,101 +58,102 @@ mod llvm_libunwind { pub fn compile() { let target = env::var("TARGET").expect("TARGET was not set"); let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap(); - let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap(); - let target_endian_little = env::var("CARGO_CFG_TARGET_ENDIAN").unwrap() != "big"; - let cfg = &mut cc::Build::new(); - - cfg.cpp(true); - cfg.cpp_set_stdlib(None); - cfg.warnings(false); + let mut cc_cfg = cc::Build::new(); + let mut cpp_cfg = cc::Build::new(); + let root = Path::new("../../src/llvm-project/libunwind"); - // libunwind expects a __LITTLE_ENDIAN__ macro to be set for LE archs, cf. #65765 - if target_endian_little { - cfg.define("__LITTLE_ENDIAN__", Some("1")); + cpp_cfg.cpp(true); + cpp_cfg.cpp_set_stdlib(None); + cpp_cfg.flag("-nostdinc++"); + cpp_cfg.flag("-fno-exceptions"); + cpp_cfg.flag("-fno-rtti"); + cpp_cfg.flag_if_supported("-fvisibility-global-new-delete-hidden"); + + // Don't set this for clang + // By default, Clang builds C code in GNU C17 mode. + // By default, Clang builds C++ code according to the C++98 standard, + // with many C++11 features accepted as extensions. + if cpp_cfg.get_compiler().is_like_gnu() { + cpp_cfg.flag("-std=c++11"); + cc_cfg.flag("-std=c99"); } - if target_env == "msvc" { - // Don't pull in extra libraries on MSVC - cfg.flag("/Zl"); - cfg.flag("/EHsc"); - cfg.define("_CRT_SECURE_NO_WARNINGS", None); - cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None); - } else if target.contains("x86_64-fortanix-unknown-sgx") { - cfg.cpp(false); - - cfg.static_flag(true); - cfg.opt_level(3); - - cfg.flag("-nostdinc++"); - cfg.flag("-fno-exceptions"); - cfg.flag("-fno-rtti"); - cfg.flag("-fstrict-aliasing"); - cfg.flag("-funwind-tables"); - cfg.flag("-fvisibility=hidden"); - cfg.flag("-fno-stack-protector"); - cfg.flag("-ffreestanding"); - cfg.flag("-fexceptions"); - - // easiest way to undefine since no API available in cc::Build to undefine - cfg.flag("-U_FORTIFY_SOURCE"); - cfg.define("_FORTIFY_SOURCE", "0"); - - cfg.flag_if_supported("-fvisibility-global-new-delete-hidden"); + if target.contains("x86_64-fortanix-unknown-sgx") || target_env == "musl" { + // use the same GCC C compiler command to compile C++ code so we do not need to setup the + // C++ compiler env variables on the builders. + // Don't set this for clang++, as clang++ is able to compile this without libc++. + if cpp_cfg.get_compiler().is_like_gnu() { + cpp_cfg.cpp(false); + } + } - cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None); - cfg.define("RUST_SGX", "1"); - cfg.define("__NO_STRING_INLINES", None); - cfg.define("__NO_MATH_INLINES", None); - cfg.define("_LIBUNWIND_IS_BAREMETAL", None); - cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None); - cfg.define("NDEBUG", None); - } else { - cfg.flag("-std=c99"); - cfg.flag("-std=c++11"); - cfg.flag("-nostdinc++"); - cfg.flag("-fno-exceptions"); - cfg.flag("-fno-rtti"); + for cfg in [&mut cc_cfg, &mut cpp_cfg].iter_mut() { + cfg.warnings(false); cfg.flag("-fstrict-aliasing"); cfg.flag("-funwind-tables"); cfg.flag("-fvisibility=hidden"); - cfg.flag_if_supported("-fvisibility-global-new-delete-hidden"); cfg.define("_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS", None); + cfg.include(root.join("include")); + cfg.cargo_metadata(false); + + if target.contains("x86_64-fortanix-unknown-sgx") { + cfg.static_flag(true); + cfg.opt_level(3); + cfg.flag("-fno-stack-protector"); + cfg.flag("-ffreestanding"); + cfg.flag("-fexceptions"); + + // easiest way to undefine since no API available in cc::Build to undefine + cfg.flag("-U_FORTIFY_SOURCE"); + cfg.define("_FORTIFY_SOURCE", "0"); + cfg.define("RUST_SGX", "1"); + cfg.define("__NO_STRING_INLINES", None); + cfg.define("__NO_MATH_INLINES", None); + cfg.define("_LIBUNWIND_IS_BAREMETAL", None); + cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None); + cfg.define("NDEBUG", None); + } } - let mut unwind_sources = vec![ - "Unwind-EHABI.cpp", - "Unwind-seh.cpp", + let mut c_sources = vec![ "Unwind-sjlj.c", "UnwindLevel1-gcc-ext.c", "UnwindLevel1.c", "UnwindRegistersRestore.S", "UnwindRegistersSave.S", - "libunwind.cpp", ]; - if target_vendor == "apple" { - unwind_sources.push("Unwind_AppleExtras.cpp"); - } + let cpp_sources = vec!["Unwind-EHABI.cpp", "Unwind-seh.cpp", "libunwind.cpp"]; + let cpp_len = cpp_sources.len(); if target.contains("x86_64-fortanix-unknown-sgx") { - unwind_sources.push("UnwindRustSgx.c"); + c_sources.push("UnwindRustSgx.c"); } - let root = Path::new("../../src/llvm-project/libunwind"); - cfg.include(root.join("include")); - for src in unwind_sources { - cfg.file(root.join("src").join(src)); + for src in c_sources { + cc_cfg.file(root.join("src").join(src).canonicalize().unwrap()); } - if target_env == "musl" { - // use the same C compiler command to compile C++ code so we do not need to setup the - // C++ compiler env variables on the builders - cfg.cpp(false); - // linking for musl is handled in lib.rs - cfg.cargo_metadata(false); - println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap()); + for src in cpp_sources { + cpp_cfg.file(root.join("src").join(src).canonicalize().unwrap()); } - cfg.compile("unwind"); + let out_dir = env::var("OUT_DIR").unwrap(); + println!("cargo:rustc-link-search=native={}", &out_dir); + + cpp_cfg.compile("unwind-cpp"); + + let mut count = 0; + for entry in std::fs::read_dir(&out_dir).unwrap() { + let obj = entry.unwrap().path().canonicalize().unwrap(); + if let Some(ext) = obj.extension() { + if ext == "o" { + cc_cfg.object(&obj); + count += 1; + } + } + } + assert_eq!(cpp_len, count, "Can't get object files from {:?}", &out_dir); + cc_cfg.compile("unwind"); } } diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index be5e56c71e36f..eaeec72fbb55b 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -37,9 +37,22 @@ cfg_if::cfg_if! { } #[cfg(target_env = "musl")] -#[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))] -#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] -extern "C" {} +cfg_if::cfg_if! { + if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { + compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); + } else if #[cfg(feature = "llvm-libunwind")] { + #[link(name = "unwind", kind = "static")] + extern "C" {} + } else if #[cfg(feature = "system-llvm-libunwind")] { + #[link(name = "unwind", kind = "static-nobundle", cfg(target_feature = "crt-static"))] + #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] + extern "C" {} + } else { + #[link(name = "unwind", kind = "static", cfg(target_feature = "crt-static"))] + #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] + extern "C" {} + } +} // When building with crt-static, we get `gcc_eh` from the `libc` crate, since // glibc needs it, and needs it listed later on the linker command line. We @@ -68,5 +81,5 @@ extern "C" {} extern "C" {} #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] -#[link(name = "unwind", kind = "static-nobundle")] +#[link(name = "unwind", kind = "static")] extern "C" {} From b36c45d6df1a52ccdfac7e3158d7925993551fc3 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Wed, 26 May 2021 14:02:26 +0200 Subject: [PATCH 56/70] Update RLS --- Cargo.lock | 4 ++-- src/tools/rls | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62734bfaf629f..d5453c5fd6ca1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2845,9 +2845,9 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.46" +version = "2.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7cbda48a9124ed2e83766d2c15e3725710d344abca35fad8cf52341a55883b1" +checksum = "513c70e67444a0d62fdc581dffa521c6820942a5f08300d0864863f8d0e750e3" dependencies = [ "bitflags", "clap", diff --git a/src/tools/rls b/src/tools/rls index 097d8908339e2..9ed6f96f2ff85 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 097d8908339e20435078233a55a1a3335fe7c2eb +Subproject commit 9ed6f96f2ff85753c5a6ac290ee88ecb2831ab2e From f9499ea9f55926bd53cd6897878a05f7982dc48f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 May 2021 14:35:39 +0200 Subject: [PATCH 57/70] * Fix bug where some
tags were not closed. * Don't generate a
if there is no documentation --- src/librustdoc/html/render/print_item.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 50153ac14a204..e06168c708c18 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -578,14 +578,23 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra info!("Documenting {} on {:?}", name, t.name); let item_type = m.type_(); let id = cx.derive_id(format!("{}.{}", item_type, name)); - write!(w, "
"); - write!(w, "

", id = id,); + let mut content = Buffer::empty_from(w); + document(&mut content, cx, m, Some(t)); + let toggled = !content.is_empty(); + if toggled { + write!(w, "
"); + } + write!(w, "

", id = id); render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl, cx); w.write_str(""); render_stability_since(w, m, t, cx.tcx()); write_srclink(cx, m, w); - w.write_str("

"); - document(w, cx, m, Some(t)); + w.write_str("

"); + if toggled { + write!(w, "
"); + w.push_buffer(content); + write!(w, "
"); + } } if !types.is_empty() { From 3bed0be9fc7cf77b56404db8291b227385e1550f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 May 2021 14:36:58 +0200 Subject: [PATCH 58/70] Update trait toggle test --- src/test/rustdoc/toggle-trait-fn.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/rustdoc/toggle-trait-fn.rs b/src/test/rustdoc/toggle-trait-fn.rs index a160809cbf957..7fcac78556b72 100644 --- a/src/test/rustdoc/toggle-trait-fn.rs +++ b/src/test/rustdoc/toggle-trait-fn.rs @@ -1,7 +1,11 @@ #![crate_name = "foo"] // @has foo/trait.Foo.html -// @has - '//details[@class="rustdoc-toggle"]//code' 'bar' +// @!has - '//details[@class="rustdoc-toggle"]//code' 'bar' +// @has - '//code' 'bar' +// @has - '//details[@class="rustdoc-toggle"]//code' 'foo' pub trait Foo { fn bar() -> (); + /// hello + fn foo(); } From b3054d2c2180631f9574ee3c6c3d138ce5e25798 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 26 May 2021 12:05:34 -0400 Subject: [PATCH 59/70] bless compare-mode=nll output --- .../multiple-lifetimes/ret-impl-trait-one.nll.stderr | 2 +- .../multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr | 2 +- .../multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr index 53b0dd691b891..eed90772d29e3 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/ret-impl-trait-one.rs:12:80 + --> $DIR/ret-impl-trait-one.rs:10:80 | LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { | ________________________________--__--__________________________________________^ diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr index 129af80ce4a62..8cf89f164b16d 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:18:74 + --> $DIR/ordinary-bounds-unrelated.rs:16:74 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr index de6d5edcae511..1bcb28120ed1b 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:20:62 + --> $DIR/ordinary-bounds-unsuited.rs:18:62 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> | ^^^^^^^^^^^^^^^^^^ From ff8a3874901303c22bf8d65e5fad870a91ad6121 Mon Sep 17 00:00:00 2001 From: Smitty Date: Wed, 26 May 2021 13:16:26 -0400 Subject: [PATCH 60/70] Remove unneeded workaround This removes a workaround for #24159, which has been fixed. --- compiler/rustc_mir/src/interpret/place.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 79aaff1c5eb34..4c53510ed00ee 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -15,9 +15,9 @@ use rustc_target::abi::{Abi, Align, FieldsShape, TagEncoding}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, VariantIdx, Variants}; use super::{ - alloc_range, mir_assign_valid_types, AllocId, AllocMap, AllocRef, AllocRefMut, Allocation, - ConstAlloc, ImmTy, Immediate, InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, - Operand, Pointer, PointerArithmetic, Scalar, ScalarMaybeUninit, + alloc_range, mir_assign_valid_types, AllocRef, AllocRefMut, ConstAlloc, ImmTy, Immediate, + InterpCx, InterpResult, LocalValue, Machine, MemoryKind, OpTy, Operand, Pointer, + PointerArithmetic, Scalar, ScalarMaybeUninit, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)] @@ -292,8 +292,6 @@ where // FIXME: Working around https://github.com/rust-lang/rust/issues/54385 Tag: Debug + Copy + Eq + Hash + 'static, M: Machine<'mir, 'tcx, PointerTag = Tag>, - // FIXME: Working around https://github.com/rust-lang/rust/issues/24159 - M::MemoryMap: AllocMap, Allocation)>, { /// Take a value, which represents a (thin or wide) reference, and make it a place. /// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`. From fdc15ef823bcd46798984c143ca436c9e9ae9771 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Wed, 26 May 2021 22:34:42 +0200 Subject: [PATCH 61/70] Don't hash `thir_body` --- compiler/rustc_middle/src/query/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 9125be33c93da..8138eeac3d650 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -222,6 +222,7 @@ rustc_queries! { /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. query thir_body(key: ty::WithOptConstParam) -> (&'tcx Steal>, thir::ExprId) { + no_hash desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } } From e7a3ada210727a6df1de38299e2177057ff43cef Mon Sep 17 00:00:00 2001 From: Smitty Date: Wed, 26 May 2021 17:15:54 -0400 Subject: [PATCH 62/70] Mention float workaround in Iterator::{min,max} --- library/core/src/iter/traits/iterator.rs | 28 ++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 1eef0f9064c90..fcb14e9b77294 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2602,6 +2602,18 @@ pub trait Iterator { /// If several elements are equally maximum, the last element is /// returned. If the iterator is empty, [`None`] is returned. /// + /// Note that [`f32`]/[`f64`] doesn't implement [`Ord`] due to NaN being + /// incomparable. You can work around this by using [`Iterator::reduce`]: + /// ``` + /// assert_eq!( + /// vec![2.4, f32::NAN, 1.3] + /// .into_iter() + /// .reduce(|a, b| f32::max(a, b)) + /// .unwrap(), + /// 2.4 + /// ); + /// ``` + /// /// # Examples /// /// Basic usage: @@ -2625,8 +2637,20 @@ pub trait Iterator { /// Returns the minimum element of an iterator. /// - /// If several elements are equally minimum, the first element is - /// returned. If the iterator is empty, [`None`] is returned. + /// If several elements are equally minimum, the first element is returned. + /// If the iterator is empty, [`None`] is returned. + /// + /// Note that [`f32`]/[`f64`] doesn't implement [`Ord`] due to NaN being + /// incomparable. You can work around this by using [`Iterator::reduce`]: + /// ``` + /// assert_eq!( + /// vec![2.4, f32::NAN, 1.3] + /// .into_iter() + /// .reduce(|a, b| f32::min(a, b)) + /// .unwrap(), + /// 1.3 + /// ); + /// ``` /// /// # Examples /// From edef5bc31bce648723ad0ddb2de4c0d1969fc8d0 Mon Sep 17 00:00:00 2001 From: Smitty Date: Wed, 26 May 2021 19:55:27 -0400 Subject: [PATCH 63/70] Lint against non-camelCase trait alias names Type aliases are linted as such, so (unstable) trait aliases should be treated the same way. --- compiler/rustc_lint/src/nonstandard_style.rs | 1 + src/test/ui/traits/alias/style_lint.rs | 8 ++++++++ src/test/ui/traits/alias/style_lint.stderr | 10 ++++++++++ 3 files changed, 19 insertions(+) create mode 100644 src/test/ui/traits/alias/style_lint.rs create mode 100644 src/test/ui/traits/alias/style_lint.stderr diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index be9c6eafb6fdb..7146dd51aa717 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -176,6 +176,7 @@ impl EarlyLintPass for NonCamelCaseTypes { | ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident), + ast::ItemKind::TraitAlias(..) => self.check_case(cx, "trait alias", &it.ident), _ => (), } } diff --git a/src/test/ui/traits/alias/style_lint.rs b/src/test/ui/traits/alias/style_lint.rs new file mode 100644 index 0000000000000..33be20054b5d3 --- /dev/null +++ b/src/test/ui/traits/alias/style_lint.rs @@ -0,0 +1,8 @@ +// check-pass + +#![feature(trait_alias)] + +trait Foo = std::fmt::Display + std::fmt::Debug; +trait bar = std::fmt::Display + std::fmt::Debug; //~WARN trait alias `bar` should have an upper camel case name + +fn main() {} diff --git a/src/test/ui/traits/alias/style_lint.stderr b/src/test/ui/traits/alias/style_lint.stderr new file mode 100644 index 0000000000000..91e2ea90eb9e8 --- /dev/null +++ b/src/test/ui/traits/alias/style_lint.stderr @@ -0,0 +1,10 @@ +warning: trait alias `bar` should have an upper camel case name + --> $DIR/style_lint.rs:6:7 + | +LL | trait bar = std::fmt::Display + std::fmt::Debug; + | ^^^ help: convert the identifier to upper camel case: `Bar` + | + = note: `#[warn(non_camel_case_types)]` on by default + +warning: 1 warning emitted + From 7146a05a43c0baa6bd566ce614491535a6ba4ca2 Mon Sep 17 00:00:00 2001 From: Smittyvb Date: Wed, 26 May 2021 20:38:43 -0400 Subject: [PATCH 64/70] don't use unneeded closure Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com> --- library/core/src/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index fcb14e9b77294..b07296f8878a0 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2608,7 +2608,7 @@ pub trait Iterator { /// assert_eq!( /// vec![2.4, f32::NAN, 1.3] /// .into_iter() - /// .reduce(|a, b| f32::max(a, b)) + /// .reduce(f32::max) /// .unwrap(), /// 2.4 /// ); From b00f6fc8a16656391f9014cda73b24712eaf2ccb Mon Sep 17 00:00:00 2001 From: Smittyvb Date: Wed, 26 May 2021 20:38:50 -0400 Subject: [PATCH 65/70] don't use unneeded closure Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com> --- library/core/src/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index b07296f8878a0..556576f3171a0 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2646,7 +2646,7 @@ pub trait Iterator { /// assert_eq!( /// vec![2.4, f32::NAN, 1.3] /// .into_iter() - /// .reduce(|a, b| f32::min(a, b)) + /// .reduce(f32::min) /// .unwrap(), /// 1.3 /// ); From 3cafe2a43f56395307a4ccce3b8615a4fabe3368 Mon Sep 17 00:00:00 2001 From: Albert Ford Date: Wed, 26 May 2021 23:17:13 -0700 Subject: [PATCH 66/70] Rename opensbd to openbsd --- library/std/src/sys/unix/net.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index e6b61062d15ff..d5a15964c089d 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -62,7 +62,7 @@ impl Socket { target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "opensbd", + target_os = "openbsd", ))] { // On platforms that support it we pass the SOCK_CLOEXEC // flag to atomically create the socket and set it as @@ -99,7 +99,7 @@ impl Socket { target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "opensbd", + target_os = "openbsd", ))] { // Like above, set cloexec atomically cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; @@ -204,7 +204,7 @@ impl Socket { target_os = "illumos", target_os = "linux", target_os = "netbsd", - target_os = "opensbd", + target_os = "openbsd", ))] { let fd = cvt_r(|| unsafe { libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC) From 04d34a97d1d47676331479e24e5afaf2583cb8e5 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 26 May 2021 23:19:35 -0700 Subject: [PATCH 67/70] Enable Vec's calloc optimization for Option --- library/alloc/src/vec/is_zero.rs | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs index b5739970b6ea4..6fade636df9e2 100644 --- a/library/alloc/src/vec/is_zero.rs +++ b/library/alloc/src/vec/is_zero.rs @@ -69,3 +69,36 @@ unsafe impl IsZero for Option> { self.is_none() } } + +// `Option` and similar have a representation guarantee that +// they're the same size as the corresponding `u32` type, as well as a guarantee +// that transmuting between `NonZeroU32` and `Option` works. +// While the documentation officially makes in UB to transmute from `None`, +// we're the standard library so we can make extra inferences, and we know that +// the only niche available to represent `None` is the one that's all zeros. + +macro_rules! impl_is_zero_option_of_nonzero { + ($($t:ident,)+) => {$( + unsafe impl IsZero for Option { + #[inline] + fn is_zero(&self) -> bool { + self.is_none() + } + } + )+}; +} + +impl_is_zero_option_of_nonzero!( + NonZeroU8, + NonZeroU16, + NonZeroU32, + NonZeroU64, + NonZeroU128, + NonZeroI8, + NonZeroI16, + NonZeroI32, + NonZeroI64, + NonZeroI128, + NonZeroUsize, + NonZeroIsize, +); From 9385be7a0cc95cb354c67cdbd5229a0f47ddd296 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 27 May 2021 10:31:47 -0400 Subject: [PATCH 68/70] Update compiler/rustc_middle/src/query/mod.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Léo Lanteri Thauvin --- compiler/rustc_middle/src/query/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 8138eeac3d650..04aa30170dc60 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -222,6 +222,7 @@ rustc_queries! { /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. query thir_body(key: ty::WithOptConstParam) -> (&'tcx Steal>, thir::ExprId) { + // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } } From 027d73dcad10c5d70a313809ff584fc8f054b6a8 Mon Sep 17 00:00:00 2001 From: Roxane Date: Tue, 25 May 2021 18:30:54 -0400 Subject: [PATCH 69/70] Restrict Fake Read precision --- compiler/rustc_typeck/src/check/upvar.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 71e222c560a05..6baa185406e20 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -1588,6 +1588,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> { impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId) { if let PlaceBase::Upvar(_) = place.base { + // We need to restrict Fake Read precision to avoid fake reading unsafe code, + // such as deref of a raw pointer. + let place = restrict_capture_precision(place); + let place = + restrict_repr_packed_field_ref_capture(self.fcx.tcx, self.fcx.param_env, &place); self.fake_reads.push((place, cause, diag_expr_id)); } } From 382338fe755a4300358ae17a5df211236c257a27 Mon Sep 17 00:00:00 2001 From: Roxane Date: Thu, 27 May 2021 17:58:35 -0400 Subject: [PATCH 70/70] Remove feature gate --- .../src/build/expr/as_rvalue.rs | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 2185bd3a5c612..69786c14ee8dd 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -186,25 +186,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // }; // ``` // - // FIXME(RFC2229, rust#85435): Remove feature gate once diagnostics are - // improved and unsafe checking works properly in closure bodies again. - if this.tcx.features().capture_disjoint_fields { - for (thir_place, cause, hir_id) in fake_reads.into_iter() { - let place_builder = - unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); - - if let Ok(place_builder_resolved) = - place_builder.try_upvars_resolved(this.tcx, this.typeck_results) - { - let mir_place = - place_builder_resolved.into_place(this.tcx, this.typeck_results); - this.cfg.push_fake_read( - block, - this.source_info(this.tcx.hir().span(*hir_id)), - *cause, - mir_place, - ); - } + for (thir_place, cause, hir_id) in fake_reads.into_iter() { + let place_builder = + unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); + + if let Ok(place_builder_resolved) = + place_builder.try_upvars_resolved(this.tcx, this.typeck_results) + { + let mir_place = + place_builder_resolved.into_place(this.tcx, this.typeck_results); + this.cfg.push_fake_read( + block, + this.source_info(this.tcx.hir().span(*hir_id)), + *cause, + mir_place, + ); } }